初学MFC,窗口实现的底层步骤

b站中学习MFC的记录

当Windows操作系统启动一个程序时,它调用的就是该程序的WinMain 函数(实际是由插入到可执行文件中的启动代码调用的)。
WinMain是Windows程序的入口点函数,与DOS程序的入口点函数main的作用相同,当WinMain函数结束或返回时,Windows应用程序结束。

在这里插入图片描述

  1. 底层实现窗口
    1.2 sdk api 句柄
    1.2 消息处理机制
    1.3 头文件 windows.h
    1.4 程序入口 winMain
  2. 具体6个步骤
    2.1 设计窗口WNDCLASS WC
    2.2 注册窗口 RegisterClass
    2.3 创建窗口 createWindow.
    2.4 显示和更新 showWindow updateWindow
    2.5 通过循环职演息MSG msg
     2.5.1写循环while(1)
     2.5.2 setMessage==false 退出循环
     2.5.3 翻译消息
     2.5.4 分发消息
    2.6窗口过程

窗口过程函数
成员变量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 <Windows.h>

//处理窗口函数
//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;

}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值