你想不想用VB编写一个剪贴板查看程序呢?你可能会问:怎样才能检测到剪贴板的变化呢?这个问题历来被认为是VB
的难题,许多人甚至断言VB不能做到。因为VB的Clipboard对象根本没有事件,也没有相关的属性,让人觉得束手无策。为
了探究剪贴板变化的奥秘,笔者进行了一个实验:用Spy++监测剪贴板查看程序和一个普通程序(如记事本),当剪贴板的
内容改变时,剪贴板查看程序接受到了WM_DRAWCLIPBOARD消息,而记事本则没有收到这样的消息。这就是问题的关键,必
须接受到这条消息,才能检测到剪贴板的变化。笔者通过查阅资料,发现只有将窗口设置成ClipboardViewer才能接受到这
条消息。现在解决了问题的第一步,如果接受到了这条消息,怎样转换为事件呢?笔者决定采用子类派生。这样问题就基
本解决了,现在给出一个例子,检测剪贴板的变化,并显示到文本框里。此例中用到了SetClipboardViewer函数,目的就
是将窗口设置成ClipboardViewer。为了安全,本例中将文本框设置成ClipboardViewer并用子类派生的办法截获文本框的
消息。
先建立一个窗体,命名为frmClipBoard,然后放置一个文本框,命名为txtMessage。添加如下代码:
Private Sub Form_Load()
注释:将文本框设置成ClipboardViewer
SetClipboardViewer txtMessage.hwnd
Show
prevWndProc = GetWindowLong(txtMessage.hwnd, GWL_WNDPROC)
注释:使用子类派生建立新窗口程序
SetWindowLong txtMessage.hwnd, GWL_WNDPROC, AddressOf WndProc
End Sub
Private Sub Form_Unload(Cancel As Integer)
注释:归还窗口程序
SetWindowLong txtMessage.hwnd, GWL_WNDPROC, prevWndProc
End Sub
添加一个模块,取名为modWndProc,然后加入这些代码:
Public Declare Function SetClipboardViewer Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _
ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Public Const WM_DRAWCLIPBOARD = &H308
Public Const GWL_WNDPROC = (-4)
Public prevWndProc As Long
Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
On Error Resume Next
注释:检测剪贴板变化的消息
If Msg = WM_DRAWCLIPBOARD Then
frmClipBoard.txtMessage.Text = Clipboard.GetText
End If
WndProc = CallWindowProc(prevWndProc, hwnd, Msg, wParam, lParam)
End Function
现在你可以运行这个程序了。还是要提醒一下,使用了子类派生的程序要非常小心,建议编译后运行,以免整个VB崩
溃,先保存哦!
本例只演示了文本的存取,要编写剪贴板查看程序,还需要检测剪贴板中信息的类型,如果你有兴趣,完全可以编写
功能超群的的新剪贴板查看程序。此外,在许多编程实例中,此技术都能用上!