19

我正在尝试使用以下代码在我的其他应用程序上按下按钮:

HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{   
   ButtonHandle = FindWindowEx(wnd, 0, "SaveButton", "&Save");
   SendMessage(wnd, WM_COMMAND, MAKEWORD(GetDlgCtrlID(ButtonHandle), BN_CLICKED ), (LPARAM)ButtonHandle);

}

它不起作用。我尝试将不同的句柄传递给 MAKEWORD 并更改 WPARM 和 LPARAM 但没有。

关于如何单击另一个应用程序窗口上的按钮的任何想法?

代码表示赞赏。谢谢。

编辑:它似乎没有工作权限的原因。我发送了一个 PostMessage(),结果是 GetLastError() = 5 错误(或拒绝访问)。有任何想法吗?

EDIT2我并不是要粗鲁,但请拜托,我已经搜索了所有 API,包括获取和设置按钮的区域,然后向下和向上发送按钮,获取控件 ID,获取类 ID 和更多。我首先在这里问这个问题的原因是因为我已经在互联网上用尽了我的搜索。如果您知道答案PLEASE POST CODE,请不要建议 API 仅此而已,请告诉我该 API 如何解决问题。这并不难。谢谢你。

编辑 3:问题的答案是在赏金完成时自动选择的。这个问题仍然没有答案。

4

12 回答 12

21
  1. 您确定“SaveButton”类名有效吗?你有按钮手柄吗?
  2. 尝试将消息发送到 ButtonHandle 窗口(直接发送到按钮)。

更新:我相信这应该有效,

