一、MFC入门

学习MFC主要学习MFC框架的设计思想。

1、Windows消息机制

1.1基本概念

1)SDK和API

SDK:软件开发工具包(SoftWare Development Kit),一般都是被一些软件工程师用于特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具集合。
API函数:Windows操作系统提供给应用程序编程的接口(Application Programming Interface)。

2)窗口和句柄

窗口:窗口是Windows应用程序中一个重要的元素,一个Windows应用程序至少要有一个窗口,称为主窗口。窗口可以有一个父窗口,有父窗口的窗口称为子窗口。
句柄(HANDLE):窗口是通过句柄(HWND)来标识的,我们要对某个窗口进行操作,就要得到这个窗口的句柄。在Windows程序中,有各种各样的资源(窗口、图标、光标、画刷等),系统在创建这些资源时,为他们分配内存,并返回标识这些资源的标识号,即句柄。在后面的内容我们还会看到,图标句柄(HICON),光标句柄(HCURSOR),画刷句柄(HBRUSH)。

3)消息与消息队列

Windows程序设计是一种事件驱动方式的程序设计模式,主要是基于消息的。每一个WIndows应用程序开始执行后,系统都会为该程序创建一个消息队列,这个消息队列用来存放程序创建窗口的消息。
在这里插入图片描述
窗口过程:专门负责处理消息的函数

4)WinMain函数

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

1.2Windows编程模型

  • WinMain函数的定义
  • 创建一个窗口
  • 进行消息循环
  • 编写窗口过程函数

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

#include <windows.h>
//处理消息(窗口过程)
LRESULT CALLBACK WindowProc(
	HWND hwnd,
	UINT uMsg,      //具体消息名称  WM——XXX
	WPARAM wParam,  //鼠标附加消息
	LPARAM lParam   //键盘附加消息
)
{
	switch(uMsg)
	{
		case WM_CLOSE:
			//所有以Window结尾的消息不会进入消息队列
			DestroyWindow(hwnd);
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		case WM_LBUTTONDOWN:
		{
			int xPos = LOWORD(lParam);
			int yPos = HOWORD(lParam);
			wsprinf(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(hwnd,100,100,TEXT("HELLO"),strlen("HELLO"));
			EndPaint(hwnd,&ps);
			break;
		}
	}
}
int WINAPI WinMain(
	HINSTANCE hInstace,   //应用程序实例句柄
	HINSTANCE hPrevInstance,  //上一个应用程序句柄,在为win32环境下,参数一般为NULL,不起作用
	LPSTR lpCmdLine,  //命令行的参数,char *argv[]
	int nShowCmd)  //显示命令,最大化,最小化,正常
{
//设计窗口
//注册窗口
//创建窗口
//显示和更新
//通过循环取消息
//处理消息(窗口程序)
//处理消息(窗口过程)

//设计窗口
//WNDCLASS是Windows类的一个缩写
WNDCLASS wc;
wc.cbClsExtra = 0; //类的额外的内存
wc.cbWndExtra = 0; //窗口额外的内存
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置背景
wc.hCursor = LoadCursor(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表示默认风格
}

//注册窗口
RegisterClass(&wc);
//创建窗口
/*
lpClassName, 类名
lpWindowName,标题名
dwStyle, WS_OVERLAPPEDWINDOW 风格
x,显示坐标  CW_USEDDEFAULT 默认值
y,显示坐标  CW_USEDDEFAULT 默认值
nWidth,宽
nHeight,高
hWndParent,父窗口
hMenu, 菜单 NULL
hInstance, 实例句
lpParam 附加值NULL
*/
CreateWindow(wc.lpClassName,TEXT("WINDOWS"),WS_OVERLAPPEDWINDOW,CW_USEDDEFAULT,CW_USEDDEFAULT,CW_USEDDEFAULT,CW_USEDDEFAULT,NULL,NULL,hInstance,NULL);

//显示和更新
ShowWindow(hwnd,SW_SHOWNORMAL);
UpadateWindow(hwnd);
//通过循环取消息
while(1)
{
	if(GetMessage(&msg,NULL,0,0)==FALSE)
	{
		break;
	}
	//不为false
	//翻译消息
	TranslateMessage(&msg);
	//分发消息
	DispatchMessage(&msg);
}

1.3MFC入门

消息映射:消息映射是一个将消息和成员函数互相关联的表,比如框架窗口接受到一个鼠标左击的消息,MFC将搜索该窗口的消息映射,如果存在一个WM——LBUTTONDOWN消息的处理程序,然后调用OnLButtonDown。
在这里插入图片描述

1.3.1 消息映射
  • 消息映射机制: 声明宏:.h
  • 分界宏:.cpp
  • 找消息宏:写到分界宏中
  • 把函数原型声明写到.h中
  • 函数的实现写道.cpp中
//mfc.h
class MyFrame:public CFrameWnd
{
	public:
		MyFrame();
		//声明宏 提供消息映射机制
		DECLARE_MESSAGE_MAP()
		//鼠标左击处理函数声明
		afx_msg OnLButtonDown(UINT,CPoint);
}
//mfc.cpp
//定义消息宏,必须在类中实现
//分解宏
BEGIN_MESSAGE_MAP(MyFrame,CFrameWnd)
	ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

MyFrame::MyFrame()
{
	Create(NULL,TEXT("mfc")); //创建窗口
}

void MyFrame::OnLButonDown(UINT,CPoint ponit)
{
	TCHAR buf[1024];
	wsprintf(buf,TEXT("x=%d,y=%d"),point.x,point.y);
	MessageBox(TEXT("鼠标左键"));
	//mfc中的中的字符串 CString
	CString str;
	str.Format(TEXT("x=%d,,,,y=%d"),point.x,point.y);
	MessageBox(str);
}
1.3.2 Windows字符集
//宽字节 Unicode 一个字符对应多个字节
//utf-8 对应3个  GBK 对应2个

//多字节转换为宽字节
MessageBox(L"aaa");
//TEXT是自适应编码的转换
//TCHAR是自适应编码的转换

//统计字符串长度
int num=0;
char *p = "aaaaa";
num = strlen(p);

//宽字节声明
//统计宽字节字符串长度
wchar_t *p2 = L"bbbb";
num = wcslen(p2);

//char * 与 CString之间的转换

//char * -> CString 
char *p3 = "ccc";
CString str = CString(p3);

//CString -> char *
CStringA temp;
temp = str;
char * pp = temp.GetBuffer();

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