Option Strict On Option Explicit On Imports System.Runtime.InteropServices Public Class Form1 Private Const WM_DRAWCLIPBOARD As Integer = &H308 Private Const WM_CHANGECBCHAIN As Integer = &H30D Private mNextClipBoardViewerHWnd As IntPtr Private Event OnClipboardChanged() <DllImport("user32")> _ Private Shared Function SetClipboardViewer(ByVal hWnd As IntPtr) As IntPtr End Function <DllImport("user32")> _ Private Shared Function ChangeClipboardChain(ByVal hWnd As IntPtr, ByVal hWndNext As IntPtr) As _ <MarshalAs(UnmanagedType.Bool)> Boolean End Function <DllImport("user32")> _ Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, _ ByVal lParam As IntPtr) As IntPtr End Function Sub New() InitializeComponent() mNextClipBoardViewerHWnd = SetClipboardViewer(Me.Handle) AddHandler Me.OnClipboardChanged, AddressOf ClipBoardChanged End Sub Protected Overrides Sub WndProc(ByRef m As Message) Select Case m.Msg Case WM_DRAWCLIPBOARD RaiseEvent OnClipboardChanged() SendMessage(mNextClipBoardViewerHWnd, m.Msg, m.WParam, m.LParam) Case WM_CHANGECBCHAIN If m.WParam.Equals(mNextClipBoardViewerHWnd) Then mNextClipBoardViewerHWnd = m.LParam Else SendMessage(mNextClipBoardViewerHWnd, m.Msg, m.WParam, m.LParam) End If End Select MyBase.WndProc(m) End Sub Private Sub ClipBoardChanged() Dim data As IDataObject = Clipboard.GetDataObject() If data.GetDataPresent(GetType(Bitmap)) Then Me.BackgroundImage = DirectCast(data.GetData(GetType(Bitmap)), Bitmap) End If End Sub Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing ChangeClipboardChain(Me.Handle, mNextClipBoardViewerHWnd) End Sub End Class
To use: start a few instances of the program. Copy an image into the clipboard - the backgrounds of the forms should change. Then close one of the forms and change the image in the clipboard - all the backgrounds should change.