C#实现操作Windows窗口句柄:常用窗口句柄相关API、Winform中句柄属性和Process的MainWindowHandle问题【窗口句柄总结之三】

简介: 本篇主要介绍一些与窗口句柄相关的一些API,比如设置窗口状态、当前激活的窗口、窗口客户区的大小、鼠标位置、禁用控件等,以及介绍Winform中的句柄属性,便于直接获取控件或窗体句柄,以及不推荐...

本篇主要介绍一些与窗口句柄相关的一些API,比如设置窗口状态、当前激活的窗口、窗口客户区的大小、鼠标位置、禁用控件等,以及介绍Winform中的句柄属性,便于直接获取控件或窗体句柄,以及不推荐使用C#自带的ProcessMainWindowHandle获取句柄的原因...

HWND窗口句柄其他的一些API

ShowWindow操作窗口状态(最大化、最小化、正常大小、关闭窗口)

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool ShowWindow(IntPtr hwnd, int nCmdShow);
AI 代码解读

nCmdShow参数表示窗体状态,其常见的取值含义为:

  • 0 —— SW_HIDE 隐藏窗口,并激活其他窗口
  • 1 —— SW_SHOWNORMAL/SW_NORMAL 激活并正常大小显示窗口
  • 2 —— SW_SHOWMINIMIZED 最小化窗口
  • 3 —— SW_SHOWMAXIMIZED/SW_MAXIMIZE 最大化窗口
  • 4 —— SW_SHOWNOACTIVATE 显示但不激活

更多的其它取值请查看官方文档中的介绍。

获取当前激活的正在工作的窗口句柄(获取当前活动窗口句柄)

返回值有可能为null

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetForegroundWindow();
AI 代码解读

判断窗口状态

/// <summary>
/// 当前窗口是否最小化
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsIconic(IntPtr hWnd);
/// <summary>
/// 当前窗口是否最大化
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern bool IsZoomed(IntPtr hWnd);
/// <summary>
/// 判断窗口是否可见
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32")]
public static extern bool IsWindowVisible(IntPtr hWnd);
AI 代码解读

设置窗口标题Title

[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int SetWindowText(IntPtr hWnd, string title);
AI 代码解读

获取窗口客户区大小

[DllImport("user32.dll")]
private static extern bool GetClientRect(IntPtr hwnd, out LPRECT lpRect);
/// <summary>
/// 获取窗口客户区大小
/// </summary>
/// <param name="hwnd"></param>
/// <returns></returns>
public static Rectangle GetClientRect(IntPtr hwnd)
{
    LPRECT rect = default;
    GetClientRect(hwnd, out rect);
    return new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
}
AI 代码解读

获取鼠标坐标

/// <summary>
/// 获取鼠标坐标
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "GetCursorPos")]
public static extern bool GetCursorPos(out Point pt);
AI 代码解读

获取指定坐标位置的窗体

/// <summary>
/// 获取指定位置所在的窗口句柄
/// </summary>
/// <param name="pt"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "WindowFromPoint")]
public static extern IntPtr WindowFromPoint(Point pt);
AI 代码解读

获取鼠标指向的窗体

/// <summary>
/// 获取鼠标位置的窗体
/// </summary>
/// <returns></returns>
public static IntPtr WindowFromCursor()
{
    if (GetCursorPos(out Point pt))
    {
        return WindowFromPoint(pt);
    }
    return IntPtr.Zero;
}
AI 代码解读

移动或调整窗体大小

/// <summary>
/// 移动窗体、调整窗体大小
/// </summary>
/// <param name="hWnd"></param>
/// <param name="X">新位置</param>
/// <param name="Y">新位置</param>
/// <param name="nWidth">新大小</param>
/// <param name="nHeight">新大小</param>
/// <param name="bRepaint">是否重新渲染客户区,推荐始终为true</param>
/// <returns></returns>
[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint=true);
AI 代码解读

使变灰的禁用控件可用

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
AI 代码解读

Winform中使用窗口句柄

Handle属性

窗体或控件的Handle属性,可以直接获取对应的窗口句柄。

var frmHwnd = this.Handle;

var btnHwnd = button1.Handle;
AI 代码解读

获取某控件在Windows中的类名

Win 32 API 中窗口句柄的操作,很多有窗口或控件句柄的类名 ClassName这一项,比如 GetClassName API用于获取句柄的类名。

窗口(控件)句柄的类名是Windows系统中的类名,并不是winform/WPF内部C#的控件或元素类名,这一点要注意。

下面以一个Button按钮为例,通过属性button1.Handle句柄,获取其对应的类名GetClassName

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

private void button1_Click(object sender, EventArgs e)
{
    int nret;
    var className = new StringBuilder(255);
    nret = GetClassName(button1.Handle, className, className.Capacity);
    if (nret != 0)
        MessageBox.Show("ClassName is " + className.ToString());
    else
        MessageBox.Show("Error getting window class name");
}
AI 代码解读

