Showing posts with label SetClipBoardViewer. Show all posts
Showing posts with label SetClipBoardViewer. Show all posts

10 December 2008

SetClipboardViewer API VB.NET

This registers a form as a clipboard viewer. It then recieves notification when something happens to the clipboard. Some post on the msdn forum. It mentioned: http://www.radsoftware.com.au/articles/ClipboardMonitor_VB.txt, which I've tidied up to my liking (a stray long, a strange cast removed, you can't override Dispose (could you before?))
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.