检查 hWnd 是否是一个按钮

check if hWnd is a button

我想检查 hWnd 是否是一个按钮。

此代码用于获取 hWnd:

public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);


public static List<IntPtr> GetChildWindows(IntPtr parent)
{
    List<IntPtr> result = new List<IntPtr>();
    GCHandle listHandle = GCHandle.Alloc(result);
    try
    {
        EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
        EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
    }
    finally
    {
        if (listHandle.IsAllocated)
            listHandle.Free();
    }
    return result;
}

现在我必须找出列表中的哪个hWnd 是一个按钮。 谢谢

Windows 按钮有 window class 按钮。您可以使用 GetClassName 来判断一个按钮是否是一个按钮。

请注意,如今许多应用程序不使用 windows 控件,因此可能会有一个不使用 BUTTON class 的按钮。一些应用程序(例如网络浏览器或 WPF 应用程序)甚至完全 "owner drawed" 并且根本不使用任何 window 控件(除了 "container" window)。

从前有一个非常有用的工具,Spy++,可以用来检查 windows。理解 UI 程序的构建方式非常有用。嗯...仍然存在于 Visual Studio: 在我的机器上 (Visual Studio 2013): C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\spyxx.exe

您可以使用函数"GetClassName"找出hwnd的win32-class。对于标准的 win32 按钮,它总是 'Button'。你可以这样使用它:

public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName,int nMaxCount);

[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);

public static List<IntPtr> GetChildButtons(IntPtr parent)
{
    List<IntPtr> result = new List<IntPtr>();
    GCHandle listHandle = GCHandle.Alloc(result);
    try
    {
        EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
        EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
    }
    finally
    {
        if (listHandle.IsAllocated)
            listHandle.Free();
    }
    return result
        .Where(x => {
            StringBuilder buffer = new StringBuilder(128);
            GetClassName(x, buffer, buffer.Capacity);
            return buffer.ToString() == "Button";
        })
        .ToList();
}
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName,int nMaxCount);

将 class 名称与 "Button"

进行比较