欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

01_MFC入门基础知识

程序员文章站 2022-06-11 22:08:25
...

一、基础概念

SDK:软件开发工具包,特定的软件包软件框架硬件平台、操作系统等建立应用软件时的开发工具的集合;一般而言SDK即开发 Windows 平台下的应用程序所使用的 SDK。

JDK:java开发工具包

IDE:集成开发环境IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器调试器和图形用户界面等工具。这里学习MFC,我采用的是vs2013.

API:应用程序接口

WINAPI:windows平台下的系统资源调用,头文件"windows.h",调用系统提供的特殊接口,得到系统的资源。

窗口:父窗口和子窗口,客户区和非客户区。

句柄:结构体变量,窗口句柄HWND,图标句柄:HICO

消息队列
消息
窗口过程函数
 

一般c/c++或其它编程语言程序都是从main()函数开始执行,而WINAPI的入口地址是WinMain().

二、winAPI窗口程序

1、定义入口函数WinMain()

2、创建一个窗口

              a)设计窗口类WNDCLASS(给成员变量赋值)
              b)注册窗口类
              c)创建窗口类
              d)显示和更新窗口

3、消息循环

4、窗口过程函数(回调函数)

下面是一个win32项目:winapi创建窗口(注意vs创建win32空项目,然后再window.cz中添加如下代码)

/* windows.c */

#include "windows.h" //窗口程序的头文件

/*
WINAPI:修饰函数,规定函数参数入栈从右到左,函数调用(CALLBACK)完毕,自动清理堆栈

winAPI窗口程序
	1、定义入口函数WinMain()
	2、创建一个窗口
		a)设计窗口类WNDCLASS(给成员变量赋值)
		b)注册窗口类
		c)创建窗口类
		d)显示和更新窗口
	3、消息循环
	4、窗口过程函数
*/

