C# 中的本机窗口层次结构和类名 [英] Native window hierarchy and class names in C#

查看:35
本文介绍了C# 中的本机窗口层次结构和类名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个函数来查找给定窗口层次结构的特定窗口,如下所示:

protected bool MapWindowHierarchy(ATS.Library.Window 窗口){布尔结果 = 假;列表<进程>进程=空;进程 = GetProcesses().ToList();进程.ForEach(过程 =>{if (process.MainWindowHandle == window.Handle){//填充窗口属性.//获取具有填充属性的子窗口.}});返回(结果);}protected bool MapWindowHierarchy (List windows){返回 (windows.All(window => this.MapWindowHierarchy(window)));}公共密封类窗口{公共 IntPtr 句柄 { 获取;放;}公共字符串类{获取;放;}公共矩形边界{得到;放;}公共 Win32Api.User32.ShowWindowCommands WindowState { get;放;}公共字符串标题{获取;放;}公共 int 样式 { 获取;放;}公共列表视窗{得到;放;}public void PopulateFromHandle(IntPtr hWnd){//使用 Win32 API 填充上述属性.}}

这只是粗略的代码,但目标是使用 [Window] 类创建层次结构,并查看使用 [EnumChildWindows] 的实际层次结构是否匹配.这显然工作正常,但我遇到了e,您在调用 RegisterClassEx() 之前填写的那个.然后从中创建窗口,在 CreateWindowEx() winapi 调用中传递类名.该方案旨在使创建相似的窗口变得容易,就像您在 C# 中使用类来创建相似的对象一样.但是仍然可以拥有自己的Text属性.以及他们自己的 Click 事件处理程序.

您可以使用 GetClassName() winapi 函数从句柄中获取窗口类名.

您可以使用 GetWindowText() winapi 函数从句柄中获取文本属性".GetWindowTextLength() 告诉您需要传递给 GetWindowText() 的字符串缓冲区有多大.

I am creating a function to find specific windows given a window hierarchy as follows:

protected bool MapWindowHierarchy (ATS.Library.Window window)
{
    bool result = false;
    List<Process> processes = null;

    processes = GetProcesses().ToList();

    processes.ForEach
    (
        process =>
        {
            if (process.MainWindowHandle == window.Handle)
            {
                // Populate window properties.
                //  Get child windows with filled properties.
            }
        }
    );

    return (result);
}

protected bool MapWindowHierarchy (List<ATS.Library.Window> windows)
{
    return (windows.All(window => this.MapWindowHierarchy(window)));
}

public sealed class Window
{
    public IntPtr Handle { get; set; }
    public string Class { get; set; }
    public Rectangle Bounds { get; set; }
    public Win32Api.User32.ShowWindowCommands WindowState { get; set; }
    public string Caption { get; set; }
    public int Style { get; set; }
    public List<ATS.Library.Window> Windows { get; set; }

    public void PopulateFromHandle(IntPtr hWnd)
    {
        // Populate above properties using Win32 API.
    }
}

This is just rough code but the objective is to create a heirarchy using the [Window] class and see if the actual hierarchy using [EnumChildWindows] matches. This apparently works fine but I came across this SO question, Hans Passant's comment "Every unique window in a desktop session must have a unique Windows class name", I wasn;t sure how to interpret it (see image below for multiple windows with the same class name). Perhaps what he mentions only applies to managed code (WinForms, WPF, etc.).

Furthermore, I am not sure how to retrieve the class names and text of the windows given I have the handle (hWnd) like Spy++ does (see image below). Notice how the text is retrieved in the tree view but not the [Find Window] dialog.

Question:

  • Should I be worried about Han's comment since I am only targeting native apps?
  • How to get the class name given a window's handle?
  • How to get the window text given a window's handle (like in the image)?

解决方案

Not sure why you have to worry. But yes, these "Button" controls you highlighted in your screenshot are not unique windows. They all look the same and behave the exact same way when you click them. The only difference is that their text "property" is different. So they are therefore the exact same window "class". With "property" and "class" in double-quotes since the winapi is a C api and the C language doesn't support classes or properties.

A window class pre-selects a bunch of properties for a window, you can see them back in the WNDCLASSEX structure, the one you fill in before you call RegisterClassEx(). You then create windows from that, you pass the class name in the CreateWindowEx() winapi call. The scheme was designed to make it easy to create windows that are similar, much like you use a class in C# to create objects that are similar. But can still have their own Text property. And their own Click event handler.

You get the window class name from a handle with the GetClassName() winapi function.

You get the text "property" from a handle with the GetWindowText() winapi function. GetWindowTextLength() tells you how large a string buffer you need to pass to GetWindowText().

这篇关于C# 中的本机窗口层次结构和类名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