原以为很简单的问题,花了近4个月的时间,一直没能很好地解决,纠结ing据说SendMessage是发消息并等待消息的处理结果,然后再执行一下句;
PostMessage是把消息放到消息队列里就返回继续执行下一句。实际上,经过多次试验,向别的程序发送消息,不管是::SendMessage还是::PostMessage,后面不跟一个Sleep(n)或者别的延时,都可能返回0,下一句得以继续执行,而此时目标程序可能接到了消息,也可能没接到;只有n足够大的时候,才能保证目标程序正确收到消息。也就是说,向目标程序的特定文本框发送一个字符串,标准方式是:
for i := 0 to Length(cStr)-1 do
begin
PostMessage(hCtrlHandle,WM_CHAR,Wparam(cStr[i]),1);
Sleep(iDelay);
Application.ProcessMessages;
end;
或者:
SendMessage(hCtrlHandle,WM_SETTEXT,0,sStr);
Sleep(iDelay);好吧,这样也挺不错的。问题是,iDelay 应该取多少呢?iDelay<=600的时候,我的程序在T4400双核CPU、2G内存的本本上运行得很好,但放到1.5G单核CPU、1G内存的台式机上,发送消息就经常失败了:(如何才能根据CPU的主频自动计算出延时值iDelay,既保证消息发送成功,又尽量避免多余的延时时间?
PostMessage是把消息放到消息队列里就返回继续执行下一句。实际上,经过多次试验,向别的程序发送消息,不管是::SendMessage还是::PostMessage,后面不跟一个Sleep(n)或者别的延时,都可能返回0,下一句得以继续执行,而此时目标程序可能接到了消息,也可能没接到;只有n足够大的时候,才能保证目标程序正确收到消息。也就是说,向目标程序的特定文本框发送一个字符串,标准方式是:
for i := 0 to Length(cStr)-1 do
begin
PostMessage(hCtrlHandle,WM_CHAR,Wparam(cStr[i]),1);
Sleep(iDelay);
Application.ProcessMessages;
end;
或者:
SendMessage(hCtrlHandle,WM_SETTEXT,0,sStr);
Sleep(iDelay);好吧,这样也挺不错的。问题是,iDelay 应该取多少呢?iDelay<=600的时候,我的程序在T4400双核CPU、2G内存的本本上运行得很好,但放到1.5G单核CPU、1G内存的台式机上,发送消息就经常失败了:(如何才能根据CPU的主频自动计算出延时值iDelay,既保证消息发送成功,又尽量避免多余的延时时间?
SendMessage 与 PostMessage都具可靠性.当然也有很小机率会失败.对于MFC程式封装的API也是使用这两个函数来实现消息传递.若像你那样描述....MFC程式在老机子上就频繁不工作?
The return value specifies the result of the message processing; it depends on the message sent.
A、调出“打开”对话框;
B、自动选择打开文件类型;
C、自动填入文件名;
D、自动执行“打开”按钮的功能;
E、调出“另存为”对话框;
F、自动选择“保存类型”为JPEG;
G、自动填入文件名;
H、自动执行“保存”按钮的功能;简单的说,就是后台调用XP自带的画图程序批量进行图像文件格式转换。在步骤A-H中,大量用到了PostMessage和SendMessage,比如调用画图的菜单打开对话框、选择下拉列表框、填入文件名等等。
hCtrlHandle是内存变量,用于保存目标控件的句柄;该句柄是用FindWindowEx找到的。
多次试验的结果,如果不是发送文本到CEdit控件,比如操纵菜单、选择下拉列表框的选项等,是不需要Sleep,但向CEdit控件填入文件名,不管是用PostMessage循环发WM_CHAR消息,还是用SendMessage直接发送WM_SETTEXT消息,都需要Sleep(n),而且n必须达到一定的大小,否则CEdit控件的内容就会为空。显然,这个问题不是SendMessage和PostMessage引起的,而是两个不同进程之间同步的问题。因为MSPAINT.EXE是外部程序,没有源码,所以只能用延时等待来实现进程之间的同步。问题是如何测算延时量,才能在不同主频的电脑都保证进程之间的同步?PS:还有个奇怪的问题,每次发送文本失败,用GetLastError取得的错误代码,都是“无效的句柄”,但句柄是事先用FindWindowEx找到并且检验过的。
怀疑是参数的问题,比如 如果传递的是用户自定义消息,而消息ID定义小于 WM_USER
就是这种情况,所以要Sleep让出CPU并等待对方处理。问题就是如何判断这个Sleep等待的时间值。TO xxd_qd & tylin_124 & smallfishff & test_machine:
你们说的都对,近4个月的时间,这些我都一一检查、试验、验证过了,只有发送WM_SETTEXT或者WM_CHAR消息的时候才会出现问题。TO ljhnew:
是找到的另一个进程中CEdit控件的句柄,已经判断无误了。TO m_tornado:
MSPAINT.EXE当然不是自己的程序,没办法直接调用该函数(其实办法也有,那些太麻烦了)TO MildSong:
"不管是用PostMessage循环发WM_CHAR消息,还是用SendMessage直接发送WM_SETTEXT消息"
当然不是自定义消息啦。还有,如果是参数的问题,肯定不会使用Sleep(n)且“只有n足够大的时候,才能保证目标程序正确收到消息。”TO aa65433:
setwindowtext函数,设置编辑框的内容只对当前进程有效,不能设置另一个进程中的CEdit文本。TO VisualEleven:
MSDN官方的帮助已经反复看了数百遍,麻烦大大不要再复制粘贴,以免浪费您的宝贵时间。
至于延时的问题,灵敏度和可靠性本来就是一对矛盾,在你不知道mspaint的源码情况下。就算知道也没多大用。
比如,一个高配置的机器600ms一般就够用了,但当他开着3个BT,2个高清电影,还开着杀毒软件时,6000毫秒也不一定够用。
PostMessage(hCtrlHandle,WM_CHAR,Wparam(cStr[i]),1);
换成这样行不?
SendMessage (hCtrlHandle, WM_CHAR, "x", 0);然后你可以单独使用
SendMessage(hCtrlHandle,WM_SETTEXT,0,sStr);获取那个程式的其它控件的文本咯.
如果不成功再使用同样的方法获取另外一个程式的控件文本....这样排除下看看是什么问题.
如果你的实现了,不知道可否拿来与大家分享?谢谢.
[email protected]
不好意思,很久没上CSDN。我在发此贴之前就分别用VC和DELPHI实现了这个程序的基本功能,能批量转换格式、缩小JPEG文件大小、放缩和旋转图片,没继续完善了。不知你动手做了没有,我的程序叫JPEGSliming,发到你邮箱去了,试用后请反馈意见,谢谢