zoukankan      html  css  js  c++  java
  • MFC程序框架

    MFC程序框架

    比如建立一个叫test的程序。

    1. 首先需要构造一个mfc实例。需要一个类CtestApp 继承自CWinAppp类。在头文件 test.h 中定义。

    // #test.h头文件
    
    #pragma once
    
    #ifndef __AFXWIN_H__
        #error "在包含此文件之前包含“stdafx.h”以生成 PCH 文件"
    #endif
    
    #include "resource.h"       // 主符号
    
    
    
    class CtestApp public CWinApp
    {
        public:
            CtestApp(); //构造函数
    
        //下面的虚函数,是要重写的
        public:
            virtual BOOL InitInstance();
    
        //声明消息映射的宏
        DECLARE_MESSAGE_MAP()   //自己定义的每个继承自MFC的类,需要使用消息映射,就必须加这个宏。
    
        extern CtestApp theApp; //声明一下,可以不加。
    }

    2.有了程序实例类的头文件,需要实现的cpp文件test.cpp

    代码:

    // test.cpp
    
    #include "stdafx.h"
    #include "test.h"
    #include "testDlg.h"
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    
    // 消息映射
    
    BEGIN_MESSAGE_MAP(CtestApp,CWinApp)
        ON_COMMAND(ID_HELP,&CWinAPP::OnHelp)  //控件ID和对应处理函数
    END_MESSAGE_MAP()
    
    
    //CtestApp的构造函数实现
    CtestApp::CtestApp()
    {
      //vc6默认是空。vs2015 默认如下:
      // 支持重新启动管理器
        m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
        // TODO: 在此处添加构造代码,
        // 将所有重要的初始化放置在 InitInstance 中
    }
    
    
    //构造一个唯一的程序实例对象
    
    CtestApp theApp;
    
    
    //CtestApp的初始化
    
    BOOL CtestApp::InitInstance()
    {
        //VC2005以后的版本都有这一部分,VC6可能被系统做了,:
        // 如果一个运行在 Windows XP 上的应用程序清单指定要
        // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
        //则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
        INITCOMMONCONTROLSEX InitCtrls;
        InitCtrls.dwSize = sizeof(InitCtrls);
        // 将它设置为包括所有要在应用程序中使用的
        // 公共控件类。
        InitCtrls.dwICC = ICC_WIN95_CLASSES;
        InitCommonControlsEx(&InitCtrls);
        CWinApp::InitInstance();
        //VC6 和VC2005以后的共同部分
        AfxEnableControlContainer();
    
        // 标准初始化
        // 如果未使用这些功能并希望减小
        // 最终可执行文件的大小,则应移除下列
        // 不需要的特定初始化例程
        // 更改用于存储设置的注册表项
        // TODO: 应适当修改该字符串,
        // 例如修改为公司或组织名
        SetRegistryKey(_T("我的test程序"));
    
        CtestDlg dlg; //创建一个窗口对象
        m_pMainWnd = &dlg;// CWnd* 指针接收
        INT_PTR nResponse = dlg.DoModal(); // int指针接收
    
        // 画面关闭前,domodal函数是不会返回的,画面关闭使用enddialog(nResult) ,那么nResult就是作为domodal的返回值。 
        if(nResponse == IDOK)
        {
            //点击"确定" 的处理
        }
        else if (nResponse == IDCANCEL)
        {
            // TODO: 在此放置处理何时用
            //  “取消”来关闭对话框的代码
        }
        else if (nResponse == -1)
        {
            TRACE(traceAppMsg, 0, "警告: 对话框创建失败,应用程序将意外终止。
    ");
        }
    
    #ifndef _AFXDLL
        ControlBarCleanUp();
    #endif
    
        // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
        //  而不是启动应用程序的消息泵。
        return FALSE;
    
    }
    

    3.主题框架有了,那么需要的每个对话框都需要一个类

    //对话框类定义头文件CtestDlg.h
    
    #pragma once // 微软搞的,只包含一次,相当于c语言的防止重复定义的define 语句
    
    // CtestDlg 对话框类, 都继承自CDialog 
    
    class CtestDlg:public CDialog
    {
    
    //构造
    public:
        CtestDlg(CWnd* pParent = NULL); //标准构造函数
    
    //对话框数据 ,VC6没有这个预编译条件
    
    #ifdef AFX_DESIGN_TIME
        enum { IDD = IDD_TEST_DIALOG };
    #endif
    
    //数据交换
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    
    //实现
    protected:
        hICON m_hIcon;
        //生成的映射函数
        virtual BOOL OnInitDialog();
        afx_msg void OnsysCommand(UINT nID, LPARAM lparam);
        afx_msg void OnPaint();
        afx_msg HCURSOR OnQueryDragIcon();
        DECLARE_MESSAGE_MAP();
    };
    
    //关于对话框类定义一般默认在 CtestDlg.cpp中,为了统一可以复制到这个.h文件中
    
    class CAboutDlg : public CDialog
    {
    public:
        CAboutDlg();
    
    // 对话框数据
    #ifdef AFX_DESIGN_TIME
        enum { IDD = IDD_ABOUTBOX };
    #endif
    
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    
    // 实现
    protected:
        DECLARE_MESSAGE_MAP()
    };
    

    4. 对话框类都定义好了,那么就剩实现类里面的函数了

    ,最重要的文件,也是主要编写的cpp文件CtestDlg.cpp

    //CtestDlg.cpp
    
    //头文件
    #include "stdafx.h"
    #include "test.h"
    #include "testDlg.h"
    #include "afxdialogex.h"
    
    //为了调试的预定义
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
    
    
    // about对话框的构造函数,为默认为空
    CAboutDlg::CAboutDlg():CDialog() {
    
    }
    
    //数据交换,默认是父类的该函数处理
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
    }
    
    //控件和消息绑定,该对话框没有消息需要处理
    
    BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    //这里是消息绑定
    END_MESSAGE_MAP()
    
    
    //test对话框构造函数,加载RC图标
    
    CtestDlg::CtestDlg(CWnd* pParent /*=NULL*/)
        : CDialog(IDD_TEST_DIALOG, pParent)
    {
        m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }
    
    
    //数据交换
    
    void CMFCApplication7Dlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
        DDX_Control(pDX,IDC_EDIT1,m_edit1);//对话框添加了一个编辑框,ID是IDC_EDIT1.
    }
    
    //消息和控件映射
    BEGIN_MESSAGE_MAP(CMFCApplication7Dlg, CDialog)
        ON_WM_SYSCOMMAND()
        ON_WM_PAINT()
        ON_WM_QUERYDRAGICON()
        ON_EN_CHANGE(IDC_EDIT1, &CMFCApplication7Dlg::OnEnChangeEdit1) //修改编辑框内容时的处理
    END_MESSAGE_MAP()
    
    
    //初始化函数,画面显示前的初始化操作
    BOOL CMFCApplication7Dlg::OnInitDialog()
    {
        CDialog::OnInitDialog();
    
        // 将“关于...”菜单项添加到系统菜单中。
    
        // IDM_ABOUTBOX 必须在系统命令范围内。
        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
        ASSERT(IDM_ABOUTBOX < 0xF000);
    
        CMenu* pSysMenu = GetSystemMenu(FALSE);
        if (pSysMenu != NULL)
        {
            BOOL bNameValid;
            CString strAboutMenu;
            bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
            ASSERT(bNameValid);
            if (!strAboutMenu.IsEmpty())
            {
                pSysMenu->AppendMenu(MF_SEPARATOR);
                pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
            }
        }
    
        // 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
        //  执行此操作
        SetIcon(m_hIcon, TRUE);         // 设置大图标
        SetIcon(m_hIcon, FALSE);        // 设置小图标
    
        // TODO: 在此添加额外的初始化代码
    
        return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
    }
    
    
    //系统命令,比如右键的消息,(右键:关于)
    void CMFCApplication7Dlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
        if ((nID & 0xFFF0) == IDM_ABOUTBOX)
        {
            CAboutDlg dlgAbout;
            dlgAbout.DoModal();
        }
        else
        {
            CDialog::OnSysCommand(nID, lParam);
        }
    }
    
    // 如果向对话框添加最小化按钮,则需要下面的代码
    //  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
    //  这将由框架自动完成。
    void CMFCApplication7Dlg::OnPaint()
    {
        if (IsIconic())
        {
            CPaintDC dc(this); // 用于绘制的设备上下文
    
            SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    
            // 使图标在工作区矩形中居中
            int cxIcon = GetSystemMetrics(SM_CXICON);
            int cyIcon = GetSystemMetrics(SM_CYICON);
            CRect rect;
            GetClientRect(&rect);
            int x = (rect.Width() - cxIcon + 1) ;
            int y = (rect.Height() - cyIcon + 1) / 2;
    
            // 绘制图标
            dc.DrawIcon(x, y, m_hIcon);
        }
        else
        {
            CDialog::OnPaint();
        }
    }
    
    //当用户拖动最小化窗口时系统调用此函数取得光标
    //显示。
    HCURSOR CMFCApplication7Dlg::OnQueryDragIcon()
    {
        return static_cast<HCURSOR>(m_hIcon);
    }
    
    
    //自己定义的,修改编辑框时触发的消息函数处理
    void CMFCApplication7Dlg::OnEnChangeEdit1()
    {
        // TODO:  如果该控件是 RICHEDIT 控件,它将不
        // 发送此通知,除非重写 CDialog::OnInitDialog()
        // 函数并调用 CRichEditCtrl().SetEventMask(),
        // 同时将 ENM_CHANGE 标志“或”运算到掩码中。
    
        // TODO:  在此添加控件通知处理程序代码
    
        MessageBox(_T("hello"), _T("hellowolrd"), MB_OK);
    }
    

    5其他的文件

    除了以上这些文件,还有resource.h 资源头文件,.rc文件,每次添加,拖动控件都会自动修改这些文件。stdafx.h 是标准系统包含的文件,stdafx.cpp 里面包含这个头文件,生成预编译的pch文件。

    6.预编译:

    把项目用到且长期不会修改的头文件,甚至inline函数代码,放到一个.cpp/.c 文件中,提前编译成.pch 文件,一般比较大,有6-7M ,这样节省编译时间,下次修改其他代码。这部分预编译的,就不会被编译。
    
  • 相关阅读:
    SQLMAP注入教程-11种常见SQLMAP使用方法详解
    VS2012/2013/2015/Visual Studio 2017 关闭单击文件进行预览的功能
    解决 IIS 反向代理ARR URLREWRITE 设置后,不能跨域跳转 return Redirect 问题
    Spring Data JPA one to one 共享主键关联
    JHipster 问题集中
    Spring Data JPA 定义超类
    Spring Data JPA查询关联数据
    maven命名
    maven仓库
    Jackson读取列表
  • 原文地址:https://www.cnblogs.com/hystill/p/13783212.html
Copyright © 2011-2022 走看看