请问怎么监视剪切版?

caiCC 2005-04-24 08:58:32
我想实现剪切版进入字符串后就做一些事情.请问怎么监视剪切版?
...全文
397 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
hxy2003 2005-05-22
  • 打赏
  • 举报
回复
?
j_x_y 2005-05-21
  • 打赏
  • 举报
回复
大意了,多写了一个 Public Const WM_DRAWCLIPBOARD = &H308
j_x_y 2005-05-21
  • 打赏
  • 举报
回复
模块代码

'要实现实时监视剪贴板必须将自己的程序注册成为剪贴板查看器(即加入链表中)。
'首先新建一个工程,在Form1上增加一个Memo控件,然后在Form1的.h里面加上
'#include <vcl\Clipbrd.hpp>,因为下面要用到的API函数大多是在该头文件中定义的。
'在Form1的.h的public加上:
'BEGIN_MESSAGE_MAP
'MESSAGE_HANDLER(WM_DRAWCLIPBOARD,TMessage,ClipboardChanged) //映射这个消息
'END_MESSAGE_MAP (TForm)
'HWND LastHandle;// 用于保存剪贴板查看器链中下一个窗口的句柄。
'接下来,当然是把自己的程序窗口注册成为剪贴板查看器了。在Form1的OnCreate
'事件中加入一句:
' LastHandle=SetClipboardViewer(Form1->Handle);
' 该函数会将指定的窗口加入剪贴板查看器链,参数handle就是你欲新加入的窗口的
'句柄,返回值则为系统的剪贴板查看器链中下一个窗口的句柄。
' 当你自己的程序退出时,必须从剪贴板查看器链中删除本窗口。在Form1的OnClose
'事件中加入两句:
'ChangeClipboardChain(Form1->Handle,LastHandle);
'函数ChangeClipboardChain是SetClipboardViewer的逆操作,能将第一个参数handle
'指定的窗口从剪贴板查看器链中删除,第二个参数是剪贴板查看器链中下一个窗口的
'句柄,是供系统调整剪贴板查看器链表用的,我们不用管它。
'最后一步,也是最关键的一步,如果剪贴板内容有变化,窗口将自动激活
'WM_DRAWCLIPBOARD消息,也即间接地实现了让剪贴板向自己的程序发消息的功能,
'这就能够实时监视剪贴板,相信网络蚂蚁也应该是用这个方法。有一点要注意的是,
'在接收处理WM_DRAWCLIPBOARD消息时要将消息传递给剪贴板查看链中的下一个窗口,
'以便让其它程序也能监视剪贴板,因为该消息只直接发给链中的第一个程序,其他
'程序不会直接收到该消息。

Public Const WM_DRAWCLIPBOARD = &H308 '剪贴板内容改变时发生的消息
Public Const GWL_WNDPROC = (-4)
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 Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function ChangeClipboardChain Lib "user32" (ByVal hWnd As Long, ByVal hWndNext As Long) As Long
Public Declare Function SetClipboardViewer Lib "user32" (ByVal hWnd As Long) As Long


Public Const WM_DRAWCLIPBOARD = &H308 '剪贴板内容改变时发生的消息

Public FrmhWnd As Long '原窗口地址



Function WndProc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal iParam As Long) As Long
If Msg = WM_DRAWCLIPBOARD Then
'这里写你处理的代码
'If Clipboard.GetFormat(vbCFBitmap) Then '位图
'Form1.Picture1.Picture = Clipboard.GetData(vbCFBitmap)

'ElseIf Clipboard.GetFormat(vbCFText) Then '文本

'End If
End If

'还原窗口原来的窗口程序,让它来处理其他的消息
WndProc = CallWindowProc(FrmhWnd, Form1.hWnd, Msg, wParam, iParam)

End Function


'===========剪贴板中其他格式数据

'vbCFText 1 文本(.txt文件)
'vbCFBitmap 2 位图(.bmp文件)
'vbCFMetafile 3 元文件(.wmf文件)
'vbCFEMetafile 14 增强元文件(.emf 文件)
'vbCFDIB 8 设备无关位图 (DIB)
'vbCFPalette 9 调色板
'vbCFFiles 15 文件列表
'vbCFRTF -16639 丰富文本格式(.rtf文件)



窗体代码
Option Explicit

Dim SetClipBoardView As Long


Private Sub Form_Load()
'记录原窗口程序
FrmhWnd = GetWindowLong(Me.hWnd, GWL_WNDPROC)

'设置回调地址
SetWindowLong Me.hWnd, GWL_WNDPROC, AddressOf WndProc

