Laden...

WM_DRAWCLIPBOARD 1mal zuviel?

Erstellt von KainPlan vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.464 Views
K
KainPlan Themenstarter:in
133 Beiträge seit 2009
vor 14 Jahren
WM_DRAWCLIPBOARD 1mal zuviel?

Hallo ich hab meine Anwendung als "ClipboardWatcher" registriert. Wenn ich jetzt aber über die Funktion SetData() selber eine z.B. FileDroplist setze dann wird die WM_DRAWCLIPBOARD Message danach 2mal gesendet! Hat da jemand nen grund für?

        

        public void MessageProc(ref Message m) 
        {
            if (m.Msg == WM_CHANGECBCHAIN)
            {
                if (m.WParam == _nextCBWatcher)
                {
                    _nextCBWatcher = m.LParam;
                }
                else
                {
                    SendMessage(_nextCBWatcher, m.Msg, m.WParam, m.LParam);
                }
            }
            else if (m.Msg == WM_DRAWCLIPBOARD)
            {
                OnClipboardChange();
            }
            else if (m.Msg == WM_CLOSE)
            {
                ChangeClipboardChain(_ownerWnd, _nextCBWatcher);
            }
        }



        public static void SetData(CBDataType type, object data)
        {
            HoldOnce = true;

            object dat;
            switch (type)
            {
                case CBDataType.Files:
                    dat = data as StringCollection;
                    if (dat == null) throw new Exception("Invalid data.");
                    Clipboard.SetFileDropList((StringCollection)dat);
                    break;
                case CBDataType.Audio:
                    dat = data as Stream;
                    if (dat == null) throw new Exception("Invalid data.");
                    Clipboard.SetAudio((Stream)dat);
                    break;
                case CBDataType.Image:
                    dat = data as Image;
                    if (dat == null) throw new Exception("Invalid data.");
                    Clipboard.SetImage((Image)dat);
                    break;
                case CBDataType.Text:
                    dat = data as string;
                    if (dat == null) throw new Exception("Invalid data.");
                    Clipboard.SetText((string)dat);
                    break;
                default: throw new Exception("Unsupported Clipboardformat.");
            }
        }


5.299 Beiträge seit 2008
vor 14 Jahren

erster Verdächtiger bei sowas ist immer eine doppelte Registrierung des Events.

Dann: Was macht

SendMessage(_nextCBWatcher, m.Msg, m.WParam, m.LParam);

?

oder auch die anderen methoden?

kannstejamal auskommentieren, obs dann immer noch doppelt kommt.

Der frühe Apfel fängt den Wurm.

K
KainPlan Themenstarter:in
133 Beiträge seit 2009
vor 14 Jahren

Die SendMessage(_nextCBWatcher, m.Msg, m.WParam, m.LParam) Funktion reicht das event an den nächsten registrierten ClipboardWatcher in der Kette weiter (siehe MSDN). Mein Watcher ist definitiv nur 1 mal registriert ansonsten würden ja alle events 2mal ankommen und nicht nur dann wenn ich daten ins Clipboard schreibe...

ChangeClipboardChain(_ownerWnd, _nextCBWatcher) entfernt meine Registrierung in der Kette.

OnClipboardChange() ist mein Event das getriggert wird...

Also kanns daran nicht liegen...

5.299 Beiträge seit 2008
vor 14 Jahren

Jo, habich jetzt auch gefunden. Immer, wenn die eigene Anwendung was ins Clipboard setzt isses doppelt.
Sieht mir Bug aus.

Ich hab in VB getestet, auf Basis von dem hier: Clipboard überwachen

Als Workaround habich ein Delay eingebaut, sodaß der ClipboardWatcher erst feuert, wenn der MessageLoop abgearbeitet ist (Application.Idle verarbeitet)


Imports System.Runtime.InteropServices

Public Class ClipboardWatcher : Inherits NativeWindow : Implements IDisposable

   <DllImport("user32", EntryPoint:="SetClipboardViewer")> _
   Private Shared Function SetClipboardViewer(ByVal hWnd As IntPtr) As IntPtr
   End Function

   Public Event Changed As EventHandler
   Private _IsNew As Boolean = True
   Private _hview As IntPtr

   'nur eine globale Instanz zulassen
   Public Shared Singleton As New ClipboardWatcher

   Private Sub New()
      MyBase.CreateHandle(New CreateParams)
      _hview = SetClipboardViewer(MyBase.Handle)
   End Sub

   Protected Overrides Sub WndProc(ByRef m As Message)
      Const WM_DRAWCLIPBOARD As Integer = &H308
      Select Case m.Msg
         Case WM_DRAWCLIPBOARD
            If _IsNew Then
               AddHandler Application.Idle, AddressOf App_Idle
               _IsNew = False
            End If
      End Select
      MyBase.WndProc(m)
   End Sub

   Private Sub App_Idle(ByVal sender As Object, ByVal e As EventArgs)
      RemoveHandler Application.Idle, AddressOf App_Idle
      RaiseEvent Changed(Me, EventArgs.Empty)
      _IsNew = True
   End Sub

#Region " IDisposable Support "
   ' Für diese Klasse ist korrekte Ressourcenbereinigung besonders wichtig, da mit
   ' systemübergreifenden Ressourcen gearbeitet wird

   Private disposedValue As Boolean = False      ' So ermitteln Sie überflüssige Aufrufe

   Protected Overridable Sub Dispose(ByVal disposing As Boolean)
      If Not Me.disposedValue Then
         If disposing Then
            ' TODO: Verwaltete Ressourcen freigeben, wenn sie explizit aufgerufen werden
         End If
         MyBase.DestroyHandle()
         Dim H As IntPtr = SetClipboardViewer(_hview)
      End If
      Me.disposedValue = True
   End Sub

   ' Dieser Code wird von Visual Basic hinzugefügt, um das Dispose-Muster richtig zu implementieren.
   Public Sub Dispose() Implements IDisposable.Dispose
      ' Ändern Sie diesen Code nicht. Fügen Sie oben in Dispose(ByVal disposing As Boolean) Bereinigungscode ein.
      Dispose(True)
      GC.SuppressFinalize(Me)
   End Sub

   Protected Overrides Sub Finalize()
      MyBase.Finalize()
      Dispose(False)
   End Sub

#End Region

End Class

Der frühe Apfel fängt den Wurm.

K
KainPlan Themenstarter:in
133 Beiträge seit 2009
vor 14 Jahren

Hm, Visual Basic 😕. Werd das mal morgen auf der Arbeit entschlüsseln 😄. Danke für deinen Lösungsansatz weitere wären trozdem erwünscht vorallem welche die sich schon bewährt haben!

5.299 Beiträge seit 2008
vor 14 Jahren

codeconverter kennste?

Der frühe Apfel fängt den Wurm.