CWin32Api取得并列出并显示其它应用窗口控件信息

一赫技术 2024-08-06 11:00:52

在Windows操作系统中,应用程序可以包含许多控件窗口。了解并调试这些控件对于开发人员和系统管理员来说是非常有价值的。本文将介绍如何使用C#和Windows Forms构建一个工具,可以列出正在运行的带窗口的进程,并显示其窗口控件的详细信息,包括它们的句柄、类名和文本内容。

创建 WinForms 项目

首先,我们需要在Visual Studio中创建一个新的Windows Forms项目。

打开Visual Studio。选择“创建新项目”。选择“Windows 窗体应用(.NET Framework)”,然后点击“下一步”。设置项目名称、位置并选择合适的 .NET 框架版本,最后点击“创建”。设计用户界面

在设计界面上,我们将需要以下控件:

一个 ListBox 控件,用于显示进程列表。将其命名为 btnGetInfo。一个 Button 按钮,用于触发获取控件信息的操作。将其命名为 buttonGetControls,并设置文本为“获取控件信息”。一个 TextBox 控件,用于显示控件的详细信息。将其命名为 txtMsg,并设置 Multiline 属性为 true。用户界面布局

引入 Windows API 以获取窗口信息

我们需要引入一些 Windows API 函数,以便获取窗口的句柄、文本和类名。

P/Invoke 声明

在代码顶部引入以下命名空间:

using System;using System.Diagnostics;using System.Runtime.InteropServices;using System.Text;using System.Windows.Forms;

然后,添加需要的P/Invoke声明:

[DllImport("user32.dll", SetLastError = true)]static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);// Windows API declarations[DllImport("user32.dll", SetLastError = true)]static extern IntPtr GetForegroundWindow();[DllImport("user32.dll", SetLastError = true)]static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);[DllImport("user32.dll", SetLastError = true)][return: MarshalAs(UnmanagedType.Bool)]static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr lParam);[DllImport("user32.dll", SetLastError = true)]static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);[DllImport("user32.dll")]static extern bool IsWindowVisible(IntPtr hWnd);private delegate bool EnumWindowProc(IntPtr hWnd, IntPtr lParam);加载进程并显示控件信息

我们需要编写代码来加载当前正在运行的进程,以及遍历每个窗体控件并获取其详细信息。

主要代码

加载进程列表:

在 MainForm 类中添加以下方法,用于加载带窗口的进程:

private void LoadProcesses(){ lstProcess.Items.Clear(); Process[] processes = Process.GetProcesses(); foreach (Process proc in processes) { if (proc.MainWindowHandle != IntPtr.Zero) { lstProcess.Items.Add(new ListItem(proc.ProcessName, proc.MainWindowHandle)); } } lstProcess.DisplayMember = "Name";}ListItem类public ListItem{ public string Name { get; } public IntPtr WindowHandle { get; } public ListItem(string name, IntPtr windowHandle) { Name = name; WindowHandle = windowHandle; } public override string ToString() { return Name; }}

获取并显示控件信息:

private void btnGetInfo_Click(object sender, EventArgs e){ if (lstProcess.SelectedItem != null) { ListItem selectedItem = (ListItem)lstProcess.SelectedItem; IntPtr hwnd = selectedItem.WindowHandle; txtMsg.Clear(); TraverseControls(hwnd, 0); }}private void TraverseControls(IntPtr hWnd, int indentLevel){ if (IsWindowVisible(hWnd)) { StringBuilder sbText = new StringBuilder(256); StringBuilder sbClass = new StringBuilder(256); GetWindowText(hWnd, sbText, sbText.Capacity); GetClassName(hWnd, sbClass, sbClass.Capacity); string indent = new string(' ', indentLevel * 2); txtMsg.AppendText($"{indent}Handle: {hWnd}, Class: {sbClass}, Text: {sbText}\r\n"); EnumChildWindows(hWnd, (childHWnd, lParam) => { TraverseControls(childHWnd, indentLevel + 1); return true; }, IntPtr.Zero); }}

通过上述步骤,我们构建了一个功能齐全的WinForms应用程序,能够列出正在运行的带窗口的进程,并显示其窗口所有控件的详细信息。

如果您有任何问题或进一步的需求,请随时告诉我!

0 阅读:0

一赫技术

简介:感谢大家的关注