'把窗口注册成为剪贴板查看器
SetClipBoardView = SetClipboardViewer(Me.hWnd)
End Sub

Private Sub Form_Unload(Cancel As Integer)
'注销剪贴板查看器
ChangeClipboardChain Me.hWnd, SetClipBoardView

'还原窗口程序
SetWindowLong Me.hWnd, GWL_WNDPROC, FrmhWnd
End Sub
DooDu 2005-05-17
  • 打赏
  • 举报
回复
c的:


实现网络蚂蚁的实时监视剪贴板功能
作者:黑龙江省五大连池 马明臣
我们知道,网络蚂蚁能够实时地监视剪贴板,如果我们能够在自己的程序中实现这个功能,肯定为我们的程序增色不少。
那它到底是如何实现的呢?我们可以想到的最简单的方法是,直接开个计时器,定时检查剪贴板上的内容,或者另写个线程来检查。这两个方法都能够监视剪贴板,但遗憾的是实时性太差,又占用了系统的大量资源,很不合算。好一点的方法可以用Win32API中关于剪贴板钩子(HOOK)的函数,只要安装了剪贴板的钩子函数,就可以做到实时地监视剪贴板,因为任何剪贴板的改变都会触发一条消息,而钩子函数拦截了这条信息。然而,这要求当前程序必须要有机会获得CPU控制权才能处理这个消息。如果该程序这时并没有释放CPU,监视剪贴板的程序并不能处理消息。只有当该程序执行完了之后,别的程序才能获得处理机会,但此时,剪贴板只剩下最后一次粘贴的内容了。而且,使用钩子函数非常危险,一旦你的程序出了问题,整个系统也就跟着瘫痪了。
既然这些方法都不太理想,那我们不妨转换一下思维,不再去管剪贴板,而想想如何让剪贴板直接向自己的程序发消息,这样肯定能做到百分之百的实时。为此我仔细的查看了各种Windows的编程资料,结果是:因为剪贴板不具有自己的句柄(Handle),它本身也不是Windows的一个类,故剪贴板是不会自己发消息的。但是系统是如何能够接收剪切/拷贝到剪贴板等命令呢?也即是如何接收WM_COPY和WM_CUT,WM_PASTE等消息呢?经过研究发现能够发送消息的是剪贴板查看器,原来多个剪贴板查看器依次连接成剪贴板查看链。因此,要实现实时监视剪贴板必须将自己的程序注册成为剪贴板查看器(即加入链表中)。下面笔者以C++ Builder 5.0为例编程说明其具体实现过程。
首先新建一个工程,在Form1上增加一个Memo控件,然后在Form1的.h里面加上#include <vcl\Clipbrd.hpp>,因为下面要用到的API函数大多是在该头文件中定义的。
在Form1的.h的public加上:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_DRAWCLIPBOARD,TMessage,ClipboardChanged) //映射这个消息
END_MESSAGE_MAP(TForm)
HWND LastHandle;// 用于保存剪贴板查看器链中下一个窗口的句柄。
接下来,当然是把自己的程序窗口注册成为剪贴板查看器了。在Form1的OnCreate事件中加入一句:
LastHandle=SetClipboardViewer(Form1->Handle);
该函数会将指定的窗口加入剪贴板查看器链,参数handle就是你欲新加入的窗口的句柄,返回值则为系统的剪贴板查看器链中下一个窗口的句柄。
当你自己的程序退出时,必须从剪贴板查看器链中删除本窗口。在Form1的OnClose事件中加入两句:
ChangeClipboardChain(Form1->Handle,LastHandle);
函数ChangeClipboardChain是SetClipboardViewer的逆操作,能将第一个参数handle指定的窗口从剪贴板查看器链中删除,第二个参数是剪贴板查看器链中下一个窗口的句柄,是供系统调整剪贴板查看器链表用的,我们不用管它。
最后一步,也是最关键的一步,如果剪贴板内容有变化,窗口将自动激活 WM_DRAWCLIPBOARD消息,也即间接地实现了让剪贴板向自己的程序发消息的功能,这就能够实时监视剪贴板,相信网络蚂蚁也应该是用这个方法。有一点要注意的是,在接收处理WM_DRAWCLIPBOARD消息时要将消息传递给剪贴板查看链中的下一个窗口,以便让其它程序也能监视剪贴板,因为该消息只直接发给链中的第一个程序,其他程序不会直接收到该消息。
程序如下,在Form1的.h的private加上:
void __fastcall ClipboardChanged(TMessage& Msg);
再编写自己的处理过程,这就是你自由发挥的地方了。本例设为自动将剪贴板的文本粘贴到Memo控件中。
在Form1的.cpp内加上:
void __fastcall TForm1::ClipboardChanged(TMessage& Msg)
{
 if (Clipboard()->HasFormat(CF_TEXT))
Memo1->Text = Clipboard()->AsText;
}
这一过程中使用了 TClipboard 类的 Clipboard 函数获取剪贴板内文本内容,至于如何获取剪贴板内的其它非文本类型的内容则不在本文讨论范围内了,读者可自己在C++ Builder中输入TClipboard ,再按F1,键,就可以看到各个函数的详细用法了,不过这些帮助可都是英文的呀!
以上程序在C++ Builder 5.0+PWIN98系统下调试通过,由于笔者水平有限,上文如有不妥之处,请大家与我一起探讨。


