2009-08-03 88 views
16

我尝试使用下面的代码按我的其他应用程序中的按钮,一个按钮:编程按下另一个应用程序(C,Windows)中

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:当赏金完成的问题的答案自动选择。问题仍然没有答案。

+1

这是哪个版本的Windows? – billmcc 2009-09-16 18:17:48

+3

可能不是相关的,但我建议你运行你的程序作为管理员或运行在管理模式下的Visual Studio,并尝试如果工程..这也是我在PostMessage文档中看到: Microsoft Windows Vista和更高版本。当一个消息被UIPI阻塞时,最后一个错误(使用GetLastError检索)被设置为5(拒绝访问)。 – FatDaemon 2009-09-16 18:36:30

+0

这是在Vista还是7?它在XP中工作吗? (下载一个图像以从Microsoft运行在Virtual PC上并进行测试。)您是否尝试过使用sendkeys? – svinto 2009-09-17 10:36:13

回答

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

更新:我认为这应该工作,

SendMessage(ButtonHandle, BM_CLICK, 0, 0); 
+0

1)是。我确定。我使用Spy ++来获取这些信息。 2)我试图将消息发送到按钮的句柄,但没有发生任何事情。 – wonderer 2009-08-03 20:01:02

+0

你在你打电话的代码中有句柄吗? – Tim 2009-08-03 20:22:35

+0

确实如此。 我得到了窗口的句柄,按钮,甚至得到按钮类 – wonderer 2009-08-03 21:22:57

0

可以使用的SendKeys(如TR3说)发送鼠标点击,这是与使用SendMessage不同。它也不那么直接,更加黑客,但对自动化(在VBS中)很有用。

而且,只是一种猜测,但问题可能是你的邮件处理由不调用基类成员某处破裂。例如:

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

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

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

或定义你的应用程序窗口内的定制WM处理保存请求。 WM_CUSTOMWM_USER(不能记住哪)标记用户定义的窗口消息的开始。

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

当我必须做这类事情我使用的SendKeys。这是VB-ISH和C#提供了一个很好的接口使用,但对于C/C++,你必须做< this way>。与它的好处是你可以编写脚本并运行它们,而不是在你的代码中硬编码。

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

} 



} 

注: 获得肯定,从窗口文本,按钮文本(检查是否在年底有空间窗口标题)

0

非-C的方法:使用Java语言和java.awt.Robot中的类来移动鼠标进行实时点击(我想有一些在Windows世界也是这样)。 问题:你必须知道你的按钮:d

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

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

这不应该发生的,除非拥有该目标窗口的进程正在运行“asAdministrator”或者是一种服务。在Windows 6及更高版本的交互式桌面上,它的服务非常难以创建窗口。

如果他们甚至远程应用于这种情况,您可以阅读一些关于Integrity Levels Here的文章。 Internet Explorer是唯一一个通过有意降低其自身完整性等级来“选择”完整性安全模型的其他应用程序,以便更有效地对沙盒进行自我评估。

1

微软正在推动Active Accessibility (MSAA)的UI自动化, (现已更名为多次多年来) 看到

对不起,我没有任何简单的代码让你开始。由于“SendMessage()”似乎没有为你工作,我不知道另一种选择,除了“UI自动化”

我假设你已经与Spy ++(与MsDev一起安装)检查你的消息是被发送到正确的按钮等 - 并且该按钮是一个标准的窗口按钮。我的第一个瞬间会说使用“SendMessage()”或“PostMessage()”,但给出关于“SendMessage()”的答案的数目,并且它不适合你。我期望有人正在...

相关问题