【问题标题】:SendMessage to click on Non-Client itemsSendMessage 点击非客户端项目
【发布时间】:2010-10-22 04:39:56
【问题描述】:

我无法让 SendMessage 激活另一个程序上的菜单。当用户单击菜单时通过 Spy++ 查看时,会发生以下情况:

000A0628 P WM_NCLBUTTONDOWN nHittest:HTMENU xPos:1706 yPos:395 [wParam:00000005 lParam:018B06AA 时间:27:23:56.156 点:(1706, 395)] 000A0628 S WM_SYSCOMMAND uCmdType:SC_MOUSEMENU xPos:1706 yPos:395 [wParam:0000F095 lParam:018B06AA] 000A0628 S WM_ENTERMENULOOP fIsTrackPopupMenu:False [wParam:00000000 lParam:00000000] 000A0628 R WM_ENTERMENULOOP lResult:00000000 000A0628 S WM_SETCURSOR hwnd:000A0628 nHittest:HTCAPTION wMouseMsg:0000 [wParam:000A0628 lParam:00000002] 000A0628 R WM_SETCURSOR fHaltProcessing:False [lResult:00000000] 000A0628 S WM_INITMENU hmenuInit:00200355 [wParam:00200355 lParam:00000000] 000C0672 S EM_GETSEL lpdwStart:0010EFA0 lpdwEnd:0010EFA4 [wParam:0010EFA0 lParam:0010EFA4] 000C0672 R EM_GETSEL wStart:26 wEnd:26 lpdwStart:0010EFA0 (684) lpdwEnd:0010EFA4 (276) [lResult:001A001A] 000C0672 S WM_GETTEXTLENGTH wParam:00000000 lParam:00000000 000C0672 R WM_GETTEXTLENGTH cch:26 [lResult:0000001A] 000C0672 S EM_CANUNDO wParam:00000000 lParam:00000000 000C0672 R EM_CANUNDO fCanUndo:True [lResult:00000001] 000A0628 R WM_INITMENU lResult:00000000 000A0628 S WM_MENUSELECT uItem:0 fuFlags:MF_POPUP | MF_HILITE | MF_MOUSESELECT hmenu:00200355 [wParam:80900000 lParam:00200355] 000A0628 R WM_MENUSELECT lResult:00000000 000A0628 S WM_INITMENUPOPUP hmenuPopup:00150595 uPos:0 fSystemMenu:False [wParam:00150595 lParam:00000000] 000A0628 R WM_INITMENUPOPUP lResult:00000000

而当我尝试使用带有 WM_NCLBUTTONDOWN 的 SendMessage 进行相同操作时,会发生以下情况:

000A0628 P WM_NCLBUTTONDOWN nHittest:HTMENU xPos:1700 yPos:400 [wParam:00000005 lParam:019006A4 时间:27:25:02.156 点:(1700, 400)] 000A0628 S WM_SYSCOMMAND uCmdType:SC_MOUSEMENU xPos:1700 yPos:400 [wParam:0000F095 lParam:019006A4] 000A0628 S WM_ENTERMENULOOP fIsTrackPopupMenu:False [wParam:00000000 lParam:00000000] 000A0628 R WM_ENTERMENULOOP lResult:00000000 000A0628 S WM_EXITMENULOOP fIsTrackPopupMenu:False [wParam:00000000 lParam:00000000] 000A0628 R WM_EXITMENULOOP lResult:00000000 000A0628 S WM_MENUSELECT uItem:0 fuFlags:FFFF(菜单已关闭) hmenu:00000000 [wParam:FFFF0000 lParam:00000000] 000A0628 R WM_MENUSELECT lResult:00000000 000A0628 S WM_EXITMENULOOP fIsTrackPopupMenu:False [wParam:00000000 lParam:00000000] 000A0628 R WM_EXITMENULOOP lResult:00000000 000A0628 R WM_SYSCOMMAND lResult:00000000

有谁知道如何让它正常工作?

干杯

罗斯

【问题讨论】:

  • 在考虑这个问题时,我想知道是否有替代解决方案。您能告诉我们您想要实现的目标吗(例如,您为什么要尝试在另一个程序中激活菜单)?
  • 我正在尝试制作一个“猴子”测试仪。作为其中的一部分,我需要猴子足够聪明,不要点击它识别为退出/退出按钮/菜单选项的任何东西,这很好,只是它点击得如此之快以至于它可以在对话框实际弹出之前点击某处并且对话框仍将接收输入,并且如果对话框上有一个退出按钮,则在鼠标碰巧所在的位置下它会触发目标程序退出。这不是预期的效果,因此需要一些方法来检测何时出现对话框。 SendMessage 阻止并提供此功能。

标签: winapi sendmessage user32


【解决方案1】:

您不应该使用 SendMessage 来模拟鼠标点击和按键操作。请改用SendInput

【讨论】:

  • 我知道我可以使用 SendInput 但是 SendInput 在消息被处理之前不会阻塞,这是我在编程时需要使用的 SendMessage 的属性之一。
【解决方案2】:

我猜菜单循环测试鼠标按钮的状态。但是,您还没有模拟按下鼠标按钮,您所做的只是发送一条消息说按钮已按下。

如果您需要同步行为,我建议您使用windows hook 并让您的线程阻塞到合适的时间。 (换句话说,您可以使用异步方法,然后将其包装,使其阻塞并充当同步调用。这是额外的工作,但如果您坚持从本质上异步的事物中进行同步行为,那么这是您最好的解决方案。)

【讨论】:

  • 它必须同步的主要原因是任何弹出菜单/模式对话框都有机会出现并被检测到。我不确定是否可以使用 Windows 挂钩来完成此操作,因为该程序不会事先知道它在哪里单击。有没有办法让菜单循环认为按钮真的关闭了,并且仍然使用 SendMessage 来完成它?
  • 不确定如何模拟按钮向下,但如果可以,你怎么知道何时模拟按钮向上?
【解决方案3】:

您可以完美地使用 SendMessage(),尤其是用于菜单(有关代码示例,请参阅 MSDN 和 Google Groups)
(这里和钩子无关)

【讨论】:

  • 原发帖者已经尝试过SendMessage。它在这里不起作用,因为应用程序正在查看鼠标的状态,但鼠标按钮并没有真正按下。 SendMessage 只完成了一半的工作。
猜你喜欢
  • 2017-05-14
  • 2011-11-25
  • 1970-01-01
  • 2010-10-21
  • 2018-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多