MFC基本使用[转]

MFC基本使用[转]

目录

MFC基本使用[转]

消息映射

帮助文档的使用

Widnows字符集

用向导生成一个MFC应用程序

MFC框架中一些重要的函数

补充说明:

示例

  • 编写MFC程序需要包含#include <afxwin.h>头文件

  •  配置环境后,代码才可编译运行:

 

  • 程序执行流程
    • ①程序开始时,先实例化应用程序对象(有且只有一个)
    • ②执行程序的入口函数InitInstance()
    • ③给框架类MyFrame对象动态分配空间(自动调用它的构造函数),在其构造函数内部,通过CWnd::Create创建窗口
    • ④框架类对象显示窗口CWnd::ShowWindow
    • ⑤框架类对象更新窗口CWnd::UpdateWindow
    • ⑥保存框架类对象指针CWinThread::m_pMainWnd
  • CFrameWnd 框架窗口类
    • CFrameWnd是从CWnd(窗口基类)派生出来的。CFrameWnd模仿框架窗口行为,我们可以把框架窗口作为顶层窗口看待,它是应用程序与外部世界的主要接口。
  • CWinApp应用程序类
    • MFC应用程序的核心就是基于CWinApp类的应用程序对象。CWinApp提供了消息循环来检索消息并将消息调度给应用程序窗口。它还包括可被覆盖的、用来自定义应用程序行为的主要虚函数。
    • 一个MFC程序可以有且仅有一个应用程序对象,此对象必须声明为在全局范围内有效,以便它在程序开始时即在内存中被实例化。
  • InitInstance函数
    • InitInstance的目的是给应用程序提供一个自身初始化的机会,其返回值决定了框架接下来要执行的内容,如果返回FALSE将关闭应用程序,如果初始化正常返回TRUE以便允许程序继续进行。此函数是MFC应用程序的入口。
  • m_pMainWnd 成员变量
    • 在CWinApp中有一个名为CWinThread::m_pMainWnd的成员变量。 该变量是一个CWnd类型的指针,它保存了应用程序框架窗口对象的指针。也就是说,是指向CFramWnd对象(框架窗口类对象)的指针。

消息映射

  • 消息映射是一个将消息和成员函数相互关联的表。
    • 比如,框架窗口接收到一个鼠标左击消息,MFC将搜索该窗口的消息映射,如果存在一个处理WM_LBUTTONDOWN消息的处理程序,然后就调用OnLButtonDown。
  • 下面是是将消息映射添加到一个类中所做的全部工作:
    • 所操作类中,声明消息映射宏。
    • 通过放置标识消息的宏来执行消息映射,相应的类将在对BEGIN_MESSAGE_MAP和END_MESSAGE_MAP的调用之间处理消息。

  •  对应消息处理函数分别在类中声明,类外定义:

帮助文档的使用

  • MSDN的使用

 

  • VC++之MFC类库中文手册 
    • 通过此手册查找,必须加上成员所属的类作用域(类名::),否则,无法查找到匹配的关键字。

 

Widnows字符集

  •  多字节字符集(8位的ANSI字符集)
    • 在Windows98以及以前的版本使用8位ANSI字符集,它类似于我们程序员熟悉的ASCII字符集。
char sz[] = "ABCDEFG";
char *psz = "ABCDEFG";
int len = strlen(sz);
  • 宽字符集(16位的Unicode字符集)
    • 在WindowsNT和Windows2000后开始使用16位的Unicode字符集,它是ANSI字符集的一个超集
    • Unicode适用于国际市场销售的应用程序,因为它包含各种各样来自非U.S.字母表的字符,比如中文,日文,韩文,西欧语言等。
//在字符串前加字母L表示将ANSI字符集转换成Unicode字符集。
wchar_t wsz[] = L"ABCDEFG"; 
wchar_t *pwsz = L"ABCDEFG";
int len = wcslen(wsz); //测试宽字节字符串的长度
  • TEXT(_T)宏
    • MFC中的TEXT宏可以自动适应字符类型,如果定义了预处理器程序符号_UNICODE,那么编译器将使用Unicode字符,如果没用定义该预处理器程序符号,那么编译器将使用ANSI字符。
MessageBox(TEXT("鼠标左键"));
MessageBox(_T("鼠标左键"));
  • CHAR类型
    • 如果定义了_UNICODE符号TCHAR将变为wchar_t类型。
    • 如果没用定义_UNICODE符号,TCHAR将变为普通古老的char类型。

用向导生成一个MFC应用程序

  • 在VS中选择“文件” -- “新建” -- “项目”:

  • 一路按默认值next,到最后一个页面: 

 

  •  MFC自动为我们生成了四个类,它们的继承关系如下:

 

类视图

 

 

