原以为很简单的问题,花了近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,既保证消息发送成功,又尽量避免多余的延时时间?

解决方案 »

  1.   

    hCtrlHandle?是啥控件?它是一个单独线程运行的控件吗?如果有个窗口存在,该句柄是否有效,最好在发送前判断。
      

  2.   

    PostMessage确实有时可能收不到消息,但SendMessage应该是有保证的,我觉得可能是出在参数传递的这一部分,您有没有试过不传递参数时,不用Sleep函数能不能接收到消息,我在使用中好像没有遇到这样的!比如要加Sleep
      

  3.   

    很少有这样情况的.
    SendMessage 与 PostMessage都具可靠性.当然也有很小机率会失败.对于MFC程式封装的API也是使用这两个函数来实现消息传递.若像你那样描述....MFC程式在老机子上就频繁不工作?
      

  4.   

    几乎从未遇到过这种情况(要么是遇到过我没注意?),至少在我所编写过的程序中,大量使用PostMessage和SendMessage,没有发生过什么让我想不通的奇怪现象。实际上,我写的程序中有很多关键代码都是靠这些消息传递来实现的,如果有问题的话,那这些程序早崩溃了。顺便说一句,我从没有在这两个函数后面用过Sleep。另外,不要说MFC,即使Windows的很多机制也都是用这两个实现的(比如各种控件),照你的说法,岂不是谁都无法保证你什么时候会不会收到消息了?所以,我觉得还是你的代码有别的方面的问题,不要光盯着这两个函数。SendMessage的返回值是对方的消息处理函数所返回的值,如果对方返回零,SendMessage自然也返回0,这并不表示调用失败。至于PostMessage,如果返回0的话,那你GetLastError看看究竟什么原因失败。
      

  5.   

    确实在PostMessage和SendMessage后面不需要延时处理,两个函数的不同非常明确,SendMessage等待消息处理完成才返回,PostMessage直接返回.在多线程程序中,建议做好共享对象的互斥访问,感觉会不会是这方面的问题.
      

  6.   

    messagebox还有类似于windows消息忙等情况似乎都能阻塞message的  注意点
      

  7.   

    SendMessage()
    The return value specifies the result of the message processing; it depends on the message sent.
      

  8.   

    先感谢各位大大。也许这个问题我没说清楚。我的程序是这样的:先调用CreateProcess在后台打开画图(MSPAINT.EXE),然后循环以下步骤,处理一批图像文件:
    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找到并且检验过的。
      

  9.   

    试验下 直接获得CEdit的句柄,然后用setwindowtext函数,设置编辑框的内容
      

  10.   

    PostMessage 和 SendMessage经常被使用,没遇到过搂主的问题
    怀疑是参数的问题,比如 如果传递的是用户自定义消息,而消息ID定义小于 WM_USER
      

  11.   

    大家的热心回答让我很感动,再次谢谢。不过还请各位大大先看清帖子再回答。毕竟这个问题偶已经研究了三个多月,再菜也可以说颇有心得了。TO pornographer & lvxinjian_cn:
    就是这种情况,所以要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官方的帮助已经反复看了数百遍,麻烦大大不要再复制粘贴,以免浪费您的宝贵时间。
      

  12.   

    很简单,除非有特殊的需要,统统用PostMessage。
    至于延时的问题,灵敏度和可靠性本来就是一对矛盾,在你不知道mspaint的源码情况下。就算知道也没多大用。
    比如,一个高配置的机器600ms一般就够用了,但当他开着3个BT,2个高清电影,还开着杀毒软件时,6000毫秒也不一定够用。
      

  13.   


    PostMessage(hCtrlHandle,WM_CHAR,Wparam(cStr[i]),1);
    换成这样行不?
    SendMessage (hCtrlHandle, WM_CHAR, "x", 0);然后你可以单独使用
    SendMessage(hCtrlHandle,WM_SETTEXT,0,sStr);获取那个程式的其它控件的文本咯.
    如果不成功再使用同样的方法获取另外一个程式的控件文本....这样排除下看看是什么问题.
      

  14.   

    ColdMooon说得好,我是钻牛角了。结了吧
      

  15.   

    你设计的这个程序实现了么,最近在处理相册图片时,也想到了该功能,如果没有发现人实现的话,打算自己编码实现并发出来跟大家共享.
    如果你的实现了,不知道可否拿来与大家分享?谢谢.
    [email protected]
      

  16.   

    TO: MM22GG
    不好意思,很久没上CSDN。我在发此贴之前就分别用VC和DELPHI实现了这个程序的基本功能,能批量转换格式、缩小JPEG文件大小、放缩和旋转图片,没继续完善了。不知你动手做了没有,我的程序叫JPEGSliming,发到你邮箱去了,试用后请反馈意见,谢谢