Windows编程初探(三)

窗口控件(按钮)

先包含库#include <CommCtrl.h>

以下代码即可在hwnd窗口创建一个按钮“按钮1”:

	CreateWindowW(
		WC_BUTTON,  // 使用已注册的窗口类名
		L"按钮1",            // 窗口标题文本
		WS_CHILD | WS_VISIBLE,   // 标准窗口样式,由于是在窗口里面,所以是CHILD属性,VISIBLE表示可见
		10,         // 初始x位置(使用默认值)
		10,                    // 初始y位置
		200,        // 窗口宽度(默认)
		100,                    // 窗口高度
		hwindow,                 // 父窗口句柄(无)
		NULL,                 // 菜单句柄(无)
		hInstance,            // 程序实例句柄
		0                     // 创建参数(无)
	);

如图:

需要注意的是,如果想把该代码放到回调函数里面,由于回调函数传参并不会传递程序实例句柄hInstance,得使用GetModuleHandleW函数来把hInstance传进来,代码如下所示:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HINSTANCE hInstance = GetModuleHandleW(NULL);
	switch (message)  // 根据消息类型进行分支处理
	{
	case WM_CREATE:
		// 创建按钮
		CreateWindowW(
			WC_BUTTON,  // 使用已注册的窗口类名
			L"按钮1",            // 窗口标题文本
			WS_CHILD | WS_VISIBLE,   // 标准窗口样式(带标题栏、边框等)
			10,         // 初始x位置(使用默认值)
			10,                    // 初始y位置
			200,        // 窗口宽度(默认)
			100,                    // 窗口高度
			hwnd,                 // 父窗口句柄(无)
			NULL,                 // 菜单句柄(无)
			hInstance,            // 程序实例句柄
			0                     // 创建参数(无)
		);
		break;

	case WM_LBUTTONDOWN:   // 鼠标左键点击时触发
		MessageBoxW(hwnd, L"鼠标左键点击", L"提示", MB_OK);  // 显示关闭提示
		SendMessageW(hwnd, WM_USERMSG, 0, 0);
		break;

	case WM_USERMSG: //收到自定义消息时触发
		MessageBoxW(hwnd, L"自定义消息触发", L"提示", MB_OK);
                break;
	case WM_RBUTTONDOWN:   // 鼠标右键点击时触发
		MessageBoxW(hwnd, L"鼠标右键点击", L"提示", MB_OK);  // 显示关闭提示
		SendMessageW((HWND)0x00010B4E, WM_CLOSE, 0, 0);
		break;


	default:  // 其他未处理的消息交给默认处理函数
		return DefWindowProc(hwnd, message, wParam, lParam);
	}
	return 0;  // 已处理的消息返回0
}

点击按钮之后,向回调函数发送的信息是WM_COMMAND(WM_COMMAND 消息 (Winuser.h) – Win32 apps | Microsoft Learn),下述代码可以实现点击按钮后的反馈:

	case WM_COMMAND:   // 按钮点击时触发
		MessageBoxW(hwnd, L"按钮点击", L"提示", MB_OK);  // 显示关闭提示
		break;

如图所示:

但是问题来了,如果想区分按钮1和按钮2怎么办?

这里就用到了回调函数中的后两个参数:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

