1.Win32项目
对于Win32项目,需要创建指定的Win32项目工程。
1.) 对于一个Win32项目,需要调用头文件“Windows.h”;
2.) win32应用程序的入口点:WinMain()函数;
3.) WinMain()函数需要给定四个参数,分别是
HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR IpCmdLine,int nCmdShow
4.) 第一个参数是当前应用程序实例的句柄,应用程序实例是指运行某个应用程序之后产生的,比如QQ可以运行多个QQ号;
5.) 第二个参数是前一个实力句柄,win32不使用,一般设置为NULL;
6.) 第三个参数,命令行参数
7.) 第四个参数,显示窗口
2.设计窗口的四个步骤
1.设计窗口
WNDCLASSEX ex;
ex.style = CS_HREDRAW | CS_VREDRAW; // 窗口的刷新方式;水平刷新:改变宽度则刷新;垂直刷新:改变高度则刷新
ex.cbSize = sizeof(WNDCLASSEX); // 当前结构体的大小
ex.cbClsExtra = 0; // 为结构体开辟附加空间存储结构体的附加信息
ex.cbWndExtra = 0; // 注册窗口时申请的空间大小存放此窗口的特有数据,通常为0
ex.hInstance = hInstance; // 应用程序句柄,此结构体在哪个应用程序中使用
ex.hIcon = NULL; // 指定窗口类图标的句柄
ex.hCursor = NULL; // 加载鼠标为空使用系统默认图标
ex.hbrBackground = CreateSolidBrush(RGB(0, 0, 255)); // 指定背景画刷句柄
ex.hIconSm = NULL; // 窗体图标,最左上角的小图标
ex.lpfnWndProc = &my_wndproc; // 消息处理函数指针
ex.lpszMenuName = NULL; // 加载菜单名,为空则没有菜单
ex.lpszClassName = "aa"; // 字符集,默认为unicode,可在项目中修改为多字符
2.注册窗口
RegisterClassEx(&ex);
3.创建窗口
使用CreateWindow函数,创建窗口时需要包括风格,大小,菜单,图标,背景,窗口函数等信息。
h_wnd = CreateWindow(ex.lpszClassName, lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam);
//
参数详解:
1.)
2.) 第二个参数–lpWindowName:窗口的名字(标题栏)
3.) 第三个参数–DWORD dwStyle:窗体样式,默认使用WS_OVERLAPPEDWINDOW
4.) 第四个参数–int x:窗口的起始点的横坐标
5.) 第五个参数–int y:窗口的起始点的横坐标
6.) 第六个参数–int nWidth:窗口的宽
7.) 第七个参数–int nHeight:窗口的高
8.) 第八个参数–HWND hWndParent:父窗口句柄
9.) 第九个参数–HMENU hMenu:制定菜单句柄
10.) 第十个参数–HINSTANCE hInstance:窗口所属应用程序的句柄
11.) 第11个参数–LPVOID lpParam:创建多文档时赋值,默认值为NULL
4.显示窗口
使用ShowWindow函数。
ShowWindow(HWND hwnd, int mCmdShow);
参数详解:
1.) 第一个参数–HWND hwnd:创建窗口时返回的窗口句柄
2.) 第二个参数–int mCmdShow:指定窗口显示的位置,SW_HIDE:隐藏窗口并激活其它窗口 SW_SHOW:在窗口原来的位置原来的大小激活窗口
3.召回函数CALLBACK
由于win32程序的运行机制是消息机制,因此若想在一个VS Win32项目中显示窗口还需要修改设计窗口时的lpfnWndProc属性。
对于该属性,需要创建一个处理消息的函数去处理接收到的消息,函数如下。
LRESULT CALLBACK my_wndproc(HWND h_wnd, UINT message_flag, WPARAM w_param, LPARAM l_param)
{
switch (message_flag)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc(h_wnd, message_flag, w_param, l_param);
}
参数详解:
1.) 第一个参数–HWND hWnd:窗口所在的应用程序句柄
2.) 第一个参数–UINT message:消息的类型
3.) 第一个参数–WPARAM wParam:一般是来源的ID号消息
4.) 第一个参数–LPARAM lParam:是通过消息传输的数据
4.其他必须的函数
在完成函数的定义之后,需要在WinMain函数中先翻译信息,再分发信息。
首先需要一个函数来接受信息:GetMessage
GetMessage(指向一个MSG指针,指向接受哪个窗口的消息 为NULL接收所有窗口,指定要获取的消息的最小值 通常为0,指定要获取的消息的最小值 最大最小都为0则接收所有)
翻译信息和分发信息:
TranslateMessage(&my_msg);
DispatchMessage(&my_msg);
整体合成一个循环,因为会一直接受信息:
while(GetMessage(&my_msg, NULL, 0, 0))
{
TranslateMessage(&my_msg);
DispatchMessage(&my_msg);
}
5.创建一个win32窗口的整体程序(可直接运行)
#include "Windows.h"
LRESULT CALLBACK my_wndproc(HWND h_wnd, UINT message_flag, WPARAM w_param, LPARAM l_param);
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR IpCmdLine, int nCmdShow)
{
HWND h_wnd;
MSG my_msg;
// 1.设计窗口
WNDCLASSEX ex;
ex.style = CS_HREDRAW | CS_VREDRAW; // 窗口的刷新方式
ex.cbSize = sizeof(WNDCLASSEX); // 当前结构体的大小
ex.cbClsExtra = 0; // 为结构体开辟附加空间存储结构体的附加信息
ex.cbWndExtra = 0; // 注册窗口时申请的空间大小存放此窗口的特有数据,通常为0
ex.hInstance = hInstance; // 应用程序句柄,此结构体在哪个应用程序中使用
ex.hIcon = NULL; // 指定窗口类图标的句柄
ex.hCursor = NULL; // 加载鼠标为空使用系统默认图标
ex.hbrBackground = CreateSolidBrush(RGB(0, 0, 255)); // 指定背景画刷句柄
ex.hIconSm = NULL; // 窗体图标,最左上角的小图标
ex.lpfnWndProc = &my_wndproc; // 消息处理函数指针
ex.lpszMenuName = NULL; // 加载菜单名,为空则没有菜单
ex.lpszClassName = "aa"; // 字符集,默认为unicode,可在项目中修改为多字符
// 2.注册窗口
RegisterClassEx(&ex);
// 3.创建窗口
h_wnd = CreateWindow(ex.lpszClassName, "hahaah", WS_OVERLAPPEDWINDOW, 50, 50, 100, 100, NULL, NULL, hInstance, NULL);
// 4.显示窗口
ShowWindow(h_wnd, SW_SHOW);
// GetMessage(指向一个MSG指针,指向接受哪个窗口的消息 为NULL接收所有窗口,指定要获取的消息的最小值 通常为0,指定要获取的消息的最小值 最大最小都为0则接收所有)
while(GetMessage(&my_msg, NULL, 0, 0))
{
TranslateMessage(&my_msg); // 翻译消息
DispatchMessage(&my_msg); // 分发消息
}
return 0;
}
LRESULT CALLBACK my_wndproc(HWND h_wnd, UINT message_flag, WPARAM w_param, LPARAM l_param)
{
switch (message_flag)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc(h_wnd, message_flag, w_param, l_param);
}