MFC底层窗口实现(二)
具体前五个步骤的实现
#include <windows.h> //底层实现窗口的头文件
//程序入口函数
//WINAPI 代表了__stdcall 参数的传递顺序,从右到左依次入栈,并且在函数返回前清空堆栈
int WINAPI WinMain(
HINSTANCE hInstance, //应用程序实例句柄
HINSTANCE hPrevInstance, //上一个程序的句柄,在win32环境下,参数一般为NULL,不起作用了
LPSTR lpCmdLine, //char * argv[]
int nShowCmd) //显示命令 ------ 最大化、最小化、正常
{
//1、设计窗口
//2、注册窗口
//3、创建3窗口
//4、显示和更新
//5、通过循环取消息 MSG msg
//5.1 写循环 while(1)
//5.2 GetMessage == false 退出循环
//5.3 翻译消息
//5.4 分发消息
//6、处理消息-----窗口过程
//6.1 LRESULT CALLBACK WindowProc
//6.2 返回默认值处理----return DefWindowProc(hwnd, uMsg, wParam, lParam);
//6.3 点击叉子 WM_CLOSE: DestroyWindow(hwnd)
//6.4 WM_DESTROY PostQuitMessage(0);
//6.5 鼠标的左键按下
//6.6 键盘的按下
//6.7 绘图 文字 ---- HELLO
//1、设计窗口
WNDCLASS wc;
wc.cbClsExtra = 0; //类的额外的内存;若不需要,则设置为0;
wc.cbWndExtra = 0; //窗口的额外的内存
wc.hbrBackground =(HBRUSH) GetStockObject(WHITE_BRUSH);//设置背景----用系统提供的api----GetStockObject
wc.hCursor = LoadCursor(NULL, IDC_HAND); //设置光标---用LoadCursor;如果第一个参数为NULL,代表使用系统默认的光标
wc.hIcon = LoadIcon(NULL, IDI_ERROR);//设置图标;如果第一个参数为NULL,代表使用系统默认的光标
wc.hInstance = hInstance; //应用程序的实例句柄,传入winmain中的形参即可
//wc.lpfnWndProc = WindowsProc;//窗口过程函数-----回调函数,名称随意写;第六步定义,函数名称写WindowsProc即可
wc.lpszClassName = TEXT("WIN"); //指定窗口的类名称----自定义,用字符串包起来
wc.lpszMenuName = NULL;//菜单名称-----若不想提供菜单,设置为空即可
wc.style = 0;//显示风格----0代表默认风格
//2、注册窗口------使用RegisterClass函数
RegisterClass(&wc);
//3、创建窗口
/*
lpClassName, 类名
lpWindowName, 窗口标题名
dwStyle, 选择风格,常用混合风格WS_OVERLAPPEDWINDOW
x, 显示坐标 使用默认值CW_USEDEFAULT
y,
nWidth, 宽,高 使用默认值CW_USEDEFAULT
nHeight,
hWndParent, 父窗口,若无,设为NULL
hMenu, 菜单,若无,设为NULL
hInstance, 实例句柄 hInstance
lpParam 鼠标附加值 若无,设为NULL
*/
HWND hwnd = (wc.lpszClassName, TEXT("WINDOW"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
//4、显示和更新
ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);
//5、通过循环取消息
/*
HWND hwnd; 主窗口句柄
UINT message; 具体的消息名称
WPARAM wParam; 附加消息(键盘)
LPARAM lParam; 附加消息(鼠标左右键)
DWORD time; 消息产生的时间
POINT pt; 附加消息(鼠标x,y坐标)
*/
MSG msg;
while (1)
{
/*
LPMSG lpMsg, //封装好的消息----msg;一般带p的是指针
HWND hWnd, //捕获的窗口,填NULL代表捕获所有的窗口
UINT wMsgFilterMin, //最小和最大的过滤消息,一般填0
UINT wMsgFilterMax //填0代表捕获所有的消息
*/
if (GetMessage(&msg,NULL,0,0) == FALSE)
{
break;
}
//分发前翻译消息-----翻译组合键
TranslateMessage(&msg);
//分发消息
DispatchMessage(&msg);
}
//6、
return 0;
}
其中有一些函数的定义需要借助msdn帮助文档
//6、处理消息-----窗口过程
//CALLBACK 参数的传递顺序,从右到左依次入栈,并且在函数返回前清空堆栈
LRESULT CALLBACK WindowProc(
HWND hwnd, // handle to window 消息所属的窗口句柄
UINT uMsg, // message identifier 具体的消息名称 WM_xxxxx消息名
WPARAM wParam, // first message parameter 键盘附加消息
LPARAM lParam // second message parameter 鼠标附加消息
)
{
switch (uMsg)
{
//所有以xxxWindow为结尾的方法都不会进入到消息队列,而是直接执行这个方法。
//这就是WM_CLOSE窗口关闭了,还可以进行下一步分发消息的原因
case WM_CLOSE:
DestroyWindow(hwnd); //DestroyWindow发送另一个消息 WM_DESTROY
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN: //鼠标左键按下
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
char buff[1024];
wsprintf(buff,TEXT("x = %d,y = %d"), xPos, yPos);
MessageBox(hwnd, buff, TEXT("鼠标左键按下"), MB_OK);
break;
}
case WM_KEYDOWN: //键盘
MessageBox(hwnd, TEXT ("键盘按下"), TEXT("键盘按下"), MB_OK);
break;
case WM_PAINT: //绘图
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 100, 100, TEXT("hello"), strlen("hello"));
EndPaint(hwnd, &ps);
break;
}
}
//返回值用默认的处理方式
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
以上就是MFC创建底层窗口的过程,希望对您有帮助。