文档/视图结构体系

  •  数据的存储和加载由文档类来完成,数据的显示和修改则由视图类来完成。
    • MFC在类CDocument和CView中为稳定视图提供了基础结构。CWinApp、CFrameWnd和其他类与CDocument和CView合作,把所有的片段连在了一起。
  •  CView类也派生于CWnd类,框架窗口是视图窗口的一个父窗口。(可以理解为相框和相片)
  • 主框架窗口(CFrameWnd)是整个应用程序外框所包括的部分,即图中粗框以内的内容,而视类窗口只是主框架中空白的地方。

  消息处理的添加

  •  在主框架类中添加WM_LBUTTONDOWN消息的响应函数,具体操作如下:

  •  从类视图中找到CMainFrame(继承自CFrameWnd),选择此类然后从属性面板中找到消息按钮,在消息列表中找到WM_LBUTTONDOWN消息,添加。
  • 工程文件增加几处改变
    • 第一处:在框架类头文件中添加了鼠标左键消息函数的函数声明

  • 第二处:在框架类cpp文件中添加了消息映射宏

 

  •  第三处:在框架列cpp文件中添加了处理鼠标左键消息的函数定义

 

  • 我们再此OnLButtonDown函数中添加一个MessageBox消息,鼠标左键按下弹出一个提示框,然后执行程序。我们会惊奇的发现程序并未如我们所愿弹出消息框。
  • 因为,框架窗口是视窗口的父窗口,那么视类窗口就应该始终覆盖在框架类窗口之上。
    • 就好比框架窗口是一面墙,视类窗口就是墙纸,它始终挡在这面墙前边。也就是说,所有操作,包括鼠标单击、鼠标移动等操作都只能有视类窗口捕获。

MFC框架中一些重要的函数

InitInstance函数

 

  •  应用程序类的一个虚函数,MFC应用程序的入口。

PreCreateWindow函数

  • 当框架调用CreateEx函数创建窗口时,会首先调用PreCreateWindow函数。
  • 通过修改传递给PreCreateWindow的结构体类型参数CREATESTRUCT,应用程序可以更改用于创建窗口的属性。在产生窗口之前让程序员有机会修改窗口的外观。
  • 最后再调用CreateWindowEx函数完成窗口的创建。

OnCreate函数

  •  OnCreate是一个消息响应函数,是响应WM_CREATE消息的一个函数,而WM_CREATE消息是由Create函数调用的。
    • 一个窗口创建(Create)之后,会向操作系统发送WM_CREATE消息,OnCreate()函数主要是用来响应此消息的。
  • OnCreate与Create的区别:
    • Create()负责注册并产生窗口,像动态创建控件中的Create()一样,窗口创建之后会向操作系统发送WM_CREATE消息。
    • OnCreate()不产生窗口,只是在窗口显示前设置窗口的属性如风格、位置等。
    • OnCreate()是消息WM_CREATE的消息响应函数。 

OnDraw和OnPaint

  • OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中。
    • OnPaint()是CWnd的类成员,负责响应WM_PAINT消息。
    • OnDraw()是CView的成员函数,没有响应消息的功能。
  • 当视图变得无效时(包括大小的改变,移动,被遮盖等等),Windows发送WM_PAINT消息。
    • 该视图的OnPaint 处理函数通过创建CPaintDC类的DC对象来响应该消息并调用视图的OnDraw成员函数。
    • OnPaint最后也要调用OnDraw,因此一般在OnDraw函数中进行绘制。
  • 通常我们不必编写OnPaint处理函数。
    • 当在View类里添加了消息处理OnPaint()时,OnPaint()就会覆盖掉OnDraw()。 

补充说明:

  • MFC中后缀名为Ex的函数都是扩展函数
  • 在MFC中,以Afx为前缀的函数都是全局函数,可以在程序的任何地方调用它们

示例

  • mfc.h
#include <afxwin.h> //mfc头文件

class MyApp:public CWinApp //CWinApp应用程序类
{
public:
	//程序入口
	virtual BOOL InitInstance();

};


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

	//声明宏 提供消息映射机制
	DECLARE_MESSAGE_MAP()

	afx_msg void OnLButtonDown(UINT, CPoint);

	afx_msg void OnChar(UINT, UINT, UINT);

	afx_msg void OnPaint();
};
  • mfc.cpp
#include "mfc.h"

MyApp app; //全局应用程序对象,有且仅有一个

BOOL MyApp::InitInstance()
{
	//创建窗口
	MyFrame * frame = new MyFrame;

	//显示和更新
	frame->ShowWindow(SW_SHOWNORMAL);
	frame->UpdateWindow();

	m_pMainWnd = frame; //保存指向应用程序的主窗口的指针

	return TRUE; //返回正常初始化

}

//分界宏
BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd)

	ON_WM_LBUTTONDOWN() //鼠标左键按下

	ON_WM_CHAR() //键盘

	ON_WM_PAINT() //绘图宏

END_MESSAGE_MAP()


MyFrame::MyFrame()
{
	Create(NULL, TEXT("mfc"));
}

void MyFrame::OnLButtonDown(UINT, CPoint point)
{

	/*TCHAR buf[1024];
	wsprintf(buf, TEXT("x = %d, y =%d"), point.x, point.y);

	MessageBox(buf);*/

	//mfc中的字符串  CString

	CString str;
	str.Format(TEXT("x = %d ,,,, y = %d "), point.x, point.y);

	MessageBox(str);

}

void MyFrame::OnChar(UINT key, UINT, UINT)
{

	CString str;
	str.Format(TEXT("按下了%c 键"), key);

	MessageBox(str);

}

void MyFrame::OnPaint()
{
	CPaintDC dc(this);  //CDC里找其他的能画的图形 

	dc.TextOutW(100, 100, TEXT("为了部落"));
	//画椭圆
	dc.Ellipse(10, 10, 100, 100);

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

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

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

	//char * 与 CString之间的转换   C++  string  .c_str();
	//char* -> CString
	char * p3 = "ccc";
	CString str = CString(p3);
	//CString  -> char *
	CStringA tmp;
	tmp = str;
	char * pp = tmp.GetBuffer();
}


//老外 1个字符对应1个字节 多字节
// 中文  1个字符对应多个字节  宽字节  Unicode   utf-8 3个  GBK 2个

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值