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 ReadOnly _handle As IntPtr

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

    Const WM_DRAWCLIPBOARD As Integer = &H308

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

    Protected Overrides Sub WndProc(ByRef m As Message)
        Select Case m.Msg
            Case WM_DRAWCLIPBOARD
                Dim oWindow = ClassWindowAPI.GetWindowInfo()

                'clsWINDOWSApi.Get_ForegroundWindow_Info()
                If IsNothing(oWindow.ProcessName) Then
                    Exit Sub
                End If

                If oWindow.ProcessName.StartsWith("DD_Clipboard_Watcher") Then
                    Exit Sub
                End If

                RaiseEvent Changed(Me, EventArgs.Empty)
        End Select
        MyBase.WndProc(m)
    End Sub

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

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

    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(_handle)
        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
        ' Sie sollten diesen Code nicht ändern, sondern stattdessen ihren
        ' Bereinigungscode oben in 
        ' Dispose(ByVal disposing As Boolean) einfügen.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

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

#End Region

End Class
