我挂入了一个WH_CALLWNDPROC钩子,并在钩子函数中截取WM_CLOSE消息时使用了SendMessage(hWndBtn, BM_CLICK,0,0),其中这个按钮是其他进程中的按钮。
但是这个按钮的事件并没有执行,可我用spy++查到bm_click事件的确发送出去了,而且也被接收了。
奇怪的是我在SendMessage后随便加一句MessageBox函数,OnClick事件就被执行了。可是我不需要这个MessageBox,开始我以为是执行时序问题,就sleep了一下,结果不是这原因,有人知道这个问题怎么解决吗?谢谢!

解决方案 »

  1.   

    用PostMessage可以解决这个问题
      

  2.   

    原因是:SendMessage要等待对方响应之后才返回,SendMessage发出的消息需要经过自己的Hook函数,而Hook函数又是同步执行的,在没有返回之前不会被再次执行,所以死锁了。可以用PostMessage。
      

  3.   

    to 2F: PostMessage同样不行
    to 3F: WH_CALLWNDPROC钩子的确截取的是通过SendMessage发出的消息,但是这里应该不存在死锁的问题。
    例如我可以在同一Hook函数中截取到自己发送的BM_CLICK消息,并且就是紧跟着SendMessage(hWnd, BM_CLICK,0,0)之后立马接收到的,完了以后才接着运行SendMessage后面的语句,return后窗口关闭。这样看来,所有语句都被执行了,否则窗口也不会关闭。再说spy++中都能看到BM_CLICK消息被发送到指定的按钮,按钮也接收到了该消息,但是按钮的单击事件却没有被执行。我奇怪的就是为什么后面加一句MessageBox就可以了,无论是SendMessage还是postmessage。也许是我的问题没有描述清楚。我想监视其他进程中的一个窗口,该窗口中有一个按钮,按钮拥有单击事件。窗口和按钮的句柄都可以获得,要在该窗口关闭之前,运行按钮的单击事件,所以就SendMessage(BM_CLICK)。我猜测会不会是因为窗口的关闭先于按钮单击事件完成,这样按钮销毁了,先前获得的句柄也就无效了,SendMessage也就没用了。如果是这样的话,如何解决。
      

  4.   

    你截取的WM_CLOSE消息的窗口和hWndBtn是不是同一线程或者同一进程中的窗口?
    可以把MessageBox改成PeekMessage函数。
      

  5.   

    我猜测会不会是因为窗口的关闭先于按钮单击事件完成,这样按钮销毁了,先前获得的句柄也就无效了,SendMessage也就没用了。如果是这样的话,如何解决。
    对于你这个猜测你可以使用进程同步来查看是否是这样的(就是建立一个互斥对象,当目标窗口发出WM_CLOSE的时候,加锁,禁止它撤消,等你另外一个进程发送完消息后,解锁它,让他执行.)
      

  6.   

    cnzdgs正解,因为WM_CLOSE时目标窗口已经没有了自己的消息循环,之所以使用MessageBox可以是因为它有自己的消息循环。
    所以需要自己建立一个消息循环,并设置适当延时,等待按钮单击事件完成。