创建.c文件,包含头文件#include < windows.h >
程序入口函数
//WINAPI 代表__stdcall 参数的传递顺序,从右到左入栈,函数返回前清空栈
int WINAPI WinMain(
HINSTANCE hInstance,//应用程序实例句柄
HINSTANCE hPrevInstance,//上一个应用程序实例句柄,现在在win32环境一般为NULL,不使用
LPSTR lpCmdLine,//char* argv[]
int nShowCmd)//窗口如何显示,显示命令,最大化、最小化、正常
{
return 0;
}
以下所有步骤都放在WinMain函数里面,这里分开是为了清晰描述
第一步、设计窗口
WNDCLASSA wc;
wc.cbClsExtra=0;//类的额外内存
wc.cbWndExtra=0;//命令额外内存
wc.hbrBackground=(HBUSH)GetStockObject(WHITE_BRUSH);//GetStockObjec函数是获取常用笔刷,图标等的句柄
wc.hCursor=LoadCursorA(NULL,IDC_HAND);//第一个参数为NULL时,使用的是系统预设的光标
wc.hIcon=LoadIcon(NULL,IDI_ERROR);//第一个参数为NULL时,使用的是系统预设的图标
wc.hInstance=hInstance;//应用程序实例句柄,传入WinMain里的形参即可
wc.lpfnWndProc=WindowProc;//回调函数,窗口过程
wc.lpszClassName=TEXT("WIN");//指定窗口名称
wc.lpszMenuName=NULL;//菜单名称
wc.style=0;//显示风格,0代表默认风格
第二步、注册窗口
RegisterClassA(&wc);
第三步、创建窗口
/*
lpClassName, 类名
lpWindowName, 标题名
dwStyle, 风格 WS_OVERLAPPEDWINDOW
x, 显示坐标 CW_USEDEFAULT默认值
y,
nWidth, 宽高 CW_USEDEFAULT默认值
nHeight,
hWndParent, 父窗口 NULL
hMenu, 菜单 NULL
hInstance, 实例句柄 hInstance
lpParam 附加值 NULL
*/
HWND bwnd = CreateWindowA(wc.lpszClassName,TEXT("WINDOWS"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT
CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
第四步、显示和更新
ShowWindow(bwnd,SW_SHOWNORMAL);//第一个参数是创建窗口的句柄,第二个参数是显示类型
UpdateWindow(bwnd);
第五步、循环获取消息
/*
HWND hwnd;主窗口句柄
UINT message;具体消息名称
WPARAM wParam;附加消息,键盘消息
LPARAM lParam;附加消息,鼠标消息(判断鼠标左右键)
DWORD time;消息产生时间
POINT pt;附加消息,鼠标消息(鼠标点击位置的坐标)
DWORD lPrivate;
*/
MSG msg;
/*
LPMSG lpMsg, 消息指针
HWND hWnd,需要捕获消息的窗口,NULL代表捕获所有窗口
UINT wMsgFilterMin,最小和最大过滤消息,一般写0
UINT wMsgFilterMax写0代表捕获所有消息
*/
while(1){
if(GetMessage(&msg,NULL,0,0)==FALSE)
{break;}
//翻译消息 ,判断消息是否需要翻译,需要翻译的消息翻译好再进入消息队列等待,不需要则直接被发给操作系统
TranslateMessage(&msg);
//分发消息,应用程序再分发给操作系统
DispatchMessage(&msg);
}
第六步
//CALLBACK 代表__stdcall 参数的传递顺序,从右到左入栈,函数返回前清空栈
//返回值LRESULT :信息处理结果
LRESULT CALLBACK WindowProc(
HWND hwnd ,//消息所处的窗口句柄
UINT uMsg,//具体消息名称 WM_XXXX消息名
WPARAM wParam,//键盘附加消息
LPARAM lParam//鼠标附加消息){
case(uMsg)
{
case WM_CLOSE:
//所有xxxWindow(以Window结尾)的方法都不会进入消息队列而是直接执行
DestoryWindow(hwnd);//发送WM_DESTORY信息
break;
case WM_DESTORY:
PostQuitMessage(0);//发送退出消息,然后应用程序接收消息返回假,退出while循环,程序就退出了
break;
case WM_LBUTTONDOWN:
{
int xPos = LDWORD(lParam);
int yPos = RDWORD(lParam);
char buf[1024];
wsprintf(buf,TEXT("x = %d,y = %d"),xPos,yPos);
MessageBox(hwnd,buf,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窗口,包括程序入口函数、窗口设计、注册、创建、显示更新以及循环获取消息的步骤,适合C++和Windows开发人员参考。
&spm=1001.2101.3001.5002&articleId=124672201&d=1&t=3&u=60498bc59c554908b3d52ebf6e52b846)
702

被折叠的 条评论
为什么被折叠?



