当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]MFC微软基础类库(英语:Microsoft FoundaTIon Classes,简称MFC)是微软公司提供的一个类库(class libraries),以C++类的形式封装了Windows API,并且包含一个应用程序框架

MFC

微软基础类库(英语:Microsoft FoundaTIon Classes,简称MFC)是微软公司提供的一个类库(class libraries),以C++类的形式封装了Windows API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。

MFC(MicrosoftFoundaTIonClasses)是微软基础类库的简称,是微软公司实现的一个c++类库,主要封装了大部分的windows API函数,vc++是微软公司开发的c/c++的集成开发环境,所谓集成开发环境,就是说利用它可以编辑,编译,调试,而不是使用多种工具轮换操作,灵活性较大。vc也指它的内部编译器,集成开发环境必须有一个编译器内核,例如DevC++其中一个编译器内核就是gcc。

MFC除了是一个类库以外,还是一个框架,在vc++里新建一个MFC的工程,开发环境会自动帮你产生许多文件,同时它使用了mfcxx.dll。xx是版本,它封装了mfc内核,所以你在你的代码看不到原本的SDK编程中的消息循环等等东西,因为MFC框架帮你封装好了,这样你就可以专心的考虑你程序的逻辑,而不是这些每次编程都要重复的东西,但是由于是通用框架,没有最好的针对性,当然也就丧失了一些灵活性和效率。但是MFC的封装很浅,所以效率上损失不大。

MFC初学教程

编写MFC程序,其实跟编写C++程序一样,在VS编译平台上新建项目,然后一直默认下一步就行,不过有其他需求则需要根据实际情况来添加。建好一个项目后,会出现两个界面,一个是显示窗口,一个是编程界面,类似LV中的前面板和程序框图。在界面右边有个工具箱,可以根据需要添加控件。

下面主要编写一个简单的计算器程序,实现对输入数的四则运算,主要步骤如下:

1、在对话框中放置6个按钮控件和3个编辑框控件

具体操作:界面右边点击工具箱,根据具体需要选择具体控件。

2、将3个编辑框控件分别添加float型变量m_edit1、m_edit2、m_edit3

具体操作:选中编辑框点右键添加变量,将右边类别改为value,变量名分别改为m_edit1、m_edit2、m_edit3。

3、将6个个按钮控件重新命名

具体操作:选中按钮点击右键属性,将CapTIon改为所需要+ - * / 清除 关闭,具体可根据需要来命名。

4、选择工具箱中Group Box将四则运算框住,然后通过属性改名字,同时在上方添加静态文本(StaTIc Text)来编辑命名。

界面主要部分完成,接下来就是编写代码,双击各个控件,就可自动跳转到程序编写部分,主要代码如下

[html] view plain copyvoid CMFC入门Dlg::OnBnClickedButton1()

{

// TODO: 在此添加控件通知处理程序代码

UpdateData(true);//从控件获得数据赋给变量

m_edit3 = m_edit1 + m_edit2;

UpdateData(false);//输出变量的值到控件

}

void CMFC入门Dlg::OnBnClickedButton2()

{

// TODO: 在此添加控件通知处理程序代码

UpdateData(true);

m_edit3 = m_edit1 - m_edit2;

UpdateData(false);

}

void CMFC入门Dlg::OnBnClickedButton3()

{

// TODO: 在此添加控件通知处理程序代码

UpdateData(true);

m_edit3 = m_edit1*m_edit2;

UpdateData(false);

}

void CMFC入门Dlg::OnBnClickedButton4()

{

// TODO: 在此添加控件通知处理程序代码

UpdateData(true);

if (m_edit2 == 0)

{

MessageBox(_T(“除数不能为0”));

return;

}

m_edit3 = m_edit1 / m_edit2;

UpdateData(false);

}

void CMFC入门Dlg::OnBnClickedButton7()

{

// TODO: 在此添加控件通知处理程序代码

m_edit1 = 0;

m_edit2 = 0;

m_edit3 = 0;

UpdateData(false);

GotoDlgCtrl((CEdit*)GetDlgItem(IDC_EDIT1));//设置焦点在第一个编辑框

}

最后编写完成,运行一下,弹出一个界面如下:

 


