以编程方式按下另一个应用程序上的按钮(C,Windows)

时间:2009-08-03 18:25:48

标签: c windows button click

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

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和更多。 我之所以问这个问题的原因是因为我已经在互联网上用尽了我的搜索。 如果您知道答案请发布代码,请不要建议API,就是这样,告诉我该API如何解决问题。这并不难。 谢谢。

编辑3:当赏金结束时,问题的答案自动被选中。问题仍然没有答案。

12 个答案:

答案 0 :(得分:18)

  1. 您确定“SaveButton”类名是否有效?你拿到了按钮吗? 处理?
  2. 尝试向ButtonHandle窗口发送消息(直接发送到按钮)。
  3. 更新:我相信这应该有效,

    SendMessage(ButtonHandle, BM_CLICK, 0, 0);
    

答案 1 :(得分: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);

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

答案 2 :(得分:2)

答案 3 :(得分: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);
  }

 }



}

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

答案 4 :(得分:2)

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

除非拥有目标窗口的进程正在“asAdministrator”运行或是服务,否则不应该发生这种情况。对于使用Windows 6及更高版本在交互式桌面上创建窗口的服务而言,该死的很难。

如果他们甚至可以远程应用这种情况,你可以阅读Integrity Levels Here。 Internet Explorer是唯一一个“选择”进入完整性安全模型的应用程序,它通过有意降低自身的完整性级别来更有效地沙箱自身。

答案 5 :(得分:1)

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

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

或者在应用程序窗口中定义自定义WM以处理保存请求。 WM_CUSTOMWM_USER(无法记住哪个)标记了用户定义的窗口消息的开始。

答案 6 :(得分:1)

当我必须做这些事情时,我使用SendKeys。它是VB-ish,C#提供了一个很好的界面,但对于C / C ++,你必须这样做< this way>。有趣的是,您可以编写脚本并运行它们,而不是在代码中对其进行硬编码。

答案 7 :(得分:1)

微软现在推动Active Accessibility (MSAA)用于UI自动化, (多年来已经多次重命名)  见

抱歉,我没有任何简单的代码可以帮助您入门。由于“SendMessage()”似乎不适合你,除了“UI自动化”之外,我不知道另一种选择

我假设您已经检查过Spy ++(与MsDev一起安装),您正在将消息发送到正确的按钮等 - 并且该按钮是标准的Windows按钮。我的第一个瞬间会说使用“SendMessage()”或“PostMessage()”但是给出了关于“SendMessage()”的答案数量以及它不适合你的事实。我希望有人继续......

答案 8 :(得分:1)

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

print("\n********************************************************************\n")

if calc_again.upper() == 'Y':
    calculate()
    print("\n********************************************************************\n")
    again()

elif calc_again.upper()  == 'N':
    print("Thank you for using Calculator, Goodbye...") 
    import sys
    sys.exit()
    
else:
    print("Invalid Input. Please try again...")
    print("\n")
    print("\n********************************************************************\n")
    print("\n")
    again()
    print("\n********************************************************************\n")
    calculate()

答案 9 :(得分:0)

您可以使用sendkeys(如tr3所述)发送鼠标点击,这与使用SendMessage不同。它也不那么直接,也不那么黑客,但对自动化很有用(在VBS中)。

另外,只是一个猜测,但问题可能是你的消息处理因为没有调用基类成员而被破坏。例如:

void CMyClass::OnMessageY(CWnd *cwnd)
{
    CBaseClass::OnMessageY(cwnd);
    //... my code
}

答案 10 :(得分: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);
}

答案 11 :(得分:0)

非C方法:使用Java和java.awt.Robot类来移动鼠标来执行实际点击(我想在Windows World中也有这样的东西)。 问题:您必须知道按钮的位置:D