给菜单句柄赋不同的值,然后接受wParam参数即可根据值得不同来处理不同的按钮,代码如下:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HINSTANCE hInstance = GetModuleHandleW(NULL);
	switch (message)  // 根据消息类型进行分支处理
	{
	case WM_CREATE:
		// 创建按钮
		CreateWindowW(
			WC_BUTTON,  // 使用已注册的窗口类名
			L"按钮1",            // 窗口标题文本
			WS_CHILD | WS_VISIBLE,   // 标准窗口样式(带标题栏、边框等)
			10,         // 初始x位置(使用默认值)
			10,                    // 初始y位置
			200,        // 窗口宽度(默认)
			100,                    // 窗口高度
			hwnd,                 // 父窗口句柄(无)
			(HMENU)0x100,                 // 菜单句柄(无)
			hInstance,            // 程序实例句柄
			0                     // 创建参数(无)

		);


		CreateWindowW(
			WC_BUTTON,  // 使用已注册的窗口类名
			L"按钮2",            // 窗口标题文本
			WS_CHILD | WS_VISIBLE,   // 标准窗口样式(带标题栏、边框等)
			10,         // 初始x位置(使用默认值)
			200,                    // 初始y位置
			200,        // 窗口宽度(默认)
			100,                    // 窗口高度
			hwnd,                 // 父窗口句柄(无)
			(HMENU)0x101,                 // 菜单句柄(无)
			hInstance,            // 程序实例句柄
			0                     // 创建参数(无)
		);
		break;

	case WM_LBUTTONDOWN:   // 鼠标左键点击时触发
		MessageBoxW(hwnd, L"鼠标左键点击", L"提示", MB_OK);  // 显示关闭提示
		SendMessageW(hwnd, WM_USERMSG, 0, 0);
		break;

	case WM_USERMSG: //收到自定义消息时触发
		MessageBoxW(hwnd, L"自定义消息触发", L"提示", MB_OK);
		break;

	case WM_RBUTTONDOWN:   // 鼠标右键点击时触发
		MessageBoxW(hwnd, L"鼠标右键点击", L"提示", MB_OK);  // 显示关闭提示
		SendMessageW((HWND)0x00010B4E, WM_CLOSE, 0, 0);
		break;

	case WM_COMMAND:   // 按钮点击时触发
	{
		WORD BUTTONMSG = LOWORD(wParam);
		if (BUTTONMSG == 0x100) {
			MessageBoxW(hwnd, L"按钮1点击", L"提示", MB_OK);  // 显示关闭提示
		}
		else if (BUTTONMSG == 0x101) {
			MessageBoxW(hwnd, L"按钮2点击", L"提示", MB_OK);  // 显示关闭提示
		}
		break;
	}
	default:  // 其他未处理的消息交给默认处理函数
		return DefWindowProc(hwnd, message, wParam, lParam);
	}
	return 0;  // 已处理的消息返回0
}

以下代码即可实现,一个按钮关闭QQ,一个按钮关闭浏览器:

#include <Windows.h> 
#include <CommCtrl.h>
const UINT WM_USERMSG = WM_USER + 1;
// 窗口过程函数 - 处理所有发送到窗口的消息
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HINSTANCE hInstance = GetModuleHandleW(NULL);
	switch (message)  // 根据消息类型进行分支处理
	{
	case WM_CREATE:
		// 创建按钮
		CreateWindowW(
			WC_BUTTON,  // 使用已注册的窗口类名
			L"关闭QQ",            // 窗口标题文本
			WS_CHILD | WS_VISIBLE,   // 标准窗口样式(带标题栏、边框等)
			10,         // 初始x位置(使用默认值)
			10,                    // 初始y位置
			200,        // 窗口宽度(默认)
			100,                    // 窗口高度
			hwnd,                 // 父窗口句柄(无)
			(HMENU)0x100,                 // 菜单句柄(无)
			hInstance,            // 程序实例句柄
			0                     // 创建参数(无)

		);


		CreateWindowW(
			WC_BUTTON,  // 使用已注册的窗口类名
			L"关闭浏览器",            // 窗口标题文本
			WS_CHILD | WS_VISIBLE,   // 标准窗口样式(带标题栏、边框等)
			10,         // 初始x位置(使用默认值)
			200,                    // 初始y位置
			200,        // 窗口宽度(默认)
			100,                    // 窗口高度
			hwnd,                 // 父窗口句柄(无)
			(HMENU)0x101,                 // 菜单句柄(无)
			hInstance,            // 程序实例句柄
			0                     // 创建参数(无)
		);
		break;

	case WM_LBUTTONDOWN:   // 鼠标左键点击时触发
		MessageBoxW(hwnd, L"鼠标左键点击", L"提示", MB_OK);  // 显示关闭提示
		SendMessageW(hwnd, WM_USERMSG, 0, 0);
		break;

	case WM_USERMSG: //收到自定义消息时触发
		MessageBoxW(hwnd, L"自定义消息触发", L"提示", MB_OK);
		break;

	case WM_RBUTTONDOWN:   // 鼠标右键点击时触发
		MessageBoxW(hwnd, L"鼠标右键点击", L"提示", MB_OK);  // 显示关闭提示
		SendMessageW((HWND)0x000600C4, WM_CLOSE, 0, 0);
		break;

	case WM_COMMAND:   // 按钮点击时触发
	{
		WORD BUTTONMSG = LOWORD(wParam);
		if (BUTTONMSG == 0x100) {
			MessageBoxW(hwnd, L"关闭QQ", L"提示", MB_OK);  // 显示关闭提示
			SendMessageW((HWND)0x000600C4, WM_CLOSE, 0, 0);
		}
		else if (BUTTONMSG == 0x101) {
			MessageBoxW(hwnd, L"关闭浏览器", L"提示", MB_OK);  // 显示关闭提示
			SendMessageW((HWND)0x00060718, WM_CLOSE, 0, 0);
		}
		break;
	}
	default:  // 其他未处理的消息交给默认处理函数
		return DefWindowProc(hwnd, message, wParam, lParam);
	}
	return 0;  // 已处理的消息返回0
}

