如何通过类名子串匹配获取指定子窗口的句柄?
按类名前缀匹配查找子窗口句柄
要实现按类名前缀Afx:ControlBar:匹配子窗口,核心逻辑是遍历父窗口的所有子窗口,逐个获取类名并判断前缀,具体实现需要结合Windows API和C#的字符串判断:
步骤1:导入所需Windows API
需要用到两个API:FindWindowEx用于遍历子窗口,GetClassName用于获取窗口类名:
using System; using System.Runtime.InteropServices; using System.Text; public static class Win32Api { [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); }
步骤2:实现前缀匹配的查找方法
编写一个封装方法,遍历所有子窗口并筛选符合前缀的窗口:
public static IntPtr GetChildWindowByClassPrefix(IntPtr parentHandle, string classPrefix) { IntPtr childHandle = IntPtr.Zero; do { // 遍历下一个子窗口 childHandle = Win32Api.FindWindowEx(parentHandle, childHandle, null, null); if (childHandle == IntPtr.Zero) break; // 获取当前窗口的类名 StringBuilder classNameBuilder = new StringBuilder(256); Win32Api.GetClassName(childHandle, classNameBuilder, classNameBuilder.Capacity); string className = classNameBuilder.ToString(); // 判断类名是否以指定前缀开头 if (className.StartsWith(classPrefix, StringComparison.Ordinal)) { return childHandle; } } while (childHandle != IntPtr.Zero); // 未找到匹配的窗口 return IntPtr.Zero; }
步骤3:调用方法获取目标句柄
直接传入父窗口句柄和固定前缀即可:
// 替换为你的父窗口句柄 IntPtr _parentWindow = ...; IntPtr controlBar = GetChildWindowByClassPrefix(_parentWindow, "Afx:ControlBar:");
关键细节说明
GetClassName的缓冲区长度设为256是常规操作,足够容纳绝大多数窗口类名;如果遇到超长类名,可以适当增大缓冲区。StringComparison.Ordinal确保按字节精确匹配,若需要忽略大小写,可改为StringComparison.OrdinalIgnoreCase。- 遍历会在找到第一个匹配的窗口后立即返回,若需要获取所有匹配的子窗口,可改为返回
List<IntPtr>并持续收集结果。
内容的提问来源于stack exchange,提问作者emilaz
相关产品推荐
相关产品推荐

