以编程方式按其他应用程序(C,Windows)上的button

我试图使用下面的代码来按下我的其他应用程序上的一个button

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,但没有任何结果。

任何想法如何点击另一个应用程序的窗口上的button?

代码表示赞赏。 谢谢。

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

编辑2我不是故意粗鲁,但请请,我已经搜查了所有的API,包括获取和设置button的区域,然后发送button和button,获得控制ID,获得类ID和一个还有更多。 我在这里首先提出这个问题的原因是因为我已经用尽了在互联网上的search。 如果你知道答案PLEASE POST CODE ,不要build议一个API,就是这样,告诉我该API如何解决这个问题。 这并不难。 谢谢。

编辑3:当赏金完成时,问题的答案被自动select。 这个问题仍然没有答案。

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

更新:我相信这应该工作,

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

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

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

看到下面的解决方案,也可以使用

 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); } } } 

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

SendMessage或PostMessage上的拒绝错误是没有意义的,除非发送消息的进程在比目标进程更低的完整性级别运行。

这应该不会发生,除非拥有目标窗口的进程正在运行“asAdministrator”或是服务。 而它的该死的艰巨的服务来创建与Windows 6和交互式桌面上的窗口。

你可以在这里阅读关于完整性等级的内容,如果他们甚至远程适用于这种情况。 Internet Explorer是唯一一个通过有意降低其自身完整性级别来选择完整性安全模型的其他应用程序,以便更有效地自定义沙箱。

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

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

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

当我必须做这些事情时,我使用SendKeys。 这是VB-ISH和C#提供了一个很好的界面来使用,但对于C / C ++,你必须做到这一点 。 有什么好的是,你可以编写脚本并运行它们,而不是硬编码到你的代码中。

微软现在正在推动UI自动化的Active Accessibility(MSAA) ,(多年来它已被重新命名)

  • UI自动化和Microsoft Active Accessibility
  • 使用UI自动化进行自动化测试
  • 用于托管代码的UI自动化客户端

对不起,我没有任何简单的代码让你开始。 由于“SendMessage()”似乎不适合你,我不知道除了“UI自动化”

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

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

此外,只是一个猜测,但问题可能是您的消息处理由于没有调用基类成员而被打破了。 例:

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

如果你确定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); } 

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