day02 创建第一个Windows窗口及Windows的消息处理

第一个Windows窗口程序

1. 入口函数

Windows编程的入口函数:
建议直接F1查询官方文档,Ctrl C+V

int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
)
{
return 0;
}

2. 创建窗口类

我们准备创建一个窗口类,使用WNDCLASSW创建一个支持宽字符的窗口类:
这个类比较复杂,但是我们实际用到的属性不多:
WNDCLASSW函数原型官方文档

WNDCLASSW myClassWindow{ 0 };
myClassWindow.lpszClassName = L"我的第一个窗口"; //显式指定窗口类名
myClassWindow.lpfnWndProc = nullptr; //指定回调函数,我们之后会用到,暂时给他赋一个空值

我们创建一个最简单的窗口类,可以只声明这个两个参数的值,但是在我们以后的学习中,你就会慢慢丰富这个类,比如,我们可以指定窗口的图标,鼠标样式等等。。。我们以后再说。

3. 注册窗口

根据我们创建的窗口类,注册一个窗口实例:

RegisterClassW(&myClassWindow);

注册成功后,我们便可以使用这个窗口类创建一个实例对象了。

4. 创建窗口实例

CreatClass创建一个窗口类:

HWND window=CreateWindowW(
myClassWindow.lpszClassName,//窗口的类名
L"无标题", //窗口的标题
WS_OVERLAPPEDWINDOW, //窗口样式
CW_USEDEFAULT, //窗口的x坐标(左上角)
0, //窗口的y坐标
CW_USEDEFAULT, //窗口的width宽度
0, //窗口的height高度
NULL, //窗口的父窗口句柄(一般为空)
NULL, //菜单
hInstance, //与此窗口相关联的窗口句柄
NULL //一般为空
);
//显示窗口
ShowWindow(window, SW_SHOWNORMAL);

我们返回一个HWND的句柄,这样我们就得到我们的主窗口的句柄了。
然后再显示此窗口。

5. 处理消息事件

Windows系统是基于消息的操作系统。
每一个窗口都在不停的处理消息,所有的操作都是接收到消息之后,进行处理的结果。
围绕着消息的处理,产生了获取消息的消息泵机制也叫消息循环,以及处理消息的窗口回调函数机制。

消息的产生
Windows下产生消息的时机共有以下四种:
1、用户主动产生的消息
2、Windows系统本身产生的消息。
3、应用程序本身产生的消息。
4、其他应用程序产生的消息。
那么应用程序是如何接受消息的呢?

Windows操作系统有一个系统消息队列,每个GUI程序,都有自己的消息队列,系统消息队列负责将消息发送给不同GUI程序的消息队列。
API函数:
GetMessage 从消息队列中取出消息
TranslateMessage 翻译消息为字符消息
DispatchMessage 将消息发送给消息处理函数。

MSG msg{ 0 };
while (GetMessageW(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}

6. 回调函数

Wndproc: 在应用程序中定义的回调函数,用于处理发送到窗口的消息。

windows就是一个不断处理消息的系统,我们要对其处理消息,并且返回给主函数。

LRESULT CALLBACK Wndproc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg)
{
case WM_CREATE:
{
MessageBoxW(hwnd, L"窗口创建成功!", L"提示", MB_OK);
break;
}
case WM_CLOSE:
{
DestroyWindow(hwnd);
PostQuitMessage(NULL);
break;
}
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}

记得在我们最开始创建的窗口类中指明我们的回调函数:

myClassWindow.lpfnWndProc = Wndproc;

完整测试

#include <Windows.h>
LRESULT CALLBACK Wndproc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg)
{
case WM_CREATE:
{
MessageBoxW(hwnd, L"窗口创建成功!", L"提示", MB_OK);
break;
}
case WM_CLOSE:
{
DestroyWindow(hwnd);
PostQuitMessage(NULL);
break;
}
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
)
{
WNDCLASSW myClassWindow{ 0 };
myClassWindow.lpszClassName = L"我的第一个窗口";
myClassWindow.lpfnWndProc = Wndproc;
RegisterClassW(&myClassWindow);
HWND window=CreateWindowW(
myClassWindow.lpszClassName,//窗口的类名
L"无标题", //窗口的标题
WS_OVERLAPPEDWINDOW, //窗口样式
CW_USEDEFAULT, //窗口的x坐标(左上角)
0, //窗口的y坐标
CW_USEDEFAULT, //窗口的width宽度
0, //窗口的height高度
NULL, //窗口的父窗口句柄(一般为空)
NULL, //菜单
hInstance, //与此窗口相关联的窗口句柄
NULL //一般为空
);
//显示窗口
ShowWindow(window, SW_SHOWNORMAL);
MSG msg{ 0 };
while (GetMessageW(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return 0;
}

在这里插入图片描述
在这里插入图片描述


Windows消息处理

Windows通用消息:
Windows通用消息标志都定义在WINUSER.H中,以WM_开头,大体分为三类。

  1. 窗口消息
    例如:WM_CREATEWM_CLOSE

  2. 命令消息
    特指WM_COMMAND消息,与处理用户请求有关,如点击菜单项,工具栏,控件等就会产生命令消息。

  3. 通知消息
    特指WM_NOTIFY消息,只使用用windows的公共控件,如列表,视图等。

  • Windos控件消息
    控件消息是用于控制控件的一些行为的,不同的控件有不同的控制消息,命名规则如下:
    BM_按钮控制消息
    EM_编辑框控制消息
    STM_静态文本控制消息
    CM_组合框控制消息
    LBM_列表框控制消息

  • 用户自定义消息
    除了windows消息外,我们也可以定义自己的消息。系统的消息马在0-WM_USER之间,故而我们定义的消息大于WM_USER即可

  • 消息的发送
    PostMessageSendMessage
    PostMessage会将消息发送到消息队列,应用程序的消息循环会最终得到消息,并分发给回调函数。
    SendMessage相当于直接调用窗口的回调函数,等待窗口过程处理结束并返回结果。
    根据发送消息的方式不同,消息分为两类:
    队列消息、非队列消息

posted @   hugeYlh  阅读(40)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示