b站中学习MFC的记录
当Windows操作系统启动一个程序时,它调用的就是该程序的WinMain 函数(实际是由插入到可执行文件中的启动代码调用的)。
WinMain是Windows程序的入口点函数,与DOS程序的入口点函数main的作用相同,当WinMain函数结束或返回时,Windows应用程序结束。
窗口过程函数
成员变量lpfnWndProc指定了这一类型窗口的过程函数,也称回调函数。回调函数的原理是这样的,当应用程序收到给某一窗口的消息时,就应该调用某一函数来处理这条消息。这一调用过程不用应用程序自己来实施,而由操作系统来完成,但是,回调函数本身的代码必须由应用程序自己完成。对于一条消息,操作系统到底调用应用程序中的哪个函数(回调函数)来处理呢?操作系统调用的就是接受消息的窗口所属的类型中的lpfnWndProc成员指定的函数。每一种不同类型的窗口都有自己专用的回调函数,该函数就是通过lpfnWndProc成员指定的。
2.6.1 LRESULT CALLBACT WindowPros
2.6.2 返回默认处理
2.6.3 return DeWindowProc(hwmd,ullsg,yParam,lParam);
2.6.4 点击关闭 WM_CLOSE destroy
2.6.5 WM_DESTROY postQutMessage(0)
2.6.6 鼠标左键按下
2.6.7 键盘按下
2.6.8 绘图
#include
//处理窗口函数
//CALLBACK 代表_stdcall参数的传递顺序,从右到左以此入栈,并且在函数返回前清空堆栈
LRESULT CALLBACK WindowProc(
HWND hwnd, //消息所属的窗口句柄
UINT uMsg, //具体消息名称,WH_XXX 消息名
WPARAM wParam,//键盘附加消息
LPARAM lParam //鼠标附加消息
)
{
switch (uMsg)
{
//所有xxxWindow为结尾的方法,都不会进入到消息队列中,而是直接执行
case WM_CLOSE: //关闭窗口
DestroyWindow(hwnd); //DstroyWindow 发送另一个消息 WM_DESTROY
break;
case WM_DESTROY: //退出程序
PostQuitMessage(0);
return 0;
case WM_LBUTTONDOWN: //鼠标左键按下
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
WCHAR 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("THE WINDOW"), strlen("THE WINDOW"));
EndPaint(hwnd, &ps);
break;
}
}
//返回值用默认处理方式
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
//程序入口函数
//WINAPI 代表_stdcall参数的传递顺序,从右到左以此入栈,并且在函数返回前清空堆栈
int WINAPI WinMain(
HINSTANCE hInstance, //应用程序实例句柄
HINSTANCE hPrevInstance,//上一个应用程序句柄,在win32环境下,参数一般为NULL,不起作用了
LPSTR lpCmdLine, //char *argv[]
int nShowCmd //显示命令 最大化、最小化、正常
)
{ //设计窗口
WNDCLASS wc;
wc.cbClsExtra = 0; //类额外的内存
wc.cbWndExtra = 0; //窗口额外的内存
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置背景
wc.hCursor = LoadCursor(NULL, IDC_HAND); //设置光标,如果第一个参数为ULL,代表使用系统提供的光标
wc.hIcon = LoadIcon(NULL, IDI_ERROR); //图标,如果第一个参数为NULL,代表使用系统提供的图标
wc.hInstance = hInstance; //应用程序实例句柄传入WinMain中的形参即可
wc.lpfnWndProc = WindowProc; //回调函数,窗口过程,上面有详细解释
wc.lpszClassName = TEXT("Firet_WIN"); //指定窗口类名称
wc.lpszMenuName = NULL; //菜单名称
wc.style = 0; //显示风格,0代表默认风格
//注册窗口类
RegisterClass(&wc);
//创建窗口
/*参数
lpClassName, 类名
lpWindowName, 标题名
dwStyle, WS_OVERLAPPEDWINDOW 混合风格
x, 显示坐标 CW_USEDEFAULT 默认值
y,
nWidth, 宽高
nHeight,
hWndParent, 父窗口 NULL
hMenu, 菜单 NULL
hInstance, 实例句柄 hInstance
lpParam 附加值,如鼠标 NULL
*/
HWND hwnd = CreateWindow(wc.lpszClassName,TEXT("First_WINDOW"),
WS_OVERLAPPEDWINDOW ,
CW_USEDEFAULT,CW_USEDEFAULT,
CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL);
//显示和更新
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
//通过循环取消息
/*
HWND hwnd; 主窗口句柄
UINT message; 具体消息名称
WPARAM wParam; 附加消息,键盘消息
LPARAM lParam; 附加消息,鼠标消息
DWORD time; 消息产生时间,操作系统决定
POINT pt; 附加信息,鼠标点位置
*/
MSG msg;
/*
__out LPMSG lpMsg, 消息
__in_opt HWND hWnd, 捕获窗口,填NULL代表捕获所有的窗口
__in UINT wMsgFilterMin, 最小和最大的过滤信息,一般0
__in UINT wMsgFilterMax 填0代表捕获所有消息
*/
while(true){
if (GetMessage(&msg,NULL,0,0) == FALSE){
break;
}
//翻译消息
TranslateMessage(&msg);
//不为false,分发消息
DispatchMessage(&msg);
}
return 0;
}