user32.dll FindWindowEx, finding elements by classname on remote WPF window

吃可爱长大的小学妹 提交于 2019-12-12 10:25:39

问题


I have a WPF application that is being started from a command-line application.

I am trying to do some simple automation (get/set text, click some buttons, etc). I cannot seem to find any of the child windows in WPF.

I have working models with WPF and UIA Framework, WinForms and WinAPI, but cannot seem to get WinAPI and WPF to play nicely.

I have used UISpy, WinSpy++, Winspector, the UIA Verify app to look at the controls, etc, but they do not seem to carry the same information for WPF as WinForms.

For example, in the WinForms app, I see a textbox with a ClassName of "WindowsForms10.EDIT.app.0.33c0d9d" when I look via the spy tools. The UIA Automation Verify app is the only one to acknowledge the element exists and reports "TextBox".

So, my question is how do I find the correct class name to pass or is there an easier route to find the child elements?

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

and here is the user32.dll imports I am using:

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


}

回答1:


If you want to automate WPF, you must use the UI Automation, not the "old thing of the past" windows API :-).

There is a good introduction on UI automation here: Bugslayer: GUI Control to Major Tom

There is also an interesting open source project named "White" that leverages UI automation: White on codeplex. There are some samples in there if you want to dig in.



来源:https://stackoverflow.com/questions/4453211/user32-dll-findwindowex-finding-elements-by-classname-on-remote-wpf-window

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!