/* 4、窗口过程函数 */
LRESULT CALLBACK DealMessage(
	HWND   hWnd,      //窗口句柄,消息所属的窗口
	UINT   uMsg,      //消息标志
	WPARAM wParam,    //附加消息
	LPARAM lParam     //附加消息
	)
{
	switch (uMsg)
	{
	case WM_LBUTTONDBLCLK://鼠标左键按下
		MessageBox(hWnd, TEXT("ABC"), TEXT("鼠标左键按下"), MB_OK);
		break;
	case WM_PAINT:
	{

					 PAINTSTRUCT ps;//绘图结构体
					 HDC dc = BeginPaint(hWnd, &ps);//开始
					 TCHAR* p = L"你好,世界!";//宽字节
					 TextOutW(dc, 30, 30, p, wcslen(p));

	}

	case WM_DESTROY:
		PostQuitMessage(2);//WM_QUIT,给主函数return msg.wParam
		break;
	default:
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}

/*1、定义入口函数WinMain()*/
int WINAPI WinMain(
	HINSTANCE hInstance,       //应用程序实例句柄 
	HINSTANCE hPrevInstance,   //上一个应用程序句柄,在win32环境下,参数一般为NULL,不用了
	LPSTR lpCmdLine,           //char * argv[] 命令行参数
	int nShowCmd)              //窗口样式:显示命令 最大化、最小化、正常
{
	
	/* 
	2、创建一个窗口 
		1.设计窗口
		2.注册窗口类
			a)设计窗口类WNDCLASS(给成员变量赋值)
			b)注册窗口类
			c)创建窗口类
			d)显示和更新窗口
		3.消息循环
		4.显示和更新
		5.通过循环取消息
		6.处理消息(窗口过程)
	*/

	/*  a)设计窗口类WNDCLASS(给成员变量赋值) */

	WNDCLASS wc; //窗口类

	/*类的附加信息*/
	wc.cbClsExtra = 0;//类的额外的内存
	wc.cbWndExtra = 0;//窗口的额外内存
	//获取系统默认的白色画刷
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//设置 背景,必须写

	//wc.hCursor = NULL;//使用系统默认
	wc.hCursor = LoadCursor(NULL, IDC_HELP);//加载系统默认光标
	wc.hIcon = LoadIcon(NULL, IDI_WARNING);//j加载系统默认图标 图标  如果第一个参数为NULL,代表使用系统提供的光标图标
	wc.hInstance = hInstance;//应用程序实例句柄 传入WinMain中的形参即可
	wc.lpfnWndProc = DealMessage; //窗口过程函数名字,消息处理函数      回调函数 窗口过程

	wc.lpszClassName = TEXT("abc");//指定窗口类名字
	wc.lpszMenuName = NULL;//菜单名字
	wc.style = nShowCmd;//显示风格  0代表默认风格SW_SHOWNORMAL

	/* b)注册窗口类 */
	RegisterClass(&wc);

	/* c)创建窗口类 */
	/*
	lpClassName,  类名
	lpWindowName, 窗口标题名
	dwStyle,  WS_OVERLAPPEDWINDOW 风格
	x,  显示坐标    CW_USEDEFAULT  默认值
	y,
	nWidth, 宽高
	nHeight,
	hWndParent,  父窗口 NULL
	hMenu,  菜单 NULL
	hInstance,  实例句柄 hInstance
	lpParam) 附加值 NULL
	*/
	HWND hWnd = CreateWindow(TEXT("abc"), TEXT("hello,windows"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

	/* d)显示和更新窗口 */
	ShowWindow(hWnd, SW_SHOWNORMAL);//SW_SHOWNORMAL表示正常显示  CWnd::ShowWindow

	/* 3、消息循环 */
	/*
	消息结构体
	typedef struct tagMSG {     // msg
	HWND hwnd;        主窗口句柄
	UINT message;     具体消息名称
	WPARAM wParam;    附加消息 键盘消息
	LPARAM lParam;    附加消息 鼠标消息
	DWORD time;       消息产生时间
	POINT pt;         附加消息  鼠标消息  x y
	} MSG;
	*/

	MSG msg;//创建消息
	//如果接受到VM_QUIT,返回0,退出
	//如果出错,返回-1,不退出
	while (GetMessage(&msg, hWnd, 0, 0))
	{
		//翻译工作
		//虚拟按键转为标准字符WM_CHAR
		TranslateMessage(&msg);
		//给操作系统分发消息
		DispatchMessage(&msg);
	}

	return 0;
}

三、一个MFC程序(纯代码)

      1)应用程序 CWinApp
      2)框架类   CFrameWnd

下面是一个MFC程序的总体结构:

#pragma once

#include "afxwin.h"
 
class MyApp:public CWinApp
{
public:
	//MFC程序的入口地址
	virtual BOOL InitInstance();
private:

};

class MyFrame:public CFrameWnd
{
public:
	MyFrame();
private:

};

1)有且只有一个全局的应用程序类对象

2)在程序入口函数实现功能 InitInstance()

      A)给框架类MyFrame对象动态分配空间(自动调用它的构造函数)

              a)框架类MyFrame对象构造函数函数里创建窗口 CWnd::Creat

      B)框架类对象显示窗口  CWnd::ShowWindow

       C)框架类对象更新窗口  CWnd::UpdateWindow

       D)保存框架类对象指针  CWinThread::m_pMainWnd

事件处理:

消息映射

1、所操作类中,声明消息映射宏

          DECLARE_MESSAGE_MAP()

2、对应的.cpp定义消息宏

           BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd) //派生类名,基类名

                      ON_WM_LBUTTONDOWN() //消息映射入口标志

                       ON_WM_PAINT()

             END_MESSAGE_MAP()

  3、对应类中,消息处理函数的声明

  4、对应.cpp 消息处理函数的定义

 void MyFrame::OnLButtonDown(UINT, CPoint)
    {
        //CWnd::MessageBox
        MessageBox(TEXT("鼠标左键"));
    }

    void MyFrame::OnPaint()
    {
        //QPainter p(this);
        //p.drawxxx();
        CPaintDC cdc(this);
        cdc.TextOutW(100, 100,TEXT("你好,mfc") );
    }