http://cache.baidu.com/c?word=%CA%B5%CA%B1%3B%BC%E0%CA%D3%3B%BC%F4%CC%F9%3B%B0%E5&url=http%3A//www%2Edelphijs%2Ecom/Article%5FPrint%2Easp%3FArticleID%3D1320&b=0&a=29&user=baidu

delphi的
j_x_y 2005-05-16
  • 打赏
  • 举报
回复
怎么注册为clipboard viewer chain
caiCC 2005-05-09
  • 打赏
  • 举报
回复
请问,能给出一个详细点的列子吗?谢谢!
jlum99 2005-04-26
  • 打赏
  • 举报
回复
当然能了,这个也算是标准方法了,不用轮讯。当剪贴板内容改变的时候,系统会给clipboard viewer chain链上的程序发送WM_DRAWCLIPBOARD消息。在自己程序里用子类处理这个消息就可以了。子类的相关文章CSDN里找的到。用到的API上面都提到了。具体的声明和用法可以自己找找
jlum99 2005-04-25
  • 打赏
  • 举报
回复
系统有个Clipboard Viewer Chain的,正确的方法是把自己的程序注册为Clipboard Viewer的.Clipboard Viewer Chain是保存Clipboard Viewer窗口以及他们之间的前后向关系的一个Windows系统链表,当一个窗口注册为Clipboard Viewer后,他会被加入Clipboard Viewer Chain,并得到链表中下一个Viewer窗口的句柄,该句柄必须保存以在响应消息时使用,该句柄的作用在下文说明。Windows正是通过Clipboard Viewer Chain保证了所有Clipboard Viewer能接收和响应剪贴板变化消息。在消息响应里必须正确处理两个消息:WM_DRAWCLIPBOARD和WM_CHANGECBCHAIN.所以要用到子类化技术,来自己处理系统消息。主要是负责传递这个链条上的消息,否则到你这就断了,后加入的程序就抓瞎了。关闭程序时是要注销。
函数就用到SetClipboardViewer ChangeClipboardChain SendMessage
MmMVP 2005-04-25
  • 打赏
  • 举报
回复
Private Sub Command1_Click()
Text2.Text = Clipboard.GetText(vbCFText)
End Sub

Private Sub Command2_Click()
Clipboard.SetText Text1.Text
End Sub

Private Sub Command3_Click()
Clipboard.SetData Picture1.Picture, vbCFBitmap
End Sub

Private Sub Command4_Click()
Picture2.Picture = Clipboard.GetData(vbCFBitmap)
End Sub

Private Sub Form_Load()
Dim astr As String

astr = Clipboard.GetFormat(vbCFLink)
If astr = "" Then
labCFStatus.Caption = "剪贴版包含未知数据"
Else
If astr = "True" Then
labCFStatus.Caption = "剪贴版包含DDE会话"
End If
astr = Clipboard.GetFormat(vbCFText)
If astr = "True" Then
labCFStatus.Caption = "剪贴版包含文本"
End If
astr = Clipboard.GetFormat(vbCFRTF)
If astr = "True" Then
labCFStatus.Caption = "剪贴版包含RTF文本"
End If
End If
End Sub
happy_sea 2005-04-25
  • 打赏
  • 举报
回复
楼上的方法能捕捉到类似于“Clipboard_Change()”事件吗?具体怎么用?
wzzwwz 2005-04-24
  • 打赏
  • 举报
回复
慢了
wzzwwz 2005-04-24
  • 打赏
  • 举报
回复
用 Clipboard.GetText 可以获得剪贴板中的文字
你用个定时器时刻对照一下
happy_sea 2005-04-24
  • 打赏
  • 举报
回复
用timer控件
private sub timer1_timer()
if clipboard.gettext<>"" then
......
end if
end sub

1,488

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