SendMessage(ButtonHandle, BM_CLICK, 0, 0);
于 2009-08-03T18:51:51.027 回答
3
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);
SendMessage(btnHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(btnHandle, WM_LBUTTONUP, 0, 0);

你必须发送一个按钮点击两次。不知道为什么(也许第一次点击只会激活按钮的窗口),但我使用这段代码很长时间了,它总是对我有用。

于 2009-09-17T11:28:45.570 回答
2

也许这可以帮助: http ://www.cplusplus.com/forum/beginner/8806/

于 2009-08-03T21:42:37.407 回答
2

请参阅以下解决方案,您也可以使用

SendMessage(ButtonHandle, WM_LBUTTONDOWN, 0, 0);
SendMessage(ButtonHandle, WM_LBUTTONUP, 0, 0);

或者

SendMessage(ButtonHandle, BM_CLICK, 0, 0);

HWND buttonHandle = 0;

BOOL CALLBACK GetButtonHandle(HWND handle, LPARAM)
{
 char label[100];
 int size = GetWindowTextA(handle,label,sizeof(label));
 if(strcmp(label,"&Save") == 0)
 {
  buttonHandle = handle;
  return false;
 }
 return true;
}
void main()
{
 HWND windowHandle = FindWindowA(NULL,"Do you want to Save?");
 if(windowHandle != 0)
 {
  BOOL ret = EnumChildWindows(windowHandle,GetButtonHandle,0);

  if(buttonHandle != 0)
  {
   LRESULT res = SendMessage(buttonHandle,BM_CLICK,0,0);
   //SendMessage(buttonHandle,WM_LBUTTONDOWN,0,0); 
   //SendMessage(buttonHandle,WM_LBUTTONUP,0,0);
  }

 }



}

注意:从窗口文本,按钮文本中确定(检查窗口标题末尾是否有空格)

于 2009-09-17T11:16:54.333 回答
2

SendMessage 或 PostMessage 上的 Access Denied 错误毫无意义,除非发送消息的进程运行的完整性级别低于目标进程。

除非拥有目标窗口的进程正在“以管理员身份”运行或者是服务,否则这种情况不应发生。服务很难在 Windows 6 及更高版本的交互式桌面上创建窗口。

如果它们甚至远程适用于这种情况,您可以在此处阅读有关 Integrity Levels的信息。Internet Explorer 是唯一一个“选择”加入完整性安全模型的应用程序,它通过故意降低自身的完整性级别以更有效地进行沙箱化。

于 2009-09-17T12:06:35.060 回答
1

如果您可以抬起包含按钮的窗口,您可以将原始鼠标事件发送到按钮边界内的位置。

有两个函数可以模拟鼠标事件SendInputmouse_event. 我推荐使用mouse_event函数。要提高窗口,您可以使用ShowWindow。我不知道如何获得按钮的句柄,但如果你有它的 hWnd,它很容易使用GetWindowRect函数找到它的绝对位置。尝试使用这些,如果您遇到任何问题,我将很乐意提供帮助。

或者在您的应用程序窗口中定义一个自定义 WM来处理保存请求。 WM_CUSTOMWM_USER(不记得是哪个)标记用户定义的窗口消息的开始。

于 2009-09-16T10:55:58.107 回答
1

当我必须做这些事情时,我会使用 SendKeys。它是 VB 风格的,C# 提供了一个很好的界面来使用,但对于 C/C++,你必须这样做<这种方式>。它的好处是您可以编写脚本并运行它们,而不是在代码中硬编码。

于 2009-09-17T10:21:19.420 回答
1

Microsoft 现在正在推动UI 自动化的Active Accessibility (MSAA),(多年来已多次重命名)请参阅

抱歉,我没有任何简单的代码可以帮助您入门。由于“SendMessage()”似乎对您不起作用,我不知道除了“UI 自动化”之外的其他选项</p>

我假设您已使用 Spy++(与 MsDev 一起安装)检查您的消息正在发送到正确的按钮等 - 并且该按钮是标准的 Windows 按钮。我的第一个瞬间会说使用“SendMessage()”或“PostMessage()”,但考虑到“SendMessage()”的答案数量以及它对你不起作用的事实。我希望有人在继续……</p>

于 2009-09-21T11:43:48.797 回答
1

//将数字4发送到已经打开的calc.exe

HWND windowHandle;

windowHandle = FindWindowA(NULL,"Calculator");

if(windowHandle != 0)
   ret = EnumChildWindows(windowHandle,GetButtonHandle,0);

BOOL CALLBACK GetButtonHandle(HWND handle, LPARAM)
{
char label[100];
int size = GetWindowTextA(handle,label,sizeof(label));

if(strcmp(label,"4") == 0)
{
PostMessage(handle ,WM_LBUTTONDOWN,(WPARAM)0x0001,0);
PostMessage(handle ,WM_LBUTTONUP,(WPARAM)0x0001,0);

PostMessage(handle ,WM_LBUTTONDOWN,(WPARAM)0x0001,0);
PostMessage(handle ,WM_LBUTTONUP,(WPARAM)0x0001,0);

return false;
}
return true;
}
于 2020-08-01T18:25:53.780 回答
0

您可以使用 sendkeys(如 tr3 所说)发送鼠标点击,这与使用 SendMessage 不同。它也不太直接且更 hack-ish,但对于自动化(在 VBS 中)很有用。

此外,这只是一个猜测,但问题可能是您的消息处理在某处因未调用基类成员而被破坏。例子:

void CMyClass::OnMessageY(CWnd *cwnd)
{
    CBaseClass::OnMessageY(cwnd);
    //... my code
}
于 2009-09-15T23:34:17.827 回答
0

如果您确定 ButtonHandle 是有效句柄,您可以使用对 WM_LBUTTONDOWN 和 WM_LBUTTONUP 消息而不是 BN_CLICKED

HWND ButtonHandle;
if( (wnd = FindWindow(0, "Do you want to save?")) )
{   
    SendMessage(ButtonHandle, WM_LBUTTONDOWN, MK_LBUTTON, 0);
    SendMessage(ButtonHandle, WM_LBUTTONUP, MK_LBUTTON, 0);
}
于 2009-09-16T18:12:46.950 回答
0

一种非 C 方法:使用 Java 和 java.awt.Robot 类来移动鼠标执行真正的点击(我猜在 Windows World 中也有这样的东西)。问题:你必须知道你的按钮在哪里:D

于 2009-09-17T11:20:20.890 回答