【问题标题】:Click a button programmatically C#以编程方式单击按钮 C#
【发布时间】:2017-06-17 02:40:37
【问题描述】:

我正在寻找一种以编程方式单击按钮的方法(Winform)。我的项目有一个表单(比如 Form2)和按钮(Button2)。当我单击我的按钮时,它应该单击 Button1(在另一个项目中),但两者都在同一个解决方案中。 这是我试图做的:

private void button2(object sender, EventArgs e)
{

    System.IntPtr hwnd;

    System.IntPtr hwndChild = IntPtr.Zero;

    hwnd = FindWindow(null, "form1");

    if (hwnd.Equals(IntPtr.Zero))
    {
     MessageBox.Show("Couldn't find the form");
    }
    else
    {
    hwndChild = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, null, "BUTTON1");

    if(!hwndChild.Equals(IntPtr.Zero))
    SendMessage(hwndChild, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
    }
}

我应该使用反射等其他方法来代替这个吗?

P.S:Button1 是私有的,不能对该函数/项目进行任何更改

【问题讨论】:

  • button2(null,null); 工作吗?
  • 如果它在您的流程中,您应该调用您的业务逻辑,而不是通过您的 UI。如果是另一个进程,请使用 Microsoft UIA
  • @sjohnson - 告诉给你这项工作的人回到设计阶段然后走开
  • "如果按钮在对话框中并且对话框未激活,BM_CLICK消息可能会失败。为确保在这种情况下成功,请在发送之前调用SetActiveWindow函数激活对话框BM_CLICK 消息到按钮。”您是否检查过您是否拥有正确的 ID 以及是否在 Spy++ 中触发了正确的事件?
  • 我会认真阅读设计模式以避免您在这里尝试做的事情。而不是在另一个项目中“单击”button2,您要做的是执行该按钮执行的操作。您应该将 UI 代码与业务逻辑分开。谷歌“MVC 设计模式”或“MVVM 设计模式”。任何一个都适用于您正在尝试做的事情。 Project1 中的控制器操作可以在 Project2 中的控制器上调用 Action 方法,而无需伪造按钮单击

标签: c# winforms reflection buttonclick findwindow


【解决方案1】:

操作:

我正在寻找一种以编程方式单击按钮的方法 (Winform)。

Button1 和 Button2 处于两个不同的进程中。我不应该对包含 button1 的代码进行任何更改。

当然,不需要对目标应用进行任何更改的最简单方法是使用 Windows UI 自动化。 UIA 本质上允许您从 GUI 角度自动化另一个应用程序(而不是说通过 COM/Ole 自动化在幕后),无论您是只想驱动另一个应用程序,例如单击按钮还是执行QA 中的全面自动化测试。

MSDN:

Microsoft UI 自动化是一种辅助功能框架,它使 Windows 应用程序能够提供和使用有关用户界面 (UI) 的编程信息。 more...

...和:

UIA 可用于自动化本机 Windows 应用程序、WPF 应用程序以及 Silverlight 应用程序。 more...

此代码将在标题为“Target Demo”的窗口中单击包含文本“Click Me”的按钮。注意我没有提到任何特定的对象类型;回调或 GUI 技术(适用于本机;WinForms;WPF 和 Web)

//
// This is the handler in the ButtonClicker app, the app that is doing the clicking
//
private void go_Click(object sender, EventArgs e)
{
    // Look for a top-level window/application called "Target Demo"
    var root = AutomationElement.RootElement;
    var condition1 = new PropertyCondition(AutomationElement.NameProperty, "Target Demo");

    var treeWalker = new TreeWalker(condition1);
    AutomationElement element = treeWalker.GetFirstChild(root);
    
    if (element == null)
    {
        // not found
        return;
    }

    // great!  window found
    var window = element;

    // now look for a button with the text "Click Me"
    var buttonElement =window.FindFirst(TreeScope.Children, 
        new PropertyCondition(AutomationElement.NameProperty, "Click Me"));
    if (buttonElement == null)
    {
        // not found
        return;
    }

    // great! now click the button
    var invokePattern = buttonElement.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
    invokePattern?.Invoke();

}

好处

  • 定位应用需要零更改
  • 不用担心寻找窗口句柄
  • 尝试将 BN_CLICK 通知发送到应用程序的消息泵,希望它能正常工作
  • 适用于 c++ 应用程序;赢表格; WPF;网络

【讨论】:

    【解决方案2】:

    您有如下几个选项

    1-button1.PerformClick();

    2-button1_Click(this, EventArgs.Empty);

    3-button1(null, null)

    【讨论】:

    • 如果两个按钮在同一个类中,那么它应该可以工作。
    • 如果这个答案对你有帮助,那么请把它标记为答案..thanx
    • 他说按钮在两个不同的项目中
    • 公开以便访问
    • 外部进程直接调用这些方法不是一个好主意。这就是他们不公开的原因
    猜你喜欢
    • 2017-06-03
    • 2013-10-09
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 1970-01-01
    相关资源
    最近更新 更多