获取Winform中Button控件的C#类名对应的window class name(GetClassName):WindowsForms10.BUTTON.app.0.xxx

通过Process进程类获取窗口句柄及相关信息【不推荐】

进程的MainWindowHandleMainWindowTitle

进程的MainWindowHandle属性可以直接获取主窗口句柄;MainWindowTitle属性为窗口的标题。

如下,根据窗口标题模糊查找窗口句柄。

/// <summary>
/// 根据窗口标题查找窗口句柄【不推荐】
/// </summary>
/// <param name="puzze_title">窗口标题,支持模糊查询可指定标题的一部分;为null则返回所有句柄</param>
/// <returns></returns>
public List<IntPtr> FindHwndsByTitle(string puzze_title=null)
{
    //按照窗口标题来寻找窗口句柄
    Process[] ps = Process.GetProcesses();
    var intptrs = new List<IntPtr>();
    foreach (Process p in ps)
    {
        if (puzze_title != null && !p.MainWindowTitle.Contains(puzze_title))
        {
            continue;
        }
        intptrs.Add(p.MainWindowHandle);
    }
    return intptrs;
}
AI 代码解读

MainWindow的问题

Process.MainWindowHandle属性是合成的(synthetic),Windows中并没有main window相关的正式概念;

一个程序可以创建多个可见的顶层窗口,对于Windows而言,它们都是相同的。

因此,推荐使用EnumWindows获取(顶层)窗口,即之前介绍到的FindAllWindows方法。

参考

相关文章
深入研究:1688商品跨境属性API接口详解
本文介绍了如何通过 1688 商品跨境属性 API 获取商品的跨境相关数据,助力企业开展电商业务。文章分为三部分:引言阐述了接口的重要性及应用场景;接口概述详细说明了调用步骤,包括参数准备、签名生成、请求发送和响应处理;Python 请求示例提供了一个完整的代码实现,帮助开发者快速上手。示例代码涵盖了请求参数配置、签名生成逻辑以及使用 requests 库发送请求的过程,为实际应用提供了参考。
57 13
Windows用户必备:Postman v11详细安装指南与API测试入门教程(附官网下载
Postman是全球领先的API开发与测试工具,支持REST、SOAP、GraphQL等协议调试。2025年最新版v11新增AI智能生成测试用例、多环境变量同步等功能,适用于前后端分离开发、自动化测试、接口文档自动生成及团队协作共享API资源。本文详细介绍Postman的软件定位、核心功能、安装步骤、首次配置、基础使用及常见问题解答,帮助用户快速上手并高效利用该工具进行API开发与测试。
1688 跨境属性 API 接口(1688API 系列)
1688跨境属性API助力跨境电商发展,提供商品目标市场适配、跨境物流、国际认证及语言文化属性等数据,支持HTTP GET/POST请求。开发者可通过商品ID、目标市场代码和语言参数精准获取信息,提升业务效率与精准度。示例代码展示了如何使用Python进行GET请求,获取商品跨境属性,确保数据准确可靠。
开源GTKSystem.Windows.Forms框架让C# Winform支持跨平台运行
开源GTKSystem.Windows.Forms框架让C# Winform支持跨平台运行
102 12
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
184 12
基于C#使用winform技术的游戏平台的实现【C#课程设计】
本文介绍了基于C#使用WinForms技术开发的游戏平台项目,包括项目结构、运行截图、实现功能、部分代码说明、数据库设计和完整代码资源。项目涵盖了登录注册、个人信息修改、游戏商城列表查看、游戏管理、用户信息管理、数据分析等功能。代码示例包括ListView和ImageList的使用、图片上传、图表插件使用和SQL工具类封装,以及高德地图天气API的调用。
基于C#使用winform技术的游戏平台的实现【C#课程设计】
Windows Forms应用程序中集成一个ASP.NET API服务
Windows Forms应用程序中集成一个ASP.NET API服务
144 9
|
8月前
|
C#一分钟浅谈:属性与索引器的定义
本文深入浅出地介绍了C#编程中的属性和索引器。属性让字段更安全,通过访问器方法在读写时执行额外操作,如验证数据有效性;索引器则赋予类数组般的访问方式,支持基于索引的数据访问模式。文章通过示例代码展示了如何定义及使用这两种特性,并提供了常见问题及其解决方案,帮助读者写出更健壮、易维护的代码。希望读者能从中学习到如何有效利用属性和索引器增强C#类的功能性。
159 13
C# 使用 WinForm MDI 模式管理多个子窗体程序的详细步骤
WinForm MDI 模式就像是有超能力一般,让多个子窗体井然有序地排列在一个主窗体之下,既美观又实用。不过,也要小心管理好子窗体们的生命周期哦,否则一不小心就会出现一些意想不到的小bug
565 0
|
7月前
|
【C#】在winform中如何实现嵌入第三方软件窗体
【C#】在winform中如何实现嵌入第三方软件窗体
344 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等