Imports System.Windows.Interop Public Class ClipBoardViewer Implements IDisposable Dim Hwnd_ As HwndSource Dim ClipboardViewerNext_ As IntPtr Sub New(ByVal hwnd As HwndSource) Hwnd_ = hwnd Hwnd_.AddHook(AddressOf ClipBoardViewerHook) ClipboardViewerNext_ = SetClipboardViewer(Hwnd_.Handle) End Sub Public Shared ReadOnly WM_DRAWCLIPBOARD As Integer = &H308 Public Shared ReadOnly WM_CHANGECBCHAIN As Integer = &H30D Private Function ClipBoardViewerHook(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByRef handled As Boolean) As IntPtr Select Case msg Case WM_DRAWCLIPBOARD handled = True OnClipBoardTextChanged(Clipboard.GetText()) SendMessage(ClipboardViewerNext_, msg, wParam, lParam) Case WM_CHANGECBCHAIN 'Another clipboard viewer has removed itself... If wParam = CType(ClipboardViewerNext_, IntPtr) Then ClipboardViewerNext_ = lParam Else SendMessage(ClipboardViewerNext_, msg, wParam, lParam) End If End Select End Function Public Event ClipBoardTextChanged(ByVal Text As String) Protected Sub OnClipBoardTextChanged(ByVal Text As String) RaiseEvent ClipBoardTextChanged(Text) End Sub 'API declarations... Declare Auto Function SetClipboardViewer Lib "user32" (ByVal HWnd As IntPtr) As IntPtr Declare Auto Function ChangeClipboardChain Lib "user32" (ByVal HWnd As IntPtr, ByVal HWndNext As IntPtr) As Boolean Declare Auto Function SendMessage Lib "User32" (ByVal HWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Long Private disposedValue As Boolean = False ' To detect redundant calls ' IDisposable Protected Overridable Sub Dispose(ByVal disposing As Boolean) If Not Me.disposedValue Then If disposing Then ' TODO: free other state (managed objects). End If ' TODO: free your own state (unmanaged objects). ChangeClipboardChain(Hwnd_.Handle, ClipboardViewerNext_) ' TODO: set large fields to null. End If Me.disposedValue = True End Sub #Region " IDisposable Support " ' This code added by Visual Basic to correctly implement the disposable pattern. Public Sub Dispose() Implements IDisposable.Dispose ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above. Dispose(True) GC.SuppressFinalize(Me) End Sub #End Region End Class