从Win32过渡到MFC工程

MFC简介

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

MFC程序就是基于MFC编译出来的可执行程序,是一种GUI程序。

VS2019下MFC程序建立

新建Windows桌面向导

 选择应用程序类型、建立一个空项目

当选择为桌面应用程序后,

项目属性下的C/C++->预处理器->预处理定义下就有_WINDOWS的宏定义。

链接器->子系统下选择项就为:窗口 (/SUBSYSTEM:WINDOWS)。

MFC程序内容书写 

这样一个空项目建立好,然后源文件下-->新建CPP文件MyFirstMFC.cpp.

MFC程序分三步:
1、建立CWinApp的派生类

class CMyApp : public CWinApp
{
public:
    CMyApp()
    {
    }
    ~CMyApp()
    {
    }
    //看做是入口函数,MFC的所有代码都从这里开始
    //InitInstance : MFC的初始化过程,启动管理
    //目的:为了初始化应用程序,虚函数
    virtual BOOL InitInstance()
    {
        //第一个对话框窗口
     CMainDlg dlg;
     INT_PTR res=dlg.DoModal();//弹出一个模态对话框
if(res==IDOK)
{
AfxMessageBox(_T("弹出对话框"));
} return TRUE;//TRUE:表示初始化成功,返回FALSE表示关闭应用程序 } //负责清理操作 int ExitInstance() { return CWinApp::ExitInstance(); } };

CMyApp::CMyApp()
{
}


CMyApp::~CMyApp()
{
}

2、重写InitInstance虚函数

如上面代码所示,子类CMyApp重写了基类CwinApp的InitInstance函数。

InitInstance函数是程序的入口函数,WinMain函数隐藏在这个函数中。在实际的开发中,一般不需要对这个类进行操作,但如果需要在建立主对话框之前处理一些数据或者准备工作,那么就可以把代码添加到这个函数中,主对话框显示之前。

3、定义CWinApp派生的全局对象

CMyApp theApp;

其为MFC应用程序的核心对象,一个应用程序有且只有一个theApp。

MFC程序整个的执行过程大致如下:

1.Windows将用户程序装入内存;
2.构造全程对象theApp,在程序被装入时,所有全程对象(全局变量对象)都会立刻被创建;
3.Windows调用全程函数WinMain,它是类库的一部分;
4.WinMain会自动搜索CWinApp派生类的唯一实例;
5.在找到后,WinMain会调用theApp的InitInstance函数,它在派生类中被重新设置了;
6.被重新设置的InitInstance函数启动了文档的装入以主要框架和视的显示处理过程;
7.然后,WinMain调用theApp的Run函数,它启动窗口消息和命令消息的传递处理过程;
当一个应用程序被中止,所有窗口被关闭后,ExitInstance函数会被自动调用。

关于MFC程序执行流程的解析,请查看《XXXX》文章。

这里提醒一下,关于第二步提到全局变量(对象),我们要明确一点,全局变量的执行是优先于主函数的(main、WinMain)。

控制台程序:

#include <iostream>
using namespace std;

int a = 30;//全局变量 生命周期:从程序的开始到程序的结束销毁

// mainCRTStartup

class Hello
{
public:
    Hello()
    {
        cout << "这是Hello构造函数" << endl;
    }
};

Hello hello;//全局对象, 首先构造hello对象

int main()
{
    cout << "这是main函数" << endl;
    int b = 40;
    cout << a << "  " << b << endl;//30 40

    return 0;
}
View Code

 可以看到先实例化了全局对象hello,而后执行main函数。

修改VS配置信息

在配置属性->高级->MFC的使用一览选择:在共享 DLL 中使用 MFC或在静态库中使用 MFC。

在上面的例子中,我们是希望在主程序执行时,弹出一个模态对话框,对话框的定义信息如下:

#include<afxwin.h>
#include"resource.h"
class CMainDlg :public CDialog
{
private:
    HICON m_hIcon;
public:
    enum { IDD = IDD_MAIN_DLG };
public:
    CMainDlg() :CDialog(IDD)
    {

    }
    BOOL OnInitDialog()
    {
        SetWindowText(_T("weiyin"));
        m_hIcon=::LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_ICON1));
        SetIcon(m_hIcon, true);
        return true;
    
    }

};

MFC实例句柄的获取

在win32桌面程序中,WinMain函数的第一个形参就是当前程序的实例句柄:hInstance.而MFC中要获取其实例句柄,设置图标的时候,可以采用以下几种方式获取。

//加载图标 hInstance
//MFC中如何获取实例句柄:
//1 . AfxGetInstanceHandle()
//2 . AfxGetApp()->m_hInstance

//1.m_hIcon = ::LoadIcon(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_ICON1));
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);

Win32 API与MFC API

当MFC API与win32 API同名冲突时,我们一般约定:

:: 如果::的前面是没有类名来修饰,那么,表示调用的是Win32 API函数 。eg ::LoadIcon()

加了前缀类名的为当前类的成员函数。

没有加::的函数为MFC API函数,其一般是以Afx开头的的全局函数,都能在MFC工程中使用。

posted @ 2021-10-15 09:16  liweiyin  阅读(317)  评论(0编辑  收藏  举报