MFC基础学习
消息循环机制
底层实现窗口
创建窗口详细步骤
- 设计窗口
- 注册窗口
- 创建窗口
- 显示和更新
- 通过循环取消息
- 处理消息(窗口过程函数)
详细代码过程
//底层实现窗口的头文件
#include <Windows.h>
//6窗口回调函数
LRESULT CALLBACK my_windows_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
//程序入口函数
/*
CALLBACK是一个宏,==> __stdcall,代表函数中参数的传递顺序
即:从右往左依次入栈,并且在函数返回前,清空堆栈
int CALLBACK WinMain(
HINSTANCE hInstance, //代表应用程序实例句柄
HINSTANCE hPrevInstance, //表示上一个应用程序句柄,在win32环境下,参数一般为NULL,不起作用了
LPSTR lpCmdLine, //参数列表,相当于char *argv[],参数类型为char *
int nCmdShow //显示命令,常用的有最大化、最小化、正常等
);
*/
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//1设计窗口
//1.0窗口类:WNDCLASS
WNDCLASS windows_class;
//1.1类的额外内存,若不需要添加额外的内存,则设置为0
windows_class.cbClsExtra = 0;
//1.2窗口的额外内存,若不需要添加额外的内存,则设置为0
windows_class.cbWndExtra = 0;
//1.3设置背景
windows_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
//1.4设置光标,如果第一个参数为NULL,则默认使用系统标准光标
windows_class.hCursor = LoadCursor(NULL, IDC_HAND);
//1.5设置图标,如果第一个参数为NULL,则默认使用系统标准图标
windows_class.hIcon = LoadIcon(NULL, IDI_ERROR);
//1.6应用程序的实例句柄,传入WinMain中的形参即可
windows_class.hInstance = hInstance;
//1.7窗口过程的回调函数
windows_class.lpfnWndProc = my_windows_proc;
//1.8指定窗口的类名称
windows_class.lpszClassName = TEXT("WIN");
//1.9菜单名称
windows_class.lpszMenuName = NULL;
//1.10显示风格,0代表默认风格
windows_class.style = 0;
//2注册窗口
RegisterClass(&windows_class);
//3创建窗口,使用函数CreateWindow()来进行创建,该函数的返回值为HWND
/*
HWND WINAPI CreateWindow(
_In_opt_ LPCTSTR lpClassName, //类名
_In_opt_ LPCTSTR lpWindowName, //标题名
_In_ DWORD dwStyle, //窗口的风格:这里使用WS_OVERLAPPEDWINDOW
_In_ int x, //显示窗口的坐标,可以使用默认值:CW_USEDEFAULT
_In_ int y,
_In_ int nWidth, //显示窗口的宽高,可以使用默认值:CW_USEDEFAULT
_In_ int nHeight,
_In_opt_ HWND hWndParent, //当前窗口的父窗口,若没有则默认写:NULL
_In_opt_ HMENU hMenu, //菜单:默认写NULL
_In_opt_ HINSTANCE hInstance, //实例句柄:hInstance
_In_opt_ LPVOID lpParam //附加参数,有鼠标附加值、键盘附加值等,若没有则默认写:NULL
);
*/
HWND hwnd = (HWND)CreateWindow(windows_class.lpszClassName, TEXT("meizi"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
//4显示和更新
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
//5通过循环取消息
//消息的结构体对象
/*
typedef struct tagMSG {
HWND hwnd; //主窗口实例句柄
UINT message; //具体消息句柄
WPARAM wParam; //附加消息,键盘消息
LPARAM lParam; //附加消息,鼠标消息
DWORD time; //消息产生时间
POINT pt; //附加消息,如鼠标等消息
} MSG, *PMSG, *LPMSG;
*/
MSG myMsg;
while (1)
{
//获取消息:相关函数GetMessage()
/*
GetMessage():
BOOL WINAPI GetMessage(
_Out_ LPMSG lpMsg, //相应消息
_In_opt_ HWND hWnd, //捕获窗口,若为NULL,则表示捕获所有的窗口
_In_ UINT wMsgFilterMin, //最小和最大的过滤消息,一般填0,代表捕获所有的消息
_In_ UINT wMsgFilterMax //
);
*/
BOOL ret = GetMessage(&myMsg, NULL, 0, 0);
if (FALSE == ret)
{
break;
}
//若为TRUE,则需要进行以下操作
//翻译消息
TranslateMessage(&myMsg);
//分发消息
DispatchMessage(&myMsg);
}
//6处理消息(窗口过程函数)
return 0;
}
//6窗口回调函数
/*
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd, //消息所属的窗口句柄
_In_ UINT uMsg, //具体的消息名称,如WM_XXXX消息名
_In_ WPARAM wParam, //键盘附加消息
_In_ LPARAM lParam //鼠标附加消息
);
*/
LRESULT CALLBACK my_windows_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
//函数DestroyWindow()发送另一个消息WM_DESTROY
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN: //鼠标
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
//MessageBox(hwnd, TEXT("左键按下"), TEXT("itcast"), MB_OK);
char buf[1024] = { 0 };
wsprintf((LPWSTR)buf, TEXT("xpos is %d, ypos is %d"), xPos, yPos);
MessageBox(hwnd, (LPWSTR)buf, TEXT("itcast"), MB_OK);
break;
}
case WM_KEYDOWN: //键盘
MessageBox(hwnd, TEXT("键盘按下"), TEXT("itcast"), MB_OK);
break;
case WM_PAINT: //绘图
{
//绘图结构体
PAINTSTRUCT paint_struct;
//开始绘图
HDC hdc = BeginPaint(hwnd, &paint_struct);
//文字绘图
TextOut(hdc, 100, 100, TEXT("hello meizi"), strlen("hello meizi"));
//结束绘图
EndPaint(hwnd, &paint_struct);
break;
}
default:
break;
}
//返回值使用默认处理方式
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}