You can use SetClipboardViewer to know about clipboard changes. You will receive a WM_DRAWCLIPBOARD message when the content changes.
Imports System.Runtime.InteropServices
Public Class Form1
Private hwndNextChain As IntPtr
Public Sub New()
InitializeComponent()
End Sub
Protected Overrides Sub OnHandleCreated(e As EventArgs)
MyBase.OnHandleCreated(e)
hwndNextChain = SetClipboardViewer(Me.Handle)
End Sub
Protected Overrides Sub OnHandleDestroyed(e As EventArgs)
MyBase.OnHandleDestroyed(e)
ChangeClipboardChain(Me.Handle, hwndNextChain)
End Sub
Protected Overrides Sub WndProc(ByRef m As Message)
Select Case m.Msg
Case WM_DRAWCLIPBOARD
If hwndNextChain <> IntPtr.Zero Then
SendMessage(hwndNextChain, m.Msg, m.WParam, m.LParam)
End If
If Clipboard.ContainsText() Then
Dim clipboardText As String = Clipboard.GetText()
TextBox1.AppendText(clipboardText & vbCrLf)
Debug.WriteLine($"{Now} Change Clipboard")
End If
Case WM_CHANGECBCHAIN
If m.WParam = hwndNextChain Then
hwndNextChain = m.LParam
ElseIf hwndNextChain <> IntPtr.Zero Then
SendMessage(hwndNextChain, m.Msg, m.WParam, m.LParam)
End If
End Select
MyBase.WndProc(m)
End Sub
<DllImport("User32.Dll")>
Private Shared Function SendMessage(hWnd As IntPtr, Msg As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)>
Private Shared Function SetClipboardViewer(hWndNewViewer As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True)>
Private Shared Function ChangeClipboardChain(hWndRemove As IntPtr, hWndNewNext As IntPtr) As Boolean
End Function
Private Const WM_DRAWCLIPBOARD As Integer = &H308
Private Const WM_CHANGECBCHAIN As Integer = &HD
End Class