// Windows应用程序入口点(不同于控制台程序的main)
int WINAPI WinMain(
	HINSTANCE hInstance,      // 当前程序实例句柄(由系统分配)
	HINSTANCE hPreHinstance,  // 前一个实例句柄(已废弃,总是NULL)
	LPSTR lpCmdLine,          // 命令行参数(ANSI字符串)
	int nCmdShow              // 窗口初始显示状态(最小化/正常等)
)
{
	// 1. 定义并初始化窗口类结构体
	WNDCLASSW myclass = { 0 };  // 清零初始化
	myclass.lpszClassName = L"n0ps1ed";  // 窗口类名称(唯一标识)
	myclass.lpfnWndProc = WndProc;       // 设置窗口消息处理函数


	// 2. 注册窗口类到操作系统
	RegisterClassW(&myclass);  // 注册后才能创建该类的窗口

	// 3. 创建窗口实例
	HWND hwindow = CreateWindowW(
		myclass.lpszClassName,  // 使用已注册的窗口类名
		L"n0ps1ed",            // 窗口标题文本
		WS_OVERLAPPEDWINDOW,   // 标准窗口样式(带标题栏、边框等)
		CW_USEDEFAULT,         // 初始x位置(使用默认值)
		0,                    // 初始y位置
		CW_USEDEFAULT,        // 窗口宽度(默认)
		0,                    // 窗口高度
		NULL,                 // 父窗口句柄(无)
		NULL,                 // 菜单句柄(无)
		hInstance,            // 程序实例句柄
		0                     // 创建参数(无)
	);


	// 4. 显示窗口
	ShowWindow(hwindow, SW_SHOWNORMAL);  // 以普通状态显示窗口


	// 5. 消息循环(程序核心)
	MSG msg = { 0 };
	while (GetMessageW(&msg, hwindow, 0, 0))  // 获取消息
	{
		DispatchMessageW(&msg);  // 将消息分发到窗口过程WndProc
	}

	return 0;  // 程序结束(当GetMessage收到WM_QUIT时退出循环)
}

此外,如果不用Spy++来找qq的句柄,也可以用FindWindowW来寻找:

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

		WORD BUTTONMSG = LOWORD(wParam);
		if (BUTTONMSG == 0x100) {
			HWND qq = FindWindowW(NULL, L"QQ");
			MessageBoxW(hwnd, L"关闭QQ", L"提示", MB_OK);  // 显示关闭提示
			SendMessageW((HWND)qq, WM_CLOSE, 0, 0);
		}

操作控件函数

操作控件可以用到以下函数:

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