什么函数可以获取剪贴板文本?(API)
另外,怎么实时监控剪贴板时候是否有更新?
问题点数:21、回复次数:37Top
1 楼hongyucn(宏宇)回复于 2001-01-23 08:10:00 得分 0
可以用OpenClipboard函数打开剪贴板,再用SetClipboardDate函数把数据放在具有指定的剪贴板格式的剪贴板上,最后要记得用CloseClipboard关闭剪贴板呀!
另外要实时监控剪贴板只要用一个记时器就好了,把原来剪贴板中的内容写如一个临时文件中,再把读出新的和原来的进行比较不就好了吗?其实不用记时器也可以,还可以用触发消息写!!Top
2 楼111222(www.111222.cn)回复于 2001-01-23 08:14:00 得分 0
你知道《我念你听》那种监控剪贴板的方法么?
写计数器可能会累坏机器,是下选。
通过什么触发消息呢?Top
3 楼111222(www.111222.cn)回复于 2001-01-23 08:16:00 得分 0
你能写一些代码给我参考么?
(我是新手,太嫩)
(我们重名哦,我也叫宏宇)Top
4 楼111222(www.111222.cn)回复于 2001-01-23 08:17:00 得分 0
hongyucn 得 10分
给出总分:10
您给的分数总和不是20。, 返回上一页。
这是怎么回事?Top
5 楼111222(www.111222.cn)回复于 2001-01-23 08:21:00 得分 0
如果我想把剪贴板文本写到RichEdit框里又该怎么写?(要求API,MFC一点不会)Top
6 楼111222(www.111222.cn)回复于 2001-01-23 08:30:00 得分 0
我在一个程序中找到下面代码,如果想把它移植到自己的程序里
(目的是将剪贴板内容写到指定RichEdit)
该做什么改动?
我对下面代码中
hClipData = GetClipboardData(CF_TEXT);
和
GlobalLock(hClipData);
存在很大疑问。
case ID_SPEAK_FROMCLIPBOARD://接受COMMAND消息
{
PTSTR pszClipboard;
HANDLE hClipData;
BOOL fRet;
fRet = OpenClipboard(NULL);
if (!fRet) {
//打开剪贴板失败
return 0;
}
if (!(hClipData = GetClipboardData(CF_TEXT)))//CF_TEXT是什么意思?
{
// 设置剪贴板数据失败
return 0;
}
if (!(pszClipboard = (PTSTR)GlobalLock(hClipData)))//这是判断什么的?
{
CloseClipboard();
return 0;
}
GlobalUnlock(hClipData);
CloseClipboard();
break;
}
}
break;Top
7 楼111222(www.111222.cn)回复于 2001-01-23 08:35:00 得分 0
哦,我明白了,CF_TEXT剪贴板格式。
其他问题还有待指点!Top
8 楼111222(www.111222.cn)回复于 2001-01-23 08:40:00 得分 0
TO:宏宇
今天过年哦(我都忘了)
“过年好!”Top
9 楼111222(www.111222.cn)回复于 2001-01-23 09:38:00 得分 0
谁!
谁?
谁~~~
谁····
能
详细
解答
啊?
我的心在等待~~~~
一直在等待 唉~~爱~~~哎~~~~Top
10 楼111222(www.111222.cn)回复于 2001-01-23 09:41:00 得分 0
<img src=http://go1.163.com/~heavenandearth/vc/rgn-2.gif>Top
11 楼hongyucn(宏宇)回复于 2001-01-23 13:44:00 得分 0
对了,我想了很久,要实时监控剪贴板除发消息我想应该是WM_RENDERFORMAT和WM_RENDRALLFORMATS你试一下,还有就是剪贴板拥有者在调用SetClipboardData之前不应该调用OpenClipboard函数!
最后同样祝你新年快乐!!!Top
12 楼111222(www.111222.cn)回复于 2001-01-23 16:54:00 得分 0
宏宇:
还有int i=5;个小时就演春节联欢晚会了,我没有多大兴趣关心晚会。
马上我开始研究你告诉我的两个剪贴板消息,我自己通过SAPI5做中文朗读软件,现在已经能够运行,效果十分好(基于微软的TTSAPP例子),还有很多问题希望能向你请教。(年不过了,我满脑子这朗读程序NOW!)
上面的程序经过我修改之后已经在程序中生效了,当我按“朗读剪贴板”之后就把剪贴板内容
通过SetDlgItemText函数把剪贴板内容写到EDIT编辑框,然后执行朗读函数···
我现在开始着手研究剪贴板监控。
另外,我想在这个程序里加上访问INTERNET的内容,浏览网页,同时朗读!
(我在API程序里插入WEB BROWSER控件,但是根本没有MFC程序中的效果)
我想,是不是要通过CSocketFile类?
或者WinInet类?
API通过什么实现?
你愿意共同开发这个软件么?
我高三,开学得猛追文化课,(2月中旬开学)
时间很紧迫,(想在开学之前完成这个东西)
等待你的消息!
我家电话是0451-3534753
我叫:张弘宇
年龄:18
男
愿意一起来么?(虽然我很菜,但我很吃苦[我能学的不错],就当你拉我一把,成么?)Top
13 楼111222(www.111222.cn)回复于 2001-01-23 16:56:00 得分 0
speech API SDK5的检体中文语音引擎真是棒极了!
相比之下,现在很火暴,很“出色”的《网络鹦鹉》、《我念你听》都很嫩。
不过,SAPI SDK5一共145MB,引擎在其中包含着,怎么分离出来加到自己的应用软件安装包里?
Top
14 楼111222(www.111222.cn)回复于 2001-01-23 17:00:00 得分 0
case IDC_CLIP://我在对话框里做了一个按钮,ID为IDC_CLIP,用来朗读剪贴板
{
PTSTR pszClipboard;
HANDLE hClipData;
BOOL fRet;
fRet = OpenClipboard(NULL);
if (!fRet)
{
//打开剪贴板失败
//return 0;
}
if (!(hClipData = GetClipboardData(CF_TEXT)))//把剪贴板内容赋值给hClipData
{
//剪贴板为空
//return 0;
}
if (!(pszClipboard = (PTSTR)GlobalLock(hClipData)))//把剪贴板内容赋值给pszClipboard
{
CloseClipboard();
//return 0;
}
SetDlgItemText(m_hWnd,IDE_EDITBOX,pszClipboard);//把剪贴板内容写到RICHEDIT框
GlobalUnlock(hClipData);
CloseClipboard();
HandleSpeak();//朗读RICH编辑框中中文文本,就是剪贴板内容
TTSAppStatusMessage( m_hWnd, _T("正在朗读剪贴板\r\n") );//提示用户正在朗读
}
break;Top
15 楼111222(www.111222.cn)回复于 2001-01-23 17:30:00 得分 0
宏宇,我试了,WM_RENDERFORMAT需要SetClipboardData 调用,我想是满足不了需求的,我的目的是当我在复制了其他应用程序中的文本剪贴板内容发生变化时,《读者》(朗读软件)跳出来自动朗读,这个SetClipboardData 函数在其他程序中被调用了么?
我想不通clipboard owner 是什么东西。
我常识了WM_COPY消息,也不行,根本没有响应。
我的方法如下:(八成错了吧?)
我在主窗口函数
DlgProcMain(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
中等消息
// Call the appropriate function to handle the messages
switch(uMsg)
{
//监控剪贴板
case WM_COPY:
MessageBox( NULL, _T("你已经成功的检测到了剪贴板消息!"), _T("成功"), MB_OK );
break;
//其他代码·········
}
一点效果都没有,
Top
16 楼111222(www.111222.cn)回复于 2001-01-23 17:36:00 得分 0
GlobalUnlock(hClipData);
之后是否需要调用GlobalFree(hClipData);函数?Top
17 楼111222(www.111222.cn)回复于 2001-01-23 17:48:00 得分 0
刚才我在另外的门诊里找到了
“首要解决的问题是截获剪贴板事件,可以用SetClipboardViewer()函数将自已的View加入剪贴板响应视窗链中,然后增加对WM_DRAWCLIPBOARD和WM_CHANGECBCHAIN这两个消息的响应,这样就可以在剪贴板内容变化时截获其内容,只要分别管理保存的内容就可以实现多重剪贴内容选择了。”
这样一则
是不是可以监测到消息?Top
18 楼hongyucn(宏宇)回复于 2001-01-23 19:11:00 得分 0
你早说呀,象你说的那种程序,我在大一时就开发过,而且很成功!Top
19 楼hongyucn(宏宇)回复于 2001-01-23 19:13:00 得分 0
但当时我是用VB开发的,不是用的VC或者C++Builder,因为VB对多媒体支持的特别好,有些已经集成了!Top
20 楼hongyucn(宏宇)回复于 2001-01-23 19:14:00 得分 0
你说的SetClipboardViewer函数让我来查查看!Top
21 楼hongyucn(宏宇)回复于 2001-01-23 19:31:00 得分 0
我刚才查过MSDN,SetClipboardViewer函数功能是把指定的窗口加到剪贴板中。剪贴板观察窗口剪贴板无论怎么样变化,都接收到一个WM_DRARCLIPBOARD消息。要注意的是作为剪贴板观察链一部分的窗口或被称做剪贴板观察窗口,它必须处理剪贴板的WM_DRARCLIPBOARD消息或者WM_CHANGCBCHAIN消息,每个窗口剪贴板观察窗口都要调用SendMessage函数才能把这些消息传递到下一个窗口!我的OICQ:1808283,宏宇欢迎你!!Top
22 楼111222(www.111222.cn)回复于 2001-01-23 20:23:00 得分 0
现在春节联欢晚会开始了,我不看了(不是心血来潮想抓紧时间···)
我一直想让程序支持HTTP,就是让朗读软件(TTS)朗读网页,因为SAPI5的引擎支持XML
所以软件可以自动解析<html>的“<”标记,跳过超文本,直接朗读网页内容···
(暂时不能识别JAVASCRIPT,这个解决起来倒是很轻松···)
哦?你在OICQ上,我来了!
Top
23 楼111222(www.111222.cn)回复于 2001-01-23 21:39:00 得分 0
/*下面是WINSOCK下载网页的部分*/
char fname[100];
void LogFile(char *p)//p是字符串指针,为网页文本内容
{
FILE *fp=fopen(fname,"a+");//采用追加方式带开文件
fprintf(fp,"%s\n",p);
fclose(fp);
}
BOOL HttpClient(void)//核心函数
{
WSADATA ws; //WINSOCK数据
SOCKET s; //套接字
struct sockaddr_in addr;
int iResult;
long lResult;
char strSubAddr[100], strBuffer[100];//地址字符数组和文件内容
lResult = WSAStartup(0x0101,&ws);
s = socket(AF_INET,SOCK_STREAM,0);
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
addr.sin_addr.s_addr = inet_addr("168.160.224.185"); // 计算机世界日报
iResult=connect(s,(struct sockaddr *)&addr, sizeof(addr));
if(SOCKET_ERROR == iResult)
{
// 连接失败
WSACleanup();
return FALSE;
}
else {
// 连接成功
strcpy(strSubAddr, "GET /99/ \r\n");
strcpy(fname, "index.html");
iResult = send(s, strSubAddr,strlen(strSubAddr),0);
// 下载文件
do {
strset(strBuffer,' ');
iResult = recv(s,strBuffer,sizeof(strBuffer),0);
LogFile(strBuffer);
} while( iResult !=0 );
}
WSACleanup();
return TRUE;
}
编译成功,LINK过程出现错误,如下
--------------------Configuration: TTSApp - Win32 Debug--------------------
Compiling resources...
Compiling...
globals.cpp
Skipping... (no relevant changes detected)
childwin.cpp
dlgmain.cpp
winmain.cpp
Linking...
dlgmain.obj : error LNK2001: unresolved external symbol __imp__recv@16
dlgmain.obj : error LNK2001: unresolved external symbol __imp__send@16
dlgmain.obj : error LNK2001: unresolved external symbol __imp__WSACleanup@0
dlgmain.obj : error LNK2001: unresolved external symbol __imp__connect@12
dlgmain.obj : error LNK2001: unresolved external symbol __imp__inet_addr@4
dlgmain.obj : error LNK2001: unresolved external symbol __imp__htons@4
dlgmain.obj : error LNK2001: unresolved external symbol __imp__socket@12
dlgmain.obj : error LNK2001: unresolved external symbol __imp__WSAStartup@8
Debug/ttsapp.exe : fatal error LNK1120: 8 unresolved externals
Error executing link.exe.
ttsapp.exe - 9 error(s), 0 warning(s)
不知道如何解决!
Top
24 楼111222(www.111222.cn)回复于 2001-01-23 22:09:00 得分 0
宏宇,上面LINK错误已经解决,考虑到是unresolved external 想到可能是没有声明,随即找了找相关的资料,发现必须在工程——设置———连接中包含wsock32.lib
之后,程序正常运行,下载到了网页了。Top
25 楼111222(www.111222.cn)回复于 2001-01-23 22:28:00 得分 0
问题又出现!
我想把网页内容直接输入到RichEdit框在
// 下载文件
do {
strset(strBuffer,' ');
iResult = recv(s,strBuffer,sizeof(strBuffer),0);
SetDlgItemText( m_hWnd, IDE_EDITBOX, strBuffer);//此处是后添加的代码
//error C2065: 'm_hWnd' : undeclared identifier
//这样“m_hWnd”不行,能不能用postmessage传递消息?
LogFile(strBuffer);
Top
26 楼111222(www.111222.cn)回复于 2001-01-23 22:43:00 得分 0
我需要在该WINSOCK对话框里加一个edit框用来写URL
URL一般为http://***.***.***.***/dir/somefile.htm(或者html\xmp\asp\cgi\pl\php\php3等等)
因为winsock是先连接***.***.***.***站点通过80端口
然后send(SOCKET s, "GET /dir/",strlen("GET /dir/somefile.htm"),0);
打开目录
之后再recv(SOCKET s,strBuffer,sizeof(strBuffer),0);
····
我必须把用户输入到edit框里的char* URL分解成几部分
“http://”//用if(前7个字符=“http://")则URL+=7;
IP //可以通过
目录
哦,OICQ上见到你了,我来拉!Top
27 楼111222(www.111222.cn)回复于 2001-01-24 09:43:00 得分 0
宏宇,
地址栏(用来书写URL的地方,IE中的地址栏就是,ReBar可以进行改画··)
用ReBar可以么?把ReBar建立在对话框程序了是不是有些小题大做?
我找到ReBar的API建立代码
HWND WINAPI CreateRebar(HWND hwndOwner)
{
REBARINFO rbi;
REBARBANDINFO rbBand;
RECT rc;
HWND hwndCB, hwndTB, hwndRB;
DWORD dwBtnSize;
INITCOMMONCONTROLSEX icex;
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
icex.dwICC = ICC_COOL_CLASSES¦ICC_BAR_CLASSES;
InitCommonControlsEx(&icex);
hwndRB = CreateWindowEx(WS_EX_TOOLWINDOW,
REBARCLASSNAME,
NULL,
WS_CHILD¦WS_VISIBLE¦WS_CLIPSIBLINGS¦
WS_CLIPCHILDREN¦RBS_VARHEIGHT¦CCS_NODIVIDER,
0,0,0,0,
hwndOwner,
NULL,
g_hinst,
NULL);
if(!hwndRB)
return NULL;
// Initialize and send the REBARINFO structure.
rbi.cbSize = sizeof(REBARINFO); // Required when using this struct.
rbi.fMask = 0;
rbi.himl = (HIMAGELIST)NULL;
if(!SendMessage(hwndRB, RB_SETBARINFO, 0, (LPARAM)&rbi))
return NULL;
// Initialize structure members that both bands will share.
rbBand.cbSize = sizeof(REBARBANDINFO); // Required
rbBand.fMask = RBBIM_COLORS ¦ RBBIM_TEXT ¦ RBBIM_BACKGROUND ¦
RBBIM_STYLE ¦ RBBIM_CHILD ¦ RBBIM_CHILDSIZE ¦
RBBIM_SIZE;
rbBand.fStyle = RBBS_CHILDEDGE ¦ RBBS_FIXEDBMP;
rbBand.hbmBack= LoadBitmap(g_hinst, MAKEINTRESOURCE(IDB_BACKGRND));
// Create the combo box control to be added.
hwndCB = CreateComboBox(hwndRB);
// Set values unique to the band with the combo box.
GetWindowRect(hwndCB, &rc);
rbBand.lpText = "Combo Box";
rbBand.hwndChild = hwndCB;
rbBand.cxMinChild = 0;
rbBand.cyMinChild = rc.bottom - rc.top;
rbBand.cx = 200;
// Add the band that has the combo box.
SendMessage(hwndRB, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
// Create the toolbar control to be added.
hwndTB = CreateToolbar(hwndOwner, dwStyle);
// Get the height of the toolbar.
dwBtnSize = SendMessage(hwndTB, TB_GETBUTTONSIZE, 0,0);
// Set values unique to the band with the toolbar.
rbBand.lpText = "Tool Bar";
rbBand.hwndChild = hwndTB;
rbBand.cxMinChild = 0;
rbBand.cyMinChild = HIWORD(dwBtnSize);
rbBand.cx = 250;
// Add the band that has the toolbar.
SendMessage(hwndRB, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);
return (hwndRB);
}
是不是可以移植到程序中?Top
28 楼111222(www.111222.cn)回复于 2001-01-24 09:44:00 得分 0
我想把界面该花俏一些,像REALPLAYER···抛弃WINDOWS传统界面,需要怎么做?Top
29 楼111222(www.111222.cn)回复于 2001-01-24 10:14:00 得分 0
宏宇!
我刚才用SPY++查了剪贴板消息,在剪贴板执行了“复制”之后的消息是WM_DESTROYCLIPBOARD
我现在尝试获取这个消息,我想到的问题是,剪贴板消息能公用么?Top
30 楼111222(www.111222.cn)回复于 2001-01-24 10:16:00 得分 0
WM_RENDERFORMAT消息是在执行了WM_PASTE后才SEND的Top
31 楼111222(www.111222.cn)回复于 2001-01-24 10:39:00 得分 0
我在DlgProcMain(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
switch(uMsg)
{
case WM_DESTROYCLIPBOARD:
//自动朗读剪贴板内容
return TRUE;
//下面省略
}
为什么收不到消息?
是不是跟进程有关系?
spy++是怎么工作的?
是不是要用HOOK?Top
32 楼touhu(虾仔)回复于 2001-01-24 18:07:00 得分 21
真是活见鬼!高手哪去了?!!!!
先用SetClipboardViewer ,再过滤 WM_DRAWCLIPBOARD 消息!Top
33 楼111222(www.111222.cn)回复于 2001-01-24 22:14:00 得分 0
问题解决了!Top
34 楼111222(www.111222.cn)回复于 2001-01-24 22:22:00 得分 0
touhu
不能给分了,总说我给的分数不是20;
毕竟分代表不了什么,我再问你一下,我想SetClipboardViewer后通过按钮控制让程序停止监控剪贴板,那该用什么函数?
SetClipboardViewer(其他窗口)?
Top
35 楼touhu(虾仔)回复于 2001-01-25 00:18:00 得分 0
这好像不行,你只要不处理 WM_DRAWCLIPBOARD 消息就行了;如果你是想把 剪贴板的监控权 交还给原来的程序,你可以在调用 SetClipboardViewer 前先用 GetClipboardViewer 得到原来的窗口句柄...Top
36 楼111222(www.111222.cn)回复于 2001-01-25 01:18:00 得分 0
把监控权随便叫给一个窗口就可以了吧,交给该程序的子窗口句柄可以么?(想到其他程序不会监控剪贴板,所以,监控权给谁都是可以的)Top
37 楼touhu(虾仔)回复于 2001-01-26 00:21:00 得分 0
应该可以吧!Top