验证一下程序,以加法为例,m_edit1输入18,m_edit2输入36,得出结果如下所示。

 


mfc编程入门教程

1.MFC窗口类CWnd

在Windows系统里,一个窗口的属性分两个地方存放:一部分放在“窗口类”里头,如上所述的在注册窗口时指定;另一部分放在Windows Object本身,如:窗口的尺寸,窗口的位置(X,Y轴),窗口的Z轴顺序,窗口的状态(ACTIVE,MINIMIZED,MAXMIZED,RESTORED…),和其他窗口的关系(父窗口,子窗口…),窗口是否可以接收键盘或鼠标消息,等等。

为了表达所有这些窗口的共性,MFC设计了一个窗口基类CWnd。有一点非常重要,那就是CWnd提供了一个标准而通用的MFC窗口过程,MFC下所有的窗口都使用这个窗口过程。至于通用的窗口过程却能为各个窗口实现不同的操作,那就是MFC消息映射机制的奥秘和作用了。这些,将在后面有关章节详细论述。

CWnd提供了一系列成员函数,或者是对Win32相关函数的封装,或者是CWnd新设计的一些函数。这些函数大致如下。

方法/步骤

(1)窗口创建函数

这里主要讨论函数Create和CreateEx。它们封装了Win32窗口创建函数::CreateWindowEx。Create的原型如下:

BOOL CWnd::Create(LPCTSTR lpszClassName,

LPCTSTR lpszWindowName, DWORD dwStyle,

const RECT& rect,

CWnd* pParentWnd, UINT nID,

CCreateContext* pContext)

Create是一个虚拟函数,用来创建子窗口(不能创建桌面窗口和POP UP窗口)。CWnd的基类可以覆盖该函数,例如边框窗口类等覆盖了该函数以实现边框窗口的创建,视类则使用它来创建视窗口。[!--empirenews.page--]

Create调用了成员函数CreateEx。CWnd::CreateEx的原型如下:

BOOL CWnd::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName,

LPCTSTR lpszWindowName, DWORD dwStyle,

int x, int y, int nWidth, int nHeight,

HWND hWndParent, HMENU nIDorHMenu, LPVOID lpParam)

CreateEx有11个参数,它将调用::CreateWindowEx完成窗口的创建,这11个参数对应地传递给::CreateWindowEx。参数指定了窗口扩展风格、“窗口类”、窗口名、窗口大小和位置、父窗口句柄、窗口菜单和窗口创建参数。

CreateEx的处理流程将在后面4.4.1节讨论窗口过程时分析。

窗口创建时发送WM_CREATE消息,消息参数lParam指向一个CreateStruct结构的变量,该结构有11个域,其描述见后面4.4.1节对窗口过程的分析,Windows使用和CreateEx参数一样的内容填充该变量

(2)窗口销毁函数

例如:

DestroyWindow函数 销毁窗口

PostNcDestroy( ),销毁窗口后调用,虚拟函数

3)用于设定、获取、改变窗口属性的函数,例如:

SetWindowText(CString tiltle) 设置窗口标题

GetWindowText() 得到窗口标题

SetIcon(HICON hIcon, BOOL bBigIcon);设置窗口像标

GetIcon( BOOL bBigIcon ) ;得到窗口像标

GetDlgItem( int nID);得到窗口类指定ID的控制子窗口

GetDC(); 得到窗口的设备上下文

SetMenu(CMenu *pMenu); 设置窗口菜单

GetMenu();得到窗口菜单

(4)用于完成窗口动作的函数

用于更新窗口,滚动窗口,等等。一部分成员函数设计成或可重载(Overloaded)函数,或虚拟(Overridden)函数,或MFC消息处理函数。这些函数或者实现了一部分功能,或者仅仅是一个空函数。如:

有关消息发送的函数:

SendMessage( UINT message,WPARAM wParam = 0, LPARAM lParam = 0 );

给窗口发送发送消息,立即调用方式

PostMessage(( UINT message,WPARAM wParam = 0, LPARAM lParam = 0 );

给窗口发送消息,放进消息队列

有关改变窗口状态的函数

MoveWindow( LPCRECT lpRect, BOOL bRepaint = TRUE );

移动窗口到指定位置

ShowWindow(BOOL );显示窗口,使之可见或不可见

实现MFC消息处理机制的函数:

virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam ); 窗口过程,虚拟函数

