Windows.h 库函数的学习

本文详细解读Windows系统中的句柄概念,作为16位无符号整数标识内核对象,通过FindWindow和SendMessage操作窗口。涉及函数如FindWindowW和SendMessage的使用示例,以及如何利用句柄进行窗口操控和消息传递,如设置窗口标题和发送字符消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

句柄:

 

句柄是Windows系统中对象或实例的标识,这些对象包括模块、应用程序实例、窗口、控制、位图、GDI对象、资源、文件等 。

从数据类型上来看,它只是一个16位的无符号整数。应用程序总是通过调用Windows API获得一个句柄,之后其他 Windows函数就可以使用该句柄,以引用和操作相应的内核对象。句柄可以像指针那样置空,那样句柄就没有任何意义,不代表任何内核对象 。

句柄地址(稳定)→记载着对象在内存中的地址→对象在内存中的地址(不稳定)→实际对象

句柄是一种指向指针的指针。在Windows中,句柄是一个系统内部数据结构的引用。

参考链接

1、FindWindow函数

该函数可以通过窗口类名或者窗口标题名来查找特定窗口句柄,返回值是窗口的句柄。

HWND FindWindowW(
  [in, optional] LPCWSTR lpClassName,
  [in, optional] LPCWSTR lpWindowName
);

微软windows.h API文档

lpClassName: "lp"可以当作指针,"ClassName" 为类名。

lpWindowName:前面"lp"一样,"WindowsName"为窗口标题。

LPCWSTR:是一个指向unicode编码字符串的32位指针,wchar型,而不是char型

其相当于WCHAR*,wchar数据类型一般为16或32位,wchar_t所能表示的字符数远超char型。

这里可以用SPY++抓类名/窗口标题。

 

 

 

 抓目标窗口,这里就复制标题来抓句柄。

2、SendMessage函数

这个函数的功能是向句柄对应窗口发送指令

SendMessage function (winuser.h) - Win32 apps | Microsoft Docs

LRESULT SendMessage(
  [in] HWND   hWnd,
  [in] UINT   Msg,
  [in] WPARAM wParam,
  [in] LPARAM lParam
);

HWND 窗口句柄

UINT   消息名称

关于消息的文档看这About Messages and Message Queues

文档里可以查到所有消息类型,常用的像是WM前缀下的窗口消息,剪贴板消息等

WPARAM  消息附带内容

LPARAM   消息附带内容

一个是WORD类型的16位整型变量;另一个是LONG类型的32位整型变量。因此根据匈牙利命名法,16位的变量就被命名为wParam, 32位的变量就被命名为lParam。

消息响应机制

消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)组成。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单选中之后会有WM_COMMAND消息发送,WPARAM的低字中(LOWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。

LPARAM_百度百科

Message.LParam Property (System.Windows.Forms) | Microsoft Docs

UNI 例子1- WM_CLOSE

WM_CLOSE message (Winuser.h) - Win32 apps | Microsoft Docs

LRESULT CALLBACK WindowProc(
    __in HWND hWindow,
    __in UINT uMsg,
    __in WPARAM wParam,
    __in LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CLOSE:
        DestroyWindow(hWindow);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWindow, uMsg, wParam, lParam);
    }

    return 0;
}

By default, the DefWindowProc function calls the DestroyWindow function to destroy the window.

这里说明传入UNI类型数据的值为WM-CLOSE时 会通过DestroyWindow这个函数来摧毁当前窗口,DestroyWindow的如何实现,好奇的话可以点进去看看。

代码

//摧毁窗口测试
void testHWND() {
	HWND window; //定义一个窗口句柄变量,用来储存窗口句柄
	window = FindWindow(NULL, TEXT("文件资源管理器"));
	SendMessage(window, WM_CLOSE, 0, 0);//不需要附带内容
}

 打开一枚窗口

运行,发现窗口君他消失了

UNI 例子2- WM_SETTEXT

官方文档,定义,评论

The DefWindowProc function sets and displays the window text. For an edit control, the text is the contents of the edit control. For a combo box, the text is the contents of the edit-control portion of the combo box. For a button, the text is the button name. For other windows, the text is the window title.

简单来说就是,根据物件的不同改不同的名字,按钮改按钮的名字,窗口就改标题。

WM_SETTEXT message (Winuser.h) - Win32 apps | Microsoft Docs

试着写个代码改标题,结果成功了

//设置改标题
void testHWND2() {
	HWND window; //定义一个窗口句柄变量,用来储存窗口句柄
	window = FindWindow(NULL, TEXT("文件资源管理器"));
	SendMessage(window, WM_SETTEXT, 0, LPARAM(TEXT("喷3快来 我tm社保")));//属于long parameter的类型?我也不懂
}

这里遇到2个问题:

1.没法直接把字符串变成LPARAM类型传进去。但用LPARAM(" ")的形式可以传进去,推测是转型成了LPARAM类型。

2.字符串不作处理会出现乱码(估计C++会,而C不会),字符串前加TEXT可以转成unicode字符串就没有乱码了。

 执行后

UNI 例子3-WM_CHAR

文档WM_CHAR message (Winuser.h) - Win32 apps | Microsoft Docs

Parameters

wParam

The character code of the key.

用这个参数就完事了

The WM_UNICHAR message is similar to WM_CHAR, but it uses Unicode Transformation Format (UTF)-32, whereas WM_CHAR uses UTF-16.

这里提到UNICHAR可以使用更高字节数32位,但WM_CHAR可以使用16位的unicode字符,其实就已经可以使用中文了,足矣。

可以写个往QQ窗口写入信息,回车模拟发送的程序。

//发送
void sendKey() {
	HWND window; //定义一个窗口句柄变量,用来储存窗口句柄
	window = FindWindow(NULL, TEXT("XXX")); //根据需要抓窗口
    //英文
	string str1 = "This is automatic English sentence.";
	for (char c : str1)
		SendMessage(window, WM_CHAR, WPARAM(c), NULL);//英文用char遍历
    //中文
	wchar_t str2[] = L"这是代码执行的中文自动消息";//string 改成wchar_t 数组成功了
	for(wchar_t c:str2)
		SendMessage(window, WM_CHAR, WPARAM(c),NULL);//中文用unicode/wchar_t遍历
	//回车发送
    SendMessage(window, WM_KEYDOWN, VK_RETURN, NULL);
}

问题:用中文的时候用char遍历会乱码,要改成:wchar_t来获取中文字符。

wchar_t_百度百科

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值