在另一个应用程序

在另一个应用程序

问题描述:

我想哟使用SendMessagePostMessage在另一个应用程序在另一个应用程序

我有一个示例代码通过获取窗口句柄做到这一点按下一个按钮,点击按钮,但它不工作

我还使用“WinDowse”获取所需的信息。这里是代码

private const uint BM_CLICK = 0x00F5; 
private const uint WM_LBUTTONDOWN = 0x0201; 
private const uint WM_LBUTTONUP = 0x0202; 

private void PushOKButton(IntPtr ptrWindow) 
{ 
    WindowHandle = FindWindow(null, "Form1"); 
    if (ptrWindow == IntPtr.Zero) 
     return; 

    IntPtr ptrOKButton = FindWindowEx(ptrWindow, IntPtr.Zero, "Button", "&Yes"); 

    if (ptrOKButton == IntPtr.Zero) 
     return; 

    SendMessage(ptrOKButton, WM_LBUTTONDOWN, 0, 0); 
    SendMessage(ptrOKButton, WM_LBUTTONUP, 0, 0); 
    SendMessage(ptrOKButton, BM_CLICK, 0, 0); 
} 

是否有在C#Compelete Suloution?

您有正确的概念。 自动化总是有一些技巧。

按钮向下/向上靠近原始点击动作,但不完全相同。 你将要考虑

  1. ,你点击COORDS - 某些按钮并不在鼠标的0,0
  2. 位置喜欢边点击 - 按钮的鼠标外,在开始或结束可能会导致它到不行
  3. 时间点击 - 有时一个快速点击将被忽略,添加的说10毫秒

BM_CLICK是做一个按钮,用鼠标点击时要发送一个额外的Win32消息的小的延迟 - 它是如果控件是适合使用的类型,则方法更简单并且更容易一个人。

一些努力是为了防止像使用WM_GetText从外国应用程序的密码编辑的东西,要警惕,你可能也有问题,取决于目标应用程序。

不幸的是,我现在没有C#示例代码。

也许你可以看看AutoIT来节省一些时间。

+0

*“你有正确的总体想法。”* - 嗯,不。这个想法是错误的。消息只是输入处理的可观察部分。如果您只重播那部分内容,那么您会以不一致的状态结束。真正的答案是[UI自动化](https://msdn.microsoft.com/en-us/library/ms747327.aspx)。 – IInspectable 2016-07-13 17:13:09

+0

.Net用户界面自动化框架是有限的,并且会导致各种人为因素 - 例如Adobe Reader提示可访问性模式,如果您甚至将其显示的窗口放在侧面。 由于自定义控件创建未正确覆盖自动化支持的目标应用程序中的错误,我们一直在崩溃许多试图使用UI自动化的Microsoft应用程序。 – 2016-07-14 05:50:55

+0

如果预构建的库支持不足,则UI自动化通过COM对象公开,这些对象很容易从.NET中使用。你的评论表明你回答了一个不同的问题:*“假设UI自动化不适合我们,有什么替代方案?”OP从未声称UI自动化不适合他们,所以应该首先考虑它。如果你需要伪造输入,你确实需要做的正确。发送消息不会(请参阅[重放输入与重新处理它不同](https://blogs.msdn.microsoft.com/oldnewthing/20121206-00/?p=5903))。 – IInspectable 2016-07-14 09:14:13

以下是使用win32 API驱动鼠标的示例 - 实际用于拖放区域的选择,但您可以将按钮上下移动鼠标的方式更改为鼠标。

POINT p; 
BOOL cursorPosGetSuccessful = GetCursorPos(&p); 
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, horA, verA, NULL, 0); 
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, NULL, 0); 
mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, horB, verB, NULL, 0); 
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, NULL, 0); 
if (cursorPosGetSuccessful)// put the mouse back to roughly where it used to be before the scan. 
    mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, p.x, p.y, NULL, 0); 
+0

假设我有这些:鼠标坐标,窗口标题,窗口句柄,窗口类名称,你可以留下一个完整的代码? – sam 2010-06-09 21:11:15

+0

直接从[mouse_event](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646260.aspx):*“该函数已被取代。使用[SendInput](https:// msdn .microsoft.com/en-us/library/windows/desktop/ms646310.aspx)。“*两者都不允许您控制特定的进程;输入总是进入前台进程。正如您在其他答案中所指出的那样(为什么您觉得迫切需要发布两个?):真正的答案是[UI自动化](https://msdn.microsoft.com/en-us/library/ms747327.aspx) 。 – IInspectable 2016-07-13 17:17:16

+0

感谢您的更新。第二篇文章是由于不同的可能答案。 – 2016-07-14 05:48:13