MFC分析对话框的运行机制心得体会
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VC++ MFC属性表对话框的运行机制
2012-07-01 19:09
属性表对话框的初始化包括框架对话框的初始化和页的初始化。页的初始化工作可在OnInitDialog函数中进行,而框架对话框的初始化应该在OnCreate函数中完成。
根据CPropertySheet::DoModal返回的是IDOK还是IDCANCEL,程序可以判断出关闭对话框时按的是OK还是Cancel按钮,这与普通对话框是一样的。
如果属性表对话框是模态对话框,在其底部会有3个按钮,依次为OK、Cancel和Apply (应用)按钮,如果对话框是非模态的,则没有这些按钮。OK与Cancel按钮的意义与普通按钮没什么两样,Apply按钮则是属性
表对话框所特有的。普通的模态对话框只有在用户按下了OK按钮返回后,对话框的设置才能生效,而设计Apply的意图是让用户能在不关闭对话框的情况下使对话框的设置立即生效。由此可见,Apply按钮的作用是使用户在设置完数据后,不必退出对话框,就可以反复进行设置,这在许多应用场合下是很有用的。
为了对上述3个按钮作出响应,CPropertyPage类提供了OnOK,OnCancel 和OnApply函数,用户可覆盖这3个函数以完成所需的工作。需要指出的是这3个函数并不是直接响应按钮的BN_CLICKED消息的,但在按钮按下后它们是被间接调用。这些函数的说明如下:
1.Virtual void OnOK( ):在按下OK或Apply按钮后,该函数被调用。默认的OnOK
函数几乎什么也不干,像数据交换和关闭对话框这样的工作是在别的地方完成的,这与普通对话框的OnOK函数是不同的:
2.Virtual void OnCancel( ):在按下Cancel 按钮后,该函数将被调用。默认的OnCancel 函数也是几乎什么也不干;
3.Virtual BOOL OnApply( ):在按下OK 或Apply按钮后,该函数将被调用。默认的OnApply 会调用OnOK函数。函数的返回值如果是TRUE,则对话框中的设置将生效,否则无效。
令人不解的是,MFC并未考虑CPropertySheet类的按钮响应问题,不要指望能通过ClassWizard来自动创建按钮的BN_CLICKED消息处理函数,通常的按钮
响应都是在CPropertyPage类完成的。
下面几个CPropertyPage类的成员函数也与属性表的运行机制相关。
Void SetModified( BOOL bChanged = TRUE ):该函数用来设置修改标志。若参数bChanged为True,则表明对话框中的设置已改动,否则说明设置未改动。该函数的一个主要用途是允许或禁止Apply按钮。在默认情况下,Apply按钮是禁止的。只要一调用SetModified(TRUE),Apply按钮就被允许,而调用SetModified(FALSE)并不一定能使Apply按钮禁止,只有在所有被标为改动的页都调用了SetModified(FALSE)后,Apply按钮才会被禁止。另外,该函数对OnApply的调用也有影响,当Apply按钮被按下后,只有那些被标记为改动过的页的OnApply函数才会被调用。在调用该函数之前,程序需要叛断页中的内容是否已被修
改,可通通过处理诸如BN_CLICKED、EN_CHANGE这样的控件消息来感知页的内容的改变;
1.1 MFC 文档视图结构程序结构总揽当我们使用MFC AppWizard 生成一个MFC 程序,选用所有默认的设置(当然也是Multiple Documents ,本文讨论主要基于Multiple Documents ,对于Single Document 情况仅以简单表述提及,皆因后者和前者很多相似相同之处,但前者更为复杂,并且更加常用。),假设你的程序名称为A ,则你会得到CMainFrame 、CChildFrame 、CAboutDlg 、CADoc 、CA View 、CAApp 6 个类(Single Document 仅少一个CChildFrame 类,其余均同)。这些类的具体含义将在后面给出,这里先要给出一个MFC 支持文档视图结构程序(以下简称App )的主要组成:
一个App (对应类CAApp )可以包含多个文档模版(CDocTemplate ),但是MFC AppWizard (无论是SDI 还是MDI )都只是默认生成一个。但是在实际开发中一个文档模版不够,需要自己手工添加(在后面实际项目例子提供示例)。这个结构是通过MFC 中CWinApp 的成员变量CDocManager* m_pDocManager 实现的,我们的CAApp 正是继承自MFC 提供的CWinApp 类。
CDocManager 类则拥有一个指针链表CPtrList m_templateList 来维护这些文档模版。这些文档模版都是在CAApp ::InitInstance ()中通过AddDocTemplate(pDocTemplate) 。
CDocTemplate 拥有 3 个成员变量,分别保存着Document 、View 、Frame 的CRuntimeClass 指针,另外持有成员变量m_nIDResource ,用来指定这个Document 显示时候采用的菜单资源。这 4 份数据都在CAApp ::InitInstance ()中CDocTemplate 的构造函数中指定。在Document 中拥有一个回指CDocTemplate 的指针(m_pDocTemplate )。
一个文档可以有多个视图,由Document 中成员变量CPtrList m_ViewList 维护。
CFrameWnd 拥有一个成员变量CView* m_pActiveView 指向当前活动的View 。
CView 中拥有一个成员变量CDocument* m_pDocument 指向该视图相关的Document 。