【问题标题】:user32.dll FindWindowEx, finding elements by classname on remote WPF windowuser32.dll FindWindowEx,在远程 WPF 窗口中按类名查找元素
【发布时间】:2010-12-15 17:54:36
【问题描述】:

我有一个从命令行应用程序启动的 WPF 应用程序。

我正在尝试做一些简单的自动化操作(获取/设置文本、单击一些按钮等)。我似乎在 WPF 中找不到任何子窗口。

我有 WPF 和 UIA 框架、WinForms 和 WinAPI 的工作模型,但似乎无法让 WinAPI 和 WPF 很好地发挥作用。

我使用过 UISpy、WinSpy++、Winspector、UIA 验证应用程序来查看控件等,但它们似乎与 WinForms 携带的 WPF 信息不同。

例如,在 WinForms 应用程序中,当我通过间谍工具查看时,我看到一个 ClassName 为“WindowsForms10.EDIT.app.0.33c0d9d”的文本框。 UIA 自动化验证应用程序是唯一确认元素存在并报告“TextBox”的应用程序。

那么,我的问题是如何找到要传递的正确类名,或者是否有更简单的方法来查找子元素?

// does not work in wpf
IntPtr child = NativeMethods.FindWindowEx(parent, prevElement, "TextBox", null);

// works in winforms
IntPtr child = NativeMethods.FindWindowEx(parent, prevElement, "WindowsForms10.EDIT.app.0.33c0d9d", null);

这是我正在使用的 user32.dll 导入:

public class NativeMethods
{
    public const int WM_SETTEXT = 0x000C;
    public const int WM_GETTEXT = 0x000D; 
    public const uint CB_SHOWDROPDOWN = 0x014F;
    public const uint CB_SETCURSEL = 0x014E;
    public const int BN_CLICKED = 245;
    public const uint WM_SYSCOMMAND = 0x0112;
    public const int SC_CLOSE = 0xF060;

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);

    [DllImport("user32.dll", SetLastError = false)]
    public static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    public static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, string lParam);

    [DllImport("user32.dll")]
    public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
    public static extern int SendMessage(int hWnd, int Msg, int wParam, StringBuilder lParam); 


}

【问题讨论】:

    标签: wpf winapi ui-automation findwindow


    【解决方案1】:

    如果您想自动化 WPF,您必须使用 UI 自动化,而不是“过去的旧事物”Windows API :-)。

    这里有很好的关于 UI 自动化的介绍:Bugslayer: GUI Control to Major Tom

    还有一个有趣的开源项目“White”,它利用了 UI 自动化:White on codeplex。如果您想深入研究,那里有一些样本。

    【讨论】:

    • 我更喜欢 UI 自动化路线。我在 WPF 和 UI 自动化以及 WinForms 和 WinAPI 中有这个工作。此练习的一部分是确定是否可以完成此操作(带有 WinAPI 的 WPF)。从下面的 cmets 看来,对于 WinForms 和以前的应用程序,WinAPI 是一个选项,WPF 和其他应用程序都使用 UI 自动化。谢谢!
    • 嗯,UI 自动化也适用于常规 Windows 和 Winforms,因为它可以依赖旧版 MSAA(可访问性)SDK,但是,我的经验表明,对所有平台的支持并不完全一致。但是,是的,UI 自动化确实是 WPF 的必经之路,此外,如果您拥有服务器端代码,则可以为自己的控件和 UIElements 配备自动化对等点,以方便外部客户端处理。
    猜你喜欢
    • 1970-01-01
    • 2015-02-07
    • 2014-02-15
    • 2021-03-05
    • 2023-01-03
    • 2015-07-12
    • 2020-02-20
    相关资源
    最近更新 更多