virtual BOOL OnCommand( WPARAM wParam, LPARAM lParam );处理命令消息

消息处理函数:

OnCreate( LPCREATESTRUCT lpCreateStruct );MFC窗口消息处理函数,窗口创建时由MFC框架调用

OnClose();MFC窗口消息处理函数,窗口创建时由MFC框架调用

其他功能的函数

CWnd的导出类是类型更具体、功能更完善的窗口类,它们继承了CWnd的属性和方法,并提供了新的成员函数(消息处理函数、虚拟函数、等等)。

常用的窗口类及其层次关系见图1-1。

 


2.在MFC下创建一个窗口对象

MFC下创建一个窗口对象分两步,首先创建MFC窗口对象,然后创建对应的Windows窗口。在内存使用上,MFC窗口对象可以在栈或者堆(使用new创建)中创建。具体表述如下:

创建MFC窗口对象。通过定义一个CWnd或其派生类的实例变量或者动态创建一个MFC窗口的实例,前者在栈空间创建一个MFC窗口对象,后者在堆空间创建一个MFC窗口对象。

调用相应的窗口创建函数,创建Windows窗口对象。

例如:在前面提到的AppWizard产生的源码中,有CMainFrame(派生于CMDIFrame(SDI)或者CMDIFrameWnd(MDI))类。它有两个成员变量定义如下:

CToolBar m_wndToolBar;

CStatusBar m_wndStatusBar;

当创建CMainFrame类对象时,上面两个MFC Object也被构造。

CMainFrame还有一个成员函数

OnCreate(LPCREATESTRUCT lpCreateStruct),

它的实现包含如下一段代码,调用CToolBar和CStatusBar的成员函数Create来创建上述两个MFC对象对应的工具栏HWND窗口和状态栏HWND窗口:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

if (!m_wndToolBar.Create(this) ||

!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))

{

TRACE0(“Failed to create toolbarn”);

return -1; // fail to create

}

if (!m_wndStatusBar.Create(this) ||

!m_wndStatusBar.SetIndicators(indicators,

sizeof(indicators)/sizeof(UINT)))

{

TRACE0(“Failed to create status barn”);

return -1; // fail to create

}

}

关于工具栏、状态栏将在后续有关章节作详细讨论。

在MFC中,还提供了一种动态创建技术。动态创建的过程实际上也如上所述分两步,只不过MFC使用这个技术是由框架自动地完成整个过程的。通常框架窗口、文档框架窗口、视使用了动态创建。介于MFC的结构,CFrameWnd和CView及其派生类的实例即使不使用动态创建,也要用new在堆中分配。理由见窗口的销毁(2.2.5节)。

至于动态创建技术,将在下一章具体讨论。

在Windows窗口的创建过程中,将发送一些消息,如:

在创建了窗口的非客户区(Nonclient area)之后,发送消息WM_NCCREATE;

在创建了窗口的客户区(client area)之后,发送消息WM_CREATE;

窗口的窗口过程在窗口显示之前收到这两个消息。

如果是子窗口,在发送了上述两个消息之后,还给父窗口发送WM_PARENATNOTIFY消息。其他类或风格的窗口可能发送更多的消息,具体参见SDK开发文档。[!--empirenews.page--]

3.MFC窗口的使用

MFC提供了大量的窗口类,其功能和用途各异。程序员应该选择哪些类来使用,以及怎么使用他们呢?

直接使用MFC提供的窗口类或者先从MFC窗口类派生一个新的C++类然后使用它,这些在通常情况下都不需要程序员提供窗口注册的代码。是否需要派生新的C++类,视MFC已有的窗口类是否能满足使用要求而定。派生的C++类继承了基类的特性并改变或扩展了它的功能,例如增加或者改变对消息、事件的特殊处理等。

主要使用或继承以下一些MFC窗口类(其层次关系图见图1-1):

框架类CFrameWnd,CMdiFrameWnd;

文档框架CMdiChildWnd;

视图CView和CView派生的有特殊功能的视图如:列表CListView,编辑CEditView,树形列表CTreeView,支持RTF的CRichEditView,基于对话框的视CFormView等等。

对话框CDialog。

