MFC笔记

一.窗口类型的概述

窗口类型主要有二种即:文档类型(Document)和对话框类型(Dialog) 表单类型(Form)是介于这2种类型之间。文档类型的窗口的编程相对对话框来说要复杂得多,是我们学习的主要对象。

a)        文档类型(Document):文档类型的应用程序的界面,大部分区域用于文字或画图等读写操作,常见的有WordExcel、写字板等。文档类型的窗口又分单文档和多文档2种类型

                       i.             多文档类型就是在一个窗口框架内有多个子窗口,常见的有WordExcel

                                                   ii.           单文档类型当然就不可能有多个子窗口了,常见的有附件中的写字板、画图等。

b)       对话框类型(Dialog):对话框类型的界面中使用了很多控件,输入输出主要是针对控件,常见的有计算器、音量控制等。共对话框也是这种类型,只调用操作系统提供的就可以了。编程用的最多的也就是表单类型。对话框类型也可以象文档类型一样进行文字、画图等处理,而文档类型窗口中同样也可以使用控件。对话框窗口有模态和非模态2种类型。所谓模态对话框就是当前对话框不关闭,就不能切换到调用该对话框的父窗口;而所谓非模态窗口就是不关闭当前对话框,也同样可以切换到调用该对话框的父窗口。

单文档

对话框

CAboutDlg

“关于”对话框类。无须修改。

CAboutDlg

“关于”对话框类。无须修改。

CTest2App

主应用程序类,调用框架类、文档类、视图类,程序类。无须修改。

CTest3App

主应用程序类,调用主对话框类。无须修改。

CMainFrame

主框架类,即主窗口。很少需要修改。

Ctest3Dlg

主对话框类。

CTest2Doc

文档类,即存放数据主要在这儿编写代码。

CTest2view

视图类,即用于屏幕显示的类,文字显示和画图主要在这儿编写代码。

 

二.CmainFrame

类中的PreCreateWindow()成员函数中,通过修改 CREATESTRUCT cs 来修改窗口类或样式。

typedef struct tagCREATESTRUCTW {

   LPVOID    lpCreateParams;     //指向创建窗口用的数据的指针

   HANDLE    hInstance;          //窗口的实例句柄

   HMENU     hMenu;              //窗口的菜单句柄

   HWND      hwndParent;         //窗口句柄

    int       cy;                 //窗口的高度

    int       cx;                 //窗口的宽度

    int       y;                  //窗口的左上角的y座标

    int       x;                  //窗口的左上角的x座标

   LONG      style;              //窗口的类型

   LPCSTR    lpszName;           //指向窗口的名称的指针

   LPCSTR    lpszClass;          //指向窗口类的名称的指针

   DWORD     dwExStyle;          //窗口的扩展类型

} CREATESTRUCTW, *PCREATESTRUCTW,*LPCREATESTRUCTW;

   

框架类主要处理窗口的类型、边框、位置、大小以及子窗口(对于多文档来说)等内容,工具条、状态条也是这个类的成员变量。如果要添加成员变量时,初始化要在CMainFrame()构造函数中添加代码;OnCreate()成员函数是消息WM_CREATE的处理函数,这里面根据需要修改代码(一般不需要)PreCreateWindow()成员函数是创建主窗口前的设置,调整窗口位置、大小、类型等都是在这儿修改代码。

三.文档类

文档类主要用来处理数据。例如画一个图,图的各节点座标、颜色、线条的粗细等都有文档类来处理,文件的保存和打开等当然也是文档类来处理。

四.            视图类

主要处理数据的显示,例如:文字在窗口中显示、键盘鼠标操作等都是由视图类来处理。视图类不断地从文档类取数据,不断地对文档类传送数据。当文档类数据较多时,视图类显示的数据只是文档类的一部分。

五.            主应用程序类

主应用程序类是程序的入口,其它各个类都是在这儿集成的。这个类除构造函数之外,唯一要注意的就是初始化函数。这个类一般不修改。

单文档

对话框

Ctest2App()

构造函数

Ctest2App()

构造函数

InitInstance()

初始化成员函数

InitInstance()

初始化成员函数

OnAppAbout()

由菜单发出的消息处理函数

 

 

 

单文档

对话框

BOOL Ctest2App::InitInstance()

