WinMain函数的定义
int WINAPI WinMain(
HINSTANCE hInstance, //应用程序实例
HINSTANCE hPrevInstance, //上一个应用程序实例
LPSTR lpCmdLine, //命令行参数
int nShowCmd); //窗口显示的样式
- WINAPI:是一个宏,它代表的是__stdcall(注意是两个下划线),表示的是参数传递的顺序:从右往左入栈,同时在函数返回前自动清空堆栈。
- hInstance:表示该程序当前运行的实例的句柄,这是一个数值。当程序在Windows下运行时,它唯一标识运行中的实例(注意,只有运行中的程序实例, 才有实例句柄)。一个应用程序可以运行多个实例,每运行一个实例,系统都会给该实例分配一个句柄值,并通过hInstance参数传递给 WinMain 函数。
- hPrevInstance:表示当前实例的前一个实例的句柄。在Win32环境下,这个参数总是NULL,即在Win32环境下,这个参数不再起作用。
- lpCmdLine:是一个以空终止的字符串, 指定传递给应用程序的命令行参数,相当于C或C++中的main函数中的参数char *argv[]。
- nShowCmd:表示一个窗口的显示,表示它是要最大化显示、最小化显示、正常大小显示还是隐藏显示。
3) 创建一个窗口
创建一个完整的窗口,需要经过下面几个步骤:
- 设计一个窗口类
- 注册窗口类
- 创建窗口
- 显示及更新窗口
- 设计一个窗口类
一个完整的窗口具有许多特征, 包括光标(鼠标进入该窗口时的形状)、图标、背景色等。窗口的创建过程类似于汽车的制造过程。
我们在生产一个型号的汽车之前, 首先要对该型号的汽车进行设计, 在图纸上画出汽车的结构图, 设计各个零部件, 同时还要给该型号的汽车取一个响亮的名字, 例如“宝马 x6”。
类似地, 在创建一个窗口前, 也必须对该类型的窗口进行设计, 指定窗口的特征。在Windows中,窗口的特征就是由WNDCLASS结构体来定义的,我们只需给WNDCLASS结构体对应的成员赋值,即可完成窗口类的设计。
WNDCLASS结构体的定义如下:
typedef struct _WNDCLASS{
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCWSTR lpszMenuName;
LPCWSTR lpszClassName;
} WNDCLASS;
- style:指定窗口的样式(风格),常用的样式如下:
类型 | 含义 |
CS_HREDRAW | 当窗口水平方向上的宽度发生变化时, 将重新绘制整个窗口。 当窗口发生重绘时, 窗口中的文字和图形将被擦除。如果没有指定这一样式,那么在水平方向上调整窗口宽度时,将不会重绘窗口。 |
CS_VREDRAW | 当窗口垂直方向上的高度发生变化时,将重新绘制整个窗口。如果没有指定这一样式,那么在垂直方向上调整窗口高度时,将不会重绘窗口。 |
CS_NOCLOSE | 禁用系统菜单的 Close 命令,这将导致窗口没有关闭按钮。 |
CS_DBLCLKS | 当用户在窗口中双击鼠标时,向窗口过程发送鼠标双击消息。 |
- lpfnWndProc:指定一个窗口回调函数,是一个函数的指针。
当应用程序收到给某一窗口的消息时,就应该调用某一函数来处理这条消息。这一调用过程不用应用程序自己来实施,而由操作系统来完成,但是,回调函数本身的代码必须由应用程序自己完成。对于一条消息,操作系统调用的是接受消息的窗口所属的类型中的lpfnWndProc成员指定的函数。每一种不同类型的窗口都有自己专用的回调函数,该函数就是通过lpfnWndProc成员指定的。
回调函数的定义形式如下:
LRESULT CALLBACK WindowProc(
HWND hWnd, //信息所属的窗口句柄
UINT uMsg, //消息类型
WPARAM wParam, //附加信息(如键盘哪个键按下)
LPARAM lParam //附加信息(如鼠标点击坐标)
);
- cbClsExtra:类的附加内存,通常数情况下为0。
- cbWndExtra:窗口附加内存,通常情况下为0。
- hInstance:当前实例句柄,用WinMain中的形参hInstance为其赋值。
- hIcon:指定窗口类的图标句柄,设置为NULL,则使用默认图标,也可用如下函数进行赋值:
HICON LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName);
如:LoadIcon(NULL, IDI_WARNING); //第一个参数为NULL,加载系统默认图标
- hCursor:指定窗口类的光标句柄,设置为NULL,则使用默认图标,也可用如下函数进行赋值:
HCURSOR LoadCursor(HINSTANCE hInstance, LPCTSTR lpCursorName);
如:LoadCursor(NULL, IDC_HELP); //第一个参数为NULL,加载系统默认光标
- hbrBackground:指示窗口的背景颜色,可用如下函数进行赋值:
HGDIOBJ GetStockObject(int fnObject);
如:GetStockObject(WHITE_BRUSH);
- lpszMenuName:指定菜单资源的名字。如果设置为NULL,那么基于这个窗口类创建的窗口将没有默认菜单。
- lpszClassName:指定窗口类的名字。
示例代码如下:
WNDCLASS wc; //窗口类变量
wc.cbClsExtra = 0; //类附加内存
wc.cbWndExtra = 0; //窗口附加内存
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //背景色为白色
wc.hCursor = (HCURSOR)LoadCursor(NULL, IDC_HELP); //帮助光标
wc.hIcon = (HICON)LoadIcon(NULL, IDI_WARNING); //警告图标
wc.hInstance = hInstance; //应用程序实例,为WinMain第1个形参
wc.lpfnWndProc = WinProc; //窗口过程函数名字
wc.lpszClassName = TEXT("MyWin"); //类的名字
wc.lpszMenuName = NULL; //没有菜单
wc.style = 0; //类的风格,填0,使用默认风格
- 注册窗口类
设计完窗口类(WNDCLASS)后, 需要调用RegisterClass函数对其进行注册,注册成功后,才可以创建该类型的窗口。
注册函数的原型声明如下:
ATOM RegisterClass(CONST WNDCLASS *lpWndClass);
使用示例:RegisterClass(&wc);
- 创建窗口
设计好窗口类并且将其成功注册之后, 即可用CreateWindow函数产生这种类型的窗口了。
CreateWindow函数的原型声明如下:
HWND CreateWindow(
LPCTSTR lpClassName,
LPCTSTR lpWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam);
参数说明:
- lpClassName:指定窗口类的名称,此名字必须和WNDCLASS的lpszClassName成员指定的名称一样。
- lpWindowName:指定窗口的名字,即窗口的标题。
- dwStyle:指定创建的窗口的样式,常指定为指WS_OVERLAPPEDWINDOW类型,这是一种多种窗口类型的组合类型。
- x, y:指定窗口左上角的x,y坐标。如果参数x被设为CW_USEDEFAULT,那么系统为窗口选择默认的左上角坐标并忽略y参数。
- nWidth,nHeight:指定窗口窗口的宽度,高度。如果参数nWidth被设为 CW_USEDEFAULT,那么系统为窗口选择默认的宽度和高度,参数nHeight被忽略。
- hWndParent:指定被创建窗口的父窗口句柄,没有父窗口,则设置NULL。
- hMenu:指定窗口菜单的句柄,没有,则设置为NULL。
- hInstance:窗口所属的应用程序实例的句柄,用WinMain中的形参hInstance为其赋值。
- lpParam:作为WM_CREATE消息的附加参数lParam传入的数据指针。通常设置为NULL。
返回值说明:如果窗口创建成功,CreateWindow函数将返回系统为该窗口分配的句柄,否则,返回NULL。
示例代码:
HWND hWnd = CreateWindow(
TEXT("MyWin"), //窗口类名字
TEXT("测试"), //窗口标题
WS_OVERLAPPEDWINDOW, //窗口风格
CW_USEDEFAULT, CW_USEDEFAULT, //窗口x,y坐标,使用默认值
CW_USEDEFAULT, CW_USEDEFAULT, //窗口宽度,高度,使用默认值
NULL, //无父窗口
NULL, //无菜单
hInstance, //应用程序实例句柄,为WinMain第1个形参
NULL); //附件信息,通常设置为NULL
- 显示及更新窗口
显示窗口函数原型:
BOOL ShowWindow(HWND hWnd, int nCmdShow);
更新窗口函数原型:
BOOL UpdateWindow(HWND hWnd);
示例代码:
ShowWindow(hWnd, SW_SHOWNORMAL); //SW_SHOWNORMAL为普通模式
UpdateWindow(hWnd);
- 示例代码
//设计一个窗口类
WNDCLASS wc; //窗口类变量
wc.cbClsExtra = 0; //类附加内存
wc.cbWndExtra = 0; //窗口附加内存
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //背景色为白色
wc.hCursor = LoadCursor(NULL, IDC_HELP); //帮助光标
wc.hIcon = LoadIcon(NULL, IDI_WARNING); //警告图标
wc.hInstance = hInstance; //应用程序实例,为WinMain第1个形参
wc.lpfnWndProc = WinProc; //窗口过程函数名字
wc.lpszClassName = TEXT("MyWin"); //类的名字
wc.lpszMenuName = NULL; //没有菜单
wc.style = 0; //类的风格,填0,使用默认风格
//注册窗口类
RegisterClass(&wc);
//创建窗口
HWND hWnd = CreateWindow(TEXT("MyWin"), TEXT("测试"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
//显示及更新窗口
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
标签:wc,函数,windows,句柄,模型,编程,hInstance,窗口,NULL From: https://blog.csdn.net/ffffffeiyu/article/details/137345358