C++之 (1) windows窗口生成

代码解析

函数声明

#include <windows.h>
// 窗口过程函数原型
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);

LRESULT:Long Result,是一个长整型数据类型,表示函数返回的结果。在消息处理函数中,通常用于返回消息的处理结果。
CALLBACK:用来告诉编译器这个函数将作为一个回调函数被调用。回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数(callback)是什么?

WindowProcedure:窗口过程,就是一个回调函数,这个函数由操作系统在有消息送到窗口的时候调用,窗口过程里对不同的消息进行处理,从而实现响应消息,做出反应。比如按下按钮,打开菜单,点击鼠标等。

HWND:handle to a window,窗口的句柄。图解说明——究竟什么是Windows句柄
UINT:unsigned int,无符号整型,是windows message的编号。
Param:参数。
WPARAM和LPARAM:字(word)参数和长(long)参数。WPARAM和LPARAM的含义

// WinMain:应用程序入口点
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow)

WinMain函数的4个参数

WinMain 函数接收 4 个参数,这些参数都是在系统调用 WinMain 函数时,传递给应用程序的。

WinMain:是窗口函数的语言声明,不可使用Main代替。

HINSTANCE hInst:实例句柄,指向当前正在运行的窗口。实例是指正在运行的窗口类程序。句柄是一种void型的无返回值的控制型指针。

HINSTANCE hPrevInst:表示上一个实例,在Win32中该参数始终为NULL

关于WinMain函数的第二个参数解释

LPSTR:Long Pointer string。Long Pointer是长指针,string是字符串类型。是一个以NULL终止的字符串,指定传递给应用程序的命令行参数。

例如:在 D 盘下有一个 sunxin.txt 文件,当我们用鼠标双击这个文件时将启动记事本程序( notepad.exe ),此时系统会将 D:/sunxin.txt 作为命令行参数传递给记事本程序的 WinMain 函数,记事本程序在得到这个文件的全路径名后,就在窗口中显示该文件的内容。

int ncmdshow:命令行指令,指定程序的窗口应该如何显示,例如最大化、最小化、隐藏等。这个参数的值由该程序的调用者所指定,在调用ShowWindow()时可以使用到该值。

创建窗口

{ 
WNDCLASSW wc = {0}; // 创建窗口类结构体实例,并初始化为0
wc.hbrBackground = (HBRUSH)COLOR_WINDOW; // 窗口背景颜色
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 窗口光标
wc.hInstance = hInst; // 应用程序实例句柄
wc.lpszClassName = L"MyWindowClass"; // 窗口类名
wc.lpfnWndProc = WindowProcedure; // 窗口过程函数

WNDCLASSW是一个结构体,与CReateWindowsW是模板与实例的关系。

// 注册窗口类
if (!RegisterClassW(&wc)) 
return -1;

类:类是C++中对于C语言中的结构体的延伸,class将结构相同的对象归统在类中,在类中定义这些对象相同的属性,行为,以及访问权限等。

教学视频:P99   类和对象-封装-属性和行为作为整体

RegisterClassW():注册窗口类函数。理解RegisterClass

参数:&wc表示对变量wc的地址进行引用。在C和C++中&运算符用于获取变量的地址。

检测函数:在if()中如果出现了!跟在非布尔型前面,表示这是一个检测函数,等价为

if(Fn()==0){
return -1;
}

而一般来说,函数Fn()只有在运行失败时返回值才会是0,所以这可以作为一个检测函数来判断函数是否运行失败。

// 创建窗口
CreateWindowW(L"MyWindowClass", L"我的窗口", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, 
100, 500, 500, NULL, NULL, NULL, NULL);

L”MyWindowClass”:lpClassName, 如果 lpClassName 是字符串,则指定窗口类名称。

IpClassName :指向一个指定了类名的空字符串,或一个标识类名字符串的成员的指针。该参数实际是一个指针,用于创建一个类成员并定义类的属性,此处定义的是类名。

WS_OVERLAPPEDWINDOW | WS_VISIBLE:创建出的窗口样式,windows style。

WS_OVERLAPPED:产生一个层叠的窗口,一个层叠的窗口有一个标题栏和一个边框。

WS_VISIBLE:窗口初始时可见。

100,100,500,500:(100,100)定义的是窗口框左上角定位点的初始坐标位置,500,500分别是宽和高。

后四个参数:详看以下链接。

CreateWindowW 宏 (winuser.h)

消息循环以及消息响应

// 消息循环
MSG msg = {0}; 
while( GetMessage(&msg, NULL, 0, 0) ) 
{ 
TranslateMessage(&msg); 
DispatchMessage(&msg); 
} 
return 0; 
}

MSG:结构体名,创建一个名为msg的结构体,初始化为0。

GetMessage:获取消息编号和其他参数,其中&msg表示指向MWG结构的指针,该结构从线程的消息队列接收消息信息。NULL表示当前窗口类。0,0是过滤器参数,捕捉编号为int-int之间的信息,如果为(0,0)则不进行过滤全部捕捉。

当GetMessage接收到WM_QUIT消息时,GetMessage输出0,断开消息获取,退出while循环。WM_QUIT消息会在应用程序调用 PostQuitMessage函数时生成。

TranslateMessage:编译消息。

DispatchMessage:发送编译后的消息给WindowProcedure。

getMessage 函数 (winuser.h)

// 窗口过程函数:处理窗口消息
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) 
{ 
switch(msg) 
{ 
case WM_DESTROY: 
PostQuitMessage(0); 
break; 
default: 
return DefWindowProcW(hwnd, msg, wp, lp); 
} 
return 0; 
}

该函数为死循环函数,在窗口运行过程中不断执行。

switch对消息的编号进行遍历。

WM_DESTROY:按下窗口右上角关闭按钮时发出该消息。

PostQuitMessage:退出并关闭窗口进程。

 

完整代码

#include <windows.h>
// 窗口过程函数原型
LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM);
// WinMain:应用程序入口点
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int ncmdshow)
{
WNDCLASSW wc = {0}; // 创建窗口类结构体实例,并初始化为0
wc.hbrBackground = (HBRUSH)COLOR_WINDOW; // 窗口背景颜色
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 窗口光标
wc.hInstance = hInst; // 应用程序实例句柄
wc.lpszClassName = L"MyWindowClass"; // 窗口类名
wc.lpfnWndProc = WindowProcedure; // 窗口过程函数
// 注册窗口类
if (!RegisterClassW(&wc))
return -1;
// 创建窗口
CreateWindowW(L"MyWindowClass", L"我的窗口", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100,
100, 500, 500, NULL, NULL, NULL, NULL);
// 消息循环
MSG msg = {0};
while( GetMessage(&msg, NULL, 0, 0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
// 窗口过程函数:处理窗口消息
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hwnd, msg, wp, lp);
}
return 0;
}
如果这篇文章对您有所帮助,不妨打赏一下作者吧~
暂无评论

发送评论 编辑评论


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