第一个MFC程序代码示例:

/*
	mfc.h
*/
#pragma once

#include "afxwin.h"

//1)应用程序 CWinApp,派生类(子类)
class MyApp :public CWinApp
{
public:
	//基类的虚函数
	//派生类只是重写
	//MFC程序的入口地址
	virtual BOOL InitInstance();

private:

};

//2)框架类   CFrameWnd
class MyFrame :public CFrameWnd
{
public:
	MyFrame();

	/* 消息处理 */
	//声明消息映射宏
	DECLARE_MESSAGE_MAP()

	/*  消息处理_消息处理函数的声明*/
	afx_msg void OnLButtonDown(UINT, CPoint);
	afx_msg void OnPaint();

private:

};

#include "mfc.h"

/* 1)有且只有一个全局的应用程序类对象 */
MyApp myApp;

/*  2)在程序入口函数实现功能 InitInstance()  程序的入口地址*/
BOOL MyApp::InitInstance()
{
	/*
	1、创建框架类对象
	2、显示窗口
	3、更新窗口
	4、保存框架类对象指针
	*/

	//1、创建框架类对象   CWnd::Create
	MyFrame *frame = new MyFrame;//构造函数

	//2、显示窗口  CWnd::ShowWindow
	frame->ShowWindow(SW_SHOWNORMAL);

	//3、更新窗口   CWnd::UpdateWindow
	frame->UpdateWindow();

	//4、保存框架类对象指针   CWinThread::m_pMainWnd
	m_pMainWnd = frame;
	return TRUE;
}

/* 消息处理_定义消息宏 */
BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd)
	ON_WM_LBUTTONDOWN()
	ON_WM_PAINT()
END_MESSAGE_MAP()

MyFrame::MyFrame()
{
	//CWnd类的成员函数 CWnd::Create
	//CFrameWnd 继承于 CWnd

	Create(NULL, TEXT("MFC"));

}

void MyFrame::OnLButtonDown(UINT, CPoint)
{
	//CWnd::MessageBox
	MessageBox(TEXT("鼠标左键"));
}

void MyFrame::OnPaint()
{
	//QPainter p(this);
	//p.drawxxx();
	CPaintDC cdc(this);
	cdc.TextOutW(100, 100, TEXT("你好,mfc"));
}

四、根据向导创建工程


1、文档视图结构

      文档:它是一个类,这个类专门来存储数据

      视图 :它是一个类,这个类专门来显示和修改数据

框架类:一个容器,这个容器装了视图

2、几个比较重要的函数

      应用程序类CWinApp:

      InitInstance(),程序的入口地址

       框架类CFrameWnd:

               PreCreateWindow()创建窗口之前调用

               OnCreate() 创建窗口后,触发WM_CREATE,它是WM_CREATE消息的处理函数

        视图类CView:

               OnDraw():绘图

                WM_PAINT消息处理函数OnPaint() 内部调用 OnDraw()    

                OnPaint() 和 OnDraw()同时存在,只有OnPaint()有效

3、事件的添加和删除

       a)框架和视图的区别

             选择所需类->右击->属性->消息->WM_LBUTTONDOWN->ADD

             框架类相当于容器,容器放视图

              视图相当于壁纸

五、字符集

ANSI 多字节,单字节

char p[]="acadad";//一个字符一个字节

unicode 宽字节,一个字符2个字节

TCHAR* p=L"ABC";//一个字符2个字节

MFC:

TCHAR:自动适应字节(条件编译)

TEXT()

_T()

六、拓展

afx_xxxx:全局成员函数,不属于某个类特有的

xxxEx:xxxW,拓展

MFC:

类名和函数名字:单词首字母大写

class MyClass
{
    
};

void SetName()
{
    
}

//形参

isFlage

isPressTest

//成员变量

m_xxx

m_hWnd