{

     InitCommonControls();

     CWinApp::InitInstance();

    if (!AfxOleInit())

    {

         AfxMessageBox(IDP_OLE_INIT_FAILED);

        return FALSE;

    }

     AfxEnableControlContainer();

     SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

   

    //加载标准 INI 文件选项(包括 MRU)

     LoadStdProfileSettings(4);

 

    //上面内容不用太关注,以下是重点

    //注册应用程序的文档模板。文档模板

    //将用作文档、框架窗口和视图之间的连接

     CSingleDocTemplate* pDocTemplate;

    pDocTemplate  = new CSingleDocTemplate(

         IDR_MAINFRAME,

         RUNTIME_CLASS(Ctest2Doc),

         RUNTIME_CLASS(CMainFrame),

         RUNTIME_CLASS(Ctest2View));

    if (!pDocTemplate)

        return FALSE;

     AddDocTemplate(pDocTemplate);

    //分析标准外壳命令、DDE、打开文件操作的命令行

     CCommandLineInfo cmdInfo;

     ParseCommandLine(cmdInfo);

    //调度在命令行中指定的命令。如果

    //用 /RegServer、/Register、/Unregserver

    //或 /Unregister 启动应用程序,则返回 FALSE。

    if (!ProcessShellCommand(cmdInfo))

        return FALSE;

    //唯一的一个窗口已初始化,因此显示它并对其进行更新

     m_pMainWnd->ShowWindow(SW_SHOW);

     m_pMainWnd->UpdateWindow();

    //仅当存在后缀时才调用 DragAcceptFiles

    //在 SDI 应用程序中,这应在 ProcessShellCommand

    //之后发生

    return TRUE;

}

BOOL Ctest3App::InitInstance()

{

     InitCommonControls();

     CWinApp::InitInstance();

 

 

 

 

 

     AfxEnableControlContainer();

     SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

 

 

 

 

    //上面内容不用太关注,以下是重点

    Ctest3Dlg  dlg;

    m_pMainWnd =  &dlg;

    INT_PTR  nResponse = dlg.DoModal();

    //下面的程序注意:对话框窗口已经被关闭

    if (nResponse == IDOK)

    {

        // TODO: 在此放置处理何时用“确定”来关闭

        //对话框的代码

    }

    else if (nResponse == IDCANCEL)

    {

        // TODO: 在此放置处理何时用“取消”来关闭

        //对话框的代码

    }

 

    // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,

    // 而不是启动应用程序的消息泵。

    return FALSE;

}

 

 

 

 

 

 

 

 

六.            WinMain()函数在哪儿

MFC把千篇一律的WinMain()函数写在crtexec.c中,在编译完后链接时才组装到你的exe程序中。运行时,这个WinMain()函数调用MFC的全局函数AfxWinMain(),这个全局函数AfxWinMain()是写在appmodul.cpp中的。在AfxWinMain()函数中做三件事,注册窗口类、调用应用程序类的初始化函数InitInstance()调用应用程序类的Run()函数(实际上是父类的父类CWinThreadRun()成员函数)

上面这个Run()函数中包含消息循环,而InitInstance()函数又将框架类、文档类、视图类结合在一起,于是所有的类全部集成起来了,然后在主应用程序类、框架类、文档类、视图类里面接受这些消息并处理。编程的重点在文档类和视图类,什么样的消息,执行什么样的处理函数,这样就有效地将数据和控制分离开来。

七.            消息处理

与窗口有关的消息(即以“WM_”开头的消息),只能在框架类和视图类中处理;来自菜单或工具条的命令事件,则框架类、视图类、主应用程序类、文档类全部可以处理。这其中有优先级别高低的问题,一个类接受到命令消息时,先传给比自己级别高的类,如果未处理再自己处理。如果自己也不处理,则传给比自己级别低的类。这个优先级别是:视图类>文档类>文档模板类>框架类>主应用程序类>MFC缺省的处理程序中。

八.            添加、删除消息处理

添加一个消息处理,一般要改动三个地方,以WM_LBUTTONDOWN消息为例,在视图类的定义(test2View.h)中添加一个成员函数,在视图类(test2View.c)中添加一条消息映射,在视图类(test2View.c)中实现消息处理的成员函数。

九.            程序入口