通常,都要从这些类派生应用程序的框架窗口和视窗口或者对话框。

工具条CToolBar

状态条CStatusBar

其他各类控制窗口,如列表框CList,编辑框CEdit,组合框CComboBox,按钮Cbutton等。

通常,直接使用这些类。

4.在MFC下窗口的销毁

窗口对象使用完毕,应该销毁。在MFC下,一个窗口对象的销毁包括HWND窗口对象的销毁和MFC窗口对象的销毁。一般情况下,MFC编程框架自动地处理了这些。

(1)对CFrameWnd和CView的派生类

这些窗口的关闭导致销毁窗口的函数DestroyWindow被调用。销毁Windows窗口时,MFC框架调用的最后一个成员函数是OnNcDestroy函数,该函数负责Windows清理工作,并在最后调用虚拟成员函数PostNcDestroy。CFrameWnd和CView的PostNcDestroy调用delete this删除自身这个MFC窗口对象。

所以,对这些窗口,如前所述,应在堆(Heap)中分配,而且,不要对这些对象使用delete操作。

(2)对Windows Control窗口

在它们的析构函数中,将调用DestroyWidnow来销毁窗口。如果在栈中分配这样的窗口对象,则在超出作用范围的时候,随着析构函数的调用,MFC窗口对象和它的Windows window对象都被销毁。如果在堆(Heap)中分配,则显式调用delete操作符,导致析构函数的调用和窗口的销毁。

所以,这种类型的窗口应尽可能在栈中分配,避免用额外的代码来销毁窗口。如前所述的CMainFrame的成员变量m_wndStatusBar和m_wndToolBar就是这样的例子。

(3)对于程序员直接从CWnd派生的窗口

程序员可以在派生类中实现上述两种机制之一,然后,在相应的规范下使用。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

融入AI功能的聊天机器人助手如今被各种组织用于节省时间和提高生产力,是企业寻求采用生成式AI最容易实现的成果之一。

关键字: 微软 copilots AI机器人

双系统将是下述内容的主要介绍对象,通过这篇文章,小编希望大家可以对双系统的相关情况以及信息有所认识和了解,详细内容如下。

关键字: 双系统 Windows Linux

你也许听过“Magnificent Seven”的大名。没听过?无妨,它指的是2023年美股市值最高的7家企业,也就是微软、苹果、英伟达、Alphabet、亚马逊、Meta、特斯拉。

关键字: 微软 苹果 英伟达 Alphabet 亚马逊 Meta 特斯拉

埃隆·马斯克日前起诉OpenAI及其 CEO萨姆·奥特曼违反创始协议。他在诉讼中声称,OpenAI在他退出之后已经将公司结构转变为一家营利性公司,并已经转变为“微软事实上的闭源子公司”,公然违反了其创始协议。

关键字: 马斯克 奥特曼 OpenAI 特斯拉 微软

2月27日消息,在MWC 2024上,微软发布了最新的AI访问原则,微软称是为了解决Microsoft作为人工智能创新者和市场领导者日益增长的作用和责任。

关键字: 微软 AI 机器AI 比尔盖茨

今天,小编将在这篇文章中为大家带来Windows 11系统的有关报道,通过阅读这篇文章,大家可以对Windows 11系统具备清晰的认识,主要内容如下。

关键字: Windows 操作系统

据报道,谷歌母公司Alphabet和微软日前都宣布,在欧洲人工智能(AI)领域投入巨资,抢在欧盟出台新的AI法规之前,重塑他们的AI基础设施。

关键字: 微软 谷歌 AI

微软近日宣布,未来两年将在德国投资32亿美元,扩大其AI和云基础设施,创下该公司在德国的最大投资记录。

关键字: 微软 云计算 AI 大模型

微软市值突破3万亿美元,仅次于苹果,这样的成绩是对微软CEO萨提亚·纳德拉(Satya Nadella)的认可。

关键字: 微软 市值 CEO 萨提亚·纳德拉

业内消息,此前微软裁减约8%的游戏部门员工大约1900人,此次裁员主要是优化去年收购动视暴雪后职能重复的情况。但引发了网络舆论的强烈抨击,玩家和业内人士纷纷对微软高层表达不满。

关键字: 微软 游戏 裁员
关闭
关闭