开发者

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

开发者 https://www.devze.com 2023-01-30 13:50 出处:网络
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

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


}


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号