主应用程序类是从CWinApp类继承的,作用相当于WinMain程序;CMainFrame是从CFrameWnd类继承的,其作用相当于WndProc程序。也就是说,消息首先由框架类接受,然后按优先顺序传给其它的类。文档类和视图类由消息来驱动(视图类的PreCreateWindow()除外)。

“Ctest2App theApp;”,这便是整个应用程序的总入口。MFCcrtexec.cWinMain()函数调用test2.cpp中的“Ctest2App theApp;”theApp是类的实例,自然也是必然要调用主应用程序类的构造函数,包括父类的构造函数,之后再调用MFCappmodul.cpp中的AfxWinMain()函数,由AfxWinMain()函数调用主应用程序类的InitInstance()成员函数。

在主应用程序类的InitInstance()成员函数中,定义了框架类、文档类、视图类的实例,从而间接地调用了框架类的PreCreateWindow()OnCreate()成员函数,由OnCreate()函数再调用视图类的PreCreateWindow()成员函数。然后再回到主应用程序类的InitInstance()成员函数中,执行“m_pMainWnd->ShowWindow(SW_SHOW);”“m_pMainWnd->UpdateWindow();”

 

十.            公共对话框MessageBox

MFCCWnd类中封装了一个MessageBox()成员函数,但MSDN并不推荐使用,一般用AfxMessageBox()全局函数

intAfxMessageBox(          

intAFXAPI AfxMessageBox(

LPCTSTR    lpszText,

UINT       nIDPrompt,            //要表示的字符串

UINT       nType = MB_OK,

UINT       nType = MB_OK,         //画面形状(按钮、模式、图标、缺省值4个值组合使用)

UINT       nIDHelp = 0            

UINT       nIDHelp = (UINT) -1    //帮助ID,缺省为0

);                             );

 

返回值

说明

0

不能正常表示

IDYES

                                                                      被按下

IDNO

     被按下

IDOK

     被按下

IDCANCEL

     被按下或【ESC】被按下

IDABORT

     被按下

IDIGNORE

     被按下

IDRETRY

     被按下

显示按钮

说明

ID_ABORTRETRYIGNORE

                

ID_OK

    

ID_OKCANCEL

          

ID_RETRYCANCEL

          

ID_YESNO

          

ID_YESNOCANCEL

                

模式

说明

ID_APPMODAL

模态(缺省值)即不关闭就不能回到父窗口,但可以切换到其它应用程序。

ID_SYSTEMMODAL

系统模态即不关闭就不能回到任何窗口。

ID_TASKMODAL

特殊用途而备用。

显示图标

说明

ID_ICONEXCLAMATION

      感叹符号

ID_ICONINFORMATION

      情报符号

ID_ICONquestion

      问号

ID_ICONSTOP

      停止符号

缺省按钮

说明

ID_DEFBUTTON1

第一个探针为缺省按钮。

ID_DEFBUTTON2

第二个探针为缺省按钮。

ID_DEFBUTTON3

第三个探针为缺省按钮。

 

十一. MFC特有的规则

a)       类型:MFCC++的关键字用宏定义成以下内容。

MFC类型

意思

C++类型

BOOL,BOOLEAN

布尔型

boolean

BYTE

1字节数值型

char

WORD

2字节数值型

short

DWORD

4字节数值型

int

UINT

无符号整型

unsigned int

VOID

void型

void

LPDWORD

DWORD的指针型

int*

LPCSTR

常量字符串

const char*

LPSTR

字符串

char*

LPCVOID

常量void指针

const void*

LPVOID

void指针

void*

b)       命名规则:MFC有以下命名规则。

                       i.             类名:以大写的C开头,单词的首字母大写,单词之间不用下划线。

                     ii.             成员函数和全局函数:以单词的首字母大写,单词之间不用下划线。全局函数前再加Afx

                   iii.             成员变量:匈牙利命名法,以“m_”开头,单词的首字母大写。

                   iv.             宏、类型名:全部使用大写。

 

十二.      TRACE宏调试

TRACE()宏函数来调试程序,TRACE()宏函数只在DEBUG状态有效,即按<F5>运行时有效,<Ctrl + F5>时无效。断点也可以设置条件。如,断点的条件是“i>5”

for(int i=0; i<10; i++) {

TRACE("i = [%d]\n", i);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值