Win32:Windows 窗口的原理,既可以编 32 位也可以编 64 位
WM:Windows Message
创建窗口的窗口类型名要写第一步、第二步注册窗口的类型名,否则会导致创建窗口失败
下面来解析 Windows 中常用的消息:
窗口处理函数会处理很多消息,会处理哪些消息呢?下面来监测一下这些消息是什么
//窗口处理函数
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
//定义一个字符串
wchar_t szMsg[100];
//多字节用 sprintf
//格式化-> 宽字符用 wsprintf
//把格式化的字符串存储到szMsg中,格式化窗口句柄hWnd 用十六进制显示 #会自动加前缀
wsprintf(szMsg,L"hWnd:%#x\tuMsg:%#x\twParm:%#x\tlParam:%#x\n",hWnd,uMsg,wParam,lParam);
//用于输出调试信息
OutputDebugString(szMsg);
switch(uMsg)
{
//窗口客户区创建消息,出来的比较早的一个消息,此时主窗口已经创建好了,只不过没有显示出来
case WM_CREATE:
//父窗口为hWnd:当前创建的窗口
//CreateWindow 函数的调用或者CreateWindowEx 函数的调用会发出 WM_CREATE 消息
MessageBox(hWnd,"这是WM_CREATE消息",L"提示",MB_OK);
//设置窗口的标题 要设置的窗口 要设置的标题
SetWindowText(hWnd,L"windows编程");
break;
}
}
WINBASEAPI
VOID
WINAPI
OutputDebugStringW(
_In_opt_ LPCWSTR lpOutputString
);
#ifdef UNICODE
#define OutputDebugString OutputDebugStringW
窗口出来之前会有消息, 会调用 WindowProc 函数很多次,会打印调试信息很多次
调试导致以下问题,直接去掉即可,就不会输出下面的信息:
窗口句柄:都是相同的,是同一个窗口
当窗口大小发生改变的时候,会发出这个消息,应用程序将使用这个消息,去改变默认的大小值和位置
WM_GETMINMAXINFO 消息 (Winuser.h) - Win32 apps | Microsoft Docs
NC:非客户区
C:客户区
非客户区的创建
非客户区自动计算大小
窗口创建消息:客户区的创建
消息分为入队列消息和不入队列消息
进队列的消息
不进队列的消息:不需要 GetMessage 去取消息,例如 WM_CREATE
GetMessage:从消息队列去取消息
WPARAM wParam,LPARAM lParam 为附加信息
会把创建窗口信息的值传到 lParam 中
正向缩进 tab,反向缩进 shift + tab
LPARAM 指向结构体 CREATESTRUCT 的指针
typedef struct tagCREATESTRUCTW {
LPVOID lpCreateParams;
HINSTANCE hInstance; //应用程序实例句柄
HMENU hMenu; //菜单句柄
HWND hwndParent; //父窗口句柄
int cy; //窗口的高度
int cx; //窗口的宽度
int y; //窗口左上角纵坐标
int x; //窗口左上角横坐标
LONG style; //风格
LPCWSTR lpszName; //窗口名
LPCWSTR lpszClass; //窗口类型名
DWORD dwExStyle; //窗口的拓展风格
} CREATESTRUCTW, *LPCREATESTRUCTW;
#ifdef UNICODE
typedef CREATESTRUCTW CREATESTRUCT;
//窗口处理函数
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
wchar_t szMsg[100];
wsprintf(szMsg,L"hWnd:%#x\tuMsg:%#x\twParm:%#x\tlParam:%#x\n",hWnd,uMsg,wParam,lParam);
OutputDebugString(szMsg);
switch(uMsg)
{
case WM_CREATE:
//指向结构体的指针-> 强制类型转换为 LPCREATESTRUCT 任何指针都是指向四个字节
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
}
}
在 case 中定义变量一定要加 { },表示是一个语句块, 不加 { } 会出现问题
开始调试的同时,打开监视窗口
选中变量,拖动到监视窗口中
或者直接输入
按 F10 单步调试后
IPCreateParams 创建窗口时需要传递的信息 NULL:没有要传递的,如果传入某个值,那个值就被传到 IPCreateParams,注意传的是指针
检查窗口类型名,注意每一个应用程序都有一个窗口类型名
为什么要有窗口类型名?
任何一个窗口都有一个窗口类型名→ 检查窗口类型名
spy++:一个是 32位,一个是 64位
点击查找窗口,按住鼠标移动到想要检查的窗口即可
CreateWindow 中最后一个参数 lParam,int 类型强制转换为指针类型
HWND hWnd = CreateWindow(
szAppClassName, //注册窗口的类型名
szWindowName, //窗口的标题
WS_CAPTION | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINMIZEBOX, //窗口的风格 标题栏|系统菜单
200, //窗口距离屏幕左上角横坐标
200, //窗口距离屏幕左上角纵坐标
800, //窗口的宽度
600, //窗口的高度
NULL, //父窗口句柄
NULL, //菜单句柄
hInstance, //应用程序实例句柄
(LPVOID)10 //创建窗口时需要传递的信息 NULL:没有要传递的
);
typedef void far *LPVOID;
#define far
很多需要初始化的东西都可以放在 WM_CREATE 中
else
{
break;
}
//如果不想自己处理、处理不了. . . 调用这个函数就交给操作系统处理
无论是否点了退出,最终都会执行这条语句:return DefWindowProc(hWnd,uMsg,wParam,lParam);
点击是
点击否,窗口也被关闭
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//窗口关闭消息
case WM_CLOSE:
if(IDYES == MessageBox(NULL,L"您确定要退出吗?",L"提示",MB_YESNO))
{
//销毁当前处理的窗口句柄-> 发出 WM_DESTROY 信息
DestroyWindow(hWnd);
}
else
{ //如果不执行break
break;
}
break;
//窗口销毁消息
case WM_DESTROY:
//发出一个退出消息 WM_QUIT-> 传入0正常退出
PostQuitMessage(0);
break;
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
能不能让它不处理,不想让它调用 DefWindowProc?
WM_CLOSE消息 (Winuser.h) - Win32 apps | Microsoft Docs
在关闭窗口时,不需要传递任何值
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
//窗口关闭消息
case WM_CLOSE:
if(IDYES == MessageBox(NULL,L"您确定要退出吗?",L"提示",MB_YESNO))
{
//销毁当前处理的窗口句柄-> 发出 WM_DESTROY 信息
DestroyWindow(hWnd);
}
else
{
//点击否 最小化
ShowWindow(hWnd,SW_MINIMIZE);
//点击否 隐藏运行|托盘
ShowWindow(hWnd,SW_HIDE);
return 1; //我已经处理了,不需要你再处理了
//return 0; //我没有处理,你再处理,但是我没有交给操作系统默认处理函数处理
}
break;
//窗口销毁消息
case WM_DESTROY:
//主要做一些清理工作、保存数据-> 凡是程序走到这个地方程序不能还原 不能再显示窗口
ShowWindow(hWnd,SW_MINIMIZE);
return 1;
//发出一个退出消息 WM_QUIT-> 传入 0 正常退出
PostQuitMessage(0);
break;
}
//调用操作系统默认窗口处理函数
//如果不想自己处理、处理不了...调用这个函数就交给操作系统处理
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
文章来源:https://www.toymoban.com/news/detail-482052.html
文章来源地址https://www.toymoban.com/news/detail-482052.html
到了这里,关于Windows --- 常用消息以及消息附加参数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!