MFC中Doc,View,MainFrmae,App总结

合集下载

MFC知识点(自己整理的,只供参考)

MFC知识点(自己整理的,只供参考)

知识点:不是很全面,只供参考第一章Windows应用程序使用的界面是由各种图形元素组成的图形界面(GUI)。

Windows提供了大量预定义的用C语言编写的函数,这些函数就叫做API(Application Programming Interface)函数。

在Windows应用程序中,存在着许多与DOS应用程序不同的复杂对象,例如窗口、按钮、滚动条等等。

Windows把为这种复杂对象所定义的标识叫做句柄。

常用的句柄类型:HWND 窗口句柄,HDC 图形设备环境句柄,HINSTANCE 当前程序应用实例句柄,HBITMAP 位图句柄,HICON 图标句柄,HCURSOR 光标句柄,HBRUSH 画刷句柄,HPEN 画笔句柄,HFONT 字体句柄,HMENU 菜单句柄,HFILE 文件句柄事件的描述是一个消息消息的结构:typedef struct tagMSG{HWND hwnd; //产生消息的窗口句柄UINT message;//消息的标识码WPARAM wParam;//消息的附加信息1LPARAM lParam;//消息的附加信息2DWORD time; //消息进入消息队列的时刻POINT pt; //表示发送该消息时鼠标的位置}MSG;消息循环:while(GetMessage(&msg,NULL,NULL,NULL))//系统处理了消息后返回{TranslateMessage(&msg);//把键盘消息翻译成字符消息DispatchMessage(&msg);//把消息派发给Windows系统创建窗口的三个步骤:注册窗口类:RegisterClass(&wc);创建窗口:hwnd=CreateWindow( lpszClassName,"Windows",WS_OVERLAPPEDWINDOW,120,50,800,600,NULL, NULL, hInstance,NULL);显示窗口:ShowWindow(hwnd,nCmdShow);UpdateWindow(hwnd);大题:用函数封装Windows程序(P16)第二章类封装:窗口类:class CFrameWnd{public:HWND hWnd;///数据成员public:int RegisterWindow(); //定义及注册窗口类void Create(LPCTSTR lpClassName,LPCTSTR lpWindowName);//创建窗口void ShowWindow(int nCmdShow);//显示与更新窗口void UpdateWindow();};应用程序类:class CWinApp{public:CFrameWnd*m_pMainWnd;//以窗口类的对象作为数据成员public:BOOL InitInstance (int nCmdShow);//在初始化函数中创建及显示窗口int Run();//消息循环};窗口函数的封装——消息映射用DECLARE_MESSAGE_MAP来声明消息映射表用BEGIN_MESSAGE_MAPBEGIN_MESSAGE_MAP(类名称,基类名称)ON_XXXX 例ON_WM_PAINT()END_MESSAGE_MAP来实现消息映射表大题:类封装Windows应用程序第三章应用程序的框架由两个对象组成:应用程序类CWinApp的派生类对象和框架窗口类CFrameWnd的派生类对象,后者作为一个成员对象嵌在前者之中。

MFC单文档模式中,四个类对消息处理的优先级

MFC单文档模式中,四个类对消息处理的优先级

MFC单⽂档模式中,四个类对消息处理的优先级MFC的单⽂档架构,有四个类(这⾥忽略About对话框类):1. MainFrame2. App3. Doc4. View这四个类和MVC设计模式的关系如下:1. MainFrame代表着MVC的C (Control)。

2. App可以理解为对hInstance的封装。

3. Doc对应着MVC的M (Model)。

4. View对应着MVC的V (View)。

这四个类全部继承⾃CCmdTarget类,所以它们都具有处理消息的能⼒。

问题是:同⼀个WM_COMMAND消息,谁先处理,谁后处理(4个类对消息处理的优先级问题)?现在做试验分析,⾸先要明确WM_COMMAND消息的产⽣⽅式。

以下三种情况都能产⽣WM_COMMAND消息:1. 菜单选项的点击2. 控件状态的改变(例如按钮按下)3. 键盘快捷键的按下⾸先增加⼀个菜单选项:然后在每个类中,都进⾏如下操作:进⼊类向导,在Command标签中增加关于此菜单项的处理函数:在每个函数内部写⼀个AfxMessageBox()函数,作为标记:这样,现在每个类都有了标记⽤的弹框提⽰。

运⾏程序,点击此菜单项,就知道这四个类对WM_COMMAND消息处理的优先权了:结果是View类对VM_COMMAND消息作出了响应。

经测试,⼀旦⼀个类处理了消息,其他类就不会处理了(也就是说只会弹出⼀个对话框(刚才设置了4个AfxMessageBox)),这四个类的优先级顺序为:1. View2. Doc3. MainFrame4. App现在探究这个顺序的原因。

研究的⽅法是在CSingleView::OnHelpTestcmd()函数⾥下断点,断下来之后分析栈回溯:分析之后找到原因:CFrameWnd::OnCmdMsg()函数内部,通过顺序结构规定了这四个类对WM_COMMAND消息的处理优先级:从代码以及注释中,可以清楚地看到这个优先级:View第⼀,下⼀个是MainFrame,最后是App。

mfc 知识点总结

mfc 知识点总结

mfc 知识点总结MFC库的基本组成包括以下几个部分:1. CObject类:是所有MFC类的基类,提供了对象的基本功能,包括内存管理、类型信息、对象的打印和序列化等。

2. CWnd类:是窗口类的基类,封装了Windows窗口的创建、显示、消息处理等功能。

3. CFrameWnd类:是框架窗口类,派生自CWnd类,封装了应用程序的主窗口,提供了菜单、工具栏、状态栏等UI组件。

4. CDocument类和CView类:分别是文档类和视图类,用于管理应用程序中的文档和视图。

文档类负责文档的打开、保存、关闭等操作,视图类负责文档内容的显示和交互。

5. CWinApp类:是应用程序类的基类,封装了应用程序的初始化、消息循环、资源管理等功能。

MFC库提供了丰富的类和函数,用于处理Windows应用程序的各个方面,下面将对MFC的一些重要知识点进行总结。

1. 消息处理在MFC应用程序中,窗口的消息处理是至关重要的。

MFC提供了消息映射机制来进行消息处理。

通过DECLARE_MESSAGE_MAP宏和BEGIN_MESSAGE_MAP/END_MESSAGE_MAP 宏,在类中声明消息处理函数并将消息与处理函数进行映射。

例如:```cpp// 声明消息处理函数afx_msg void OnMouseMove(UINT nFlags, CPoint point);// 映射消息到处理函数BEGIN_MESSAGE_MAP(CMyWnd, CWnd)ON_WM_MOUSEMOVE()END_MESSAGE_MAP()```2. 对话框对话框是Windows应用程序中常用的界面元素,用于与用户进行交互。

MFC提供了CDialog类和CDialogEx类来封装对话框。

开发者可以使用资源编辑器创建对话框模板,然后通过类向导生成对话框类。

对话框类中可以处理控件的事件,并通过DoModal函数或Create函数来显示对话框。

mfc文件操作个人总结

mfc文件操作个人总结

MFC文件操作一,打开文件对话框CString szFilters=_T("txt Files (*.txt)");CFileDialog fileDlg(TRUE, _T("txt"), _T("*.txt"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilters, NULL);if(fileDlg.DoModal() == IDOK){CString filestr;filestr = fileDlg.GetPathName(); //得到打开的文件的全路径+后缀};二,打开文件CFile::CFile( LPCTSTR lpszFileName, UINT nOpenFlags ); //CFile构造lpszFileName文件名nOpenFlags 打开方式,有:CFile::modeCreate:以新建方式打开,如果文件不存在,新建;如果文件已存在,把该文件长度置零,即清除文件原有内容。

CFile::modeRead:只读。

CFile::modeWrite:只写。

CFile::modeReadWrite:以读写方式打开文件。

CFile::modeNoTruncate:以追加方式打开,如果文件存在,打开并且不将文件长度置零,如果文件不存在,会抛出异常。

一般与CFile::modeCreate一起使用,则文件不存在时,新建一个文件;存在就进行追加操作(其追加是从起始位置进行覆盖式追加的,所以要与定位配合操作)。

例:1,利用CFile的构造函数打开文件filestr = _T("C:\\Users\\zktw\\Desktop\\new.txt");//或用一中获得的路径CFile RWFile(filestr,CFile::modeCreate | CFile::modeReadWrite | CFile::modeNoTruncate); 例2:利用CFile的成员函数CFile myfile;Myfile.open(_T(“路径”), CFile::modeCreate | CFile::modeReadWrite | CFile::modeNoTruncate);三,文件读写操作读操作CFile::Read( void* lpBuf, UINT nCount ); 从lpBuf指向的地址开始读取nCount 个字节,指针也自动下移nCount写操作CFile::Write( const void* lpBuf, UINT nCount ); 向lpBuf指向的内存地址写入nCount 个字节,指针也自动下移nCount四,定位CFile::Seek( LONG lOff, UINT nFrom );从指定位nFrom置偏移lOff字节.nFrom 有三种方式,如:CFile::begin 从文件开始移动CFile::current从当前位置移动CFile::end 从文件末位移动,此时lOff为负值. 例:CFile::Seek(0, CFile::end); //定位文件尾五,关闭打开的文件CFile::Close(); //关闭文件,删除对象,再次对文件读写时必须重新定义对象六,查找文件是否存在(CFileFind的成员函数)CString strFileTitle;CFileFind finder;BOOL bWorking = finder.FindFile(_T("C:\\Users\\zktw\\Desktop\\new.txt"));if(bWorking){AfxMessageBox(_T(“文件已存在”);}elseAfxMessageBox(_T(“文件不存在”));finder.close(); //结束查找请求释放资源,但是再次发出查找请求时不需要重新定义//CFileFind对象如下:bWorking = finder.FindFile(_T("C:\\Users\\zktw\\Desktop\\new1.txt"));。

MFC学习总结(重要)

MFC学习总结(重要)

Windows程序的执行过程:首先,Windows程序是以WinMain函数作为它的入口函数的,WinMain函数类似c语言中的main函数,其功能是完成一系列的定义和初始化,并产生消息循环。

函数原型:int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow);参数:hInstance:当前应用程序实例句柄;hPrevInstance:先前应用程序实例句柄;lpCmdLine:命令行;nCmdShow:窗口的显示状态:可以是以下值Value MeaningSW_HIDE Hides the window and activates another window.SW_MAXIMIZE Maximizes the specified window.SW_MINIMIZE Minimizes the specified window and activates the next top-level window in the Z order.SW_RESTORE Activates and displays the window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when restoring a minimized window.SW_SHOW Activates the window and displays it in its current size and position. SW_SHOWMAXIMIZEDActivates the window and displays it as a maximized window.SW_SHOWMINIMIZEDActivates the window and displays it as a minimized window.SW_SHOWMINNO ACTIVE Displays the window as a minimized window.This value is similar to SW_SHOWMINIMIZED, except the window is not activated.SW_SHOWNA Displays the window in its current size and position.This value is similar to SW_SHOW, except the window is not activated.SW_SHOWNOACTI V ATE Displays a window in its most recent size and position.This value is similar to SW_SHOWNORMAL, except the window is not actived.SW_SHOWNORMA L Activates and displays a window. If the window is minimized or maximized, the system restores it to its original size and position. An application should specify this flag when displaying the window for the first time.//函数内部实现:定义参数:MSG message1、初始化:设计窗口类注册窗口类产生窗口显示窗口更新窗口//设计窗口类和注册窗口类,称为初始化窗口类,可以放入InitWindClass(hInstance)//返回值为BOOL型{WNDCLASS WndClass;WndClass.cbClsExtra=0;WndClass.cbWndExtra=0;WndClass.hbrBackground=(HBRUSH)(GetStockObject(WHIT E_BRUSH));WndClass.hCursor=LoadCursor(NULL,IDC_ARROW); WndClass.hIcon=LoadIcon(NULL,"END");WndClass.hInstance=hInstance;Wndclass.lpfnWndProc=WndProc;WndClass.lpszClassName="WinText";WndClass.lpszMenuName=NULL;WndClass.style=CS_HREDRAW|CS_VREDRAW;Return RegisterClass(&WndClass);}//BOOL InitWindows(HINSTANCE hInstance,int nCmdShow) {HWND hWnd;hWnd=CreateWindow("WinText","文本显示示例程序",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL );if(!hWnd)Return FALSE;ShowWindow(hWnd,nCmdShow); UpdateWindow(hWnd);Return TRUE;}2、消息循环While(GetMessage(&Message,0,0,0)){TranslateMessage(&Message);DispatchMessage(&Message);}最后WINMAIN返回Message.wParam在WinMain()函数中会看到消息循环的主体while (GetMessage (&msg, NULL, 0, 0)){TranslateMessage (&msg) ;DispatchMessage (&msg) ;}GetMessage()用于接受消息,在接收到除WM_QUIT 之外的任何一个消息后,GetMessage()都返回TRUE。

MFC中五个初始类的作用

MFC中五个初始类的作用

MFC中五个初始类的作用一个最基本的单文档视图的MFC程序,包含CxxApp、CxxDoc、CMainFrame、CxxView和CAboutDlg五个类。

它们在程序开始运行时被创建的顺序是:CxxApp 、CxxDoc 、CMainFrame 、CxxView 、CAboutDlg。

C**App()定义了窗体加载之前需要做的预处理。

比如一个加密的软件,打开后提示用户输入密码。

这个事件的处理程序就要写在C**App()的InitInstance(中。

CMainFrame()包含了对工具栏、状态栏、窗口的定义。

C**View包含了最主要的处理功能,如菜单操作、快捷键、用户交互操作等。

CAboutDlg定义了ABOUT对话框。

其中,前四个都是在程序主窗口出现之前被创建的,CAboutDlg 是在“关于”对话框弹出时被创建的1CAboutDlg//这个是关于对话框里面是构造和析构2CMainFrame //主框架`是在窗口生成之前准备工作全在这吗?3CTestApp//这个是什么`initlnstance()在这里也是初始化什么对象? 4CTestDoc//这是文档`是管理哪些文档`对初学者来说很少用呐 ?5CTestView视图`这个常用 OnDraw我了解一些`我想知道`是不是默认就调用一次? 还有个问题啊`我想加个音乐`虽然加成功了`但是`我一直不明白加在哪个函数里`运行就有音乐?看过孙鑫的教程后来忘了`各位高手各抒已见,互相学习LZ需要系统地学习一下。

CTestApp是基于WinApp的,WinApp封装了程序的主入口WinMain,WinMain就和c语言的main函数地位一样,是Win32程序的入口。

在MFC的封装中,一个程序启动,Windows调用WinMain,这个WinMain函数现在由MFC事先写好藏好了,你不能也不需要修改,在这个预定义的WinMain里面会调用CWinApp的InitInstrance函数。

MFC文档与视图深入详解

1.1 MFC 文档视图结构程序结构总揽当我们使用MFC AppWizard 生成一个MFC 程序,选用所有默认的设置(当然也是Multiple Documents ,本文讨论主要基于Multiple Documents ,对于Single Document 情况仅以简单表述提及,皆因后者和前者很多相似相同之处,但前者更为复杂,并且更加常用。

),假设你的程序名称为 A ,则你会得到CMainFrame 、CChildFrame 、CAboutDlg 、CADoc 、CAView 、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 的构造函数中指定。

MFC学习笔记

MFC程序也有一个WinMain函数,这个函数是我们在编译链接的时候由链接器将WinMain函数链接进来的。

这个函数在APPMODUL.CPP中。

带有Afx的属于应用程序框架类的函数,应用程序框架是辅助我们生成应用程序的框架模型,这个框架模型把很多类或者类与类之间做了一个有机的集成提供给我们,我们可以根据框架模型提供的类库来设计我们自己的应用程序,Af即Application frame 看看这些类如何和我们WinMain函数关联到一起的?CmainFrame的名字是不会变的,其它的都是C+工程名+App/Doc/View命名。

class CTestApp : public CwinApp,可以看到CtestApp是从CwinApp派生出来的。

当我们双击CtestApp这个类时,我们可以看到VC++6.0上面显示我们进入了Test.h头文件中,当把CtestApp展开时,然后双击任何一个函数名,包括构造函数名,析构函数名…我们可以看到VC++6.0上面显示我们进入了Test.cpp源文件中。

且这种情况和我们直接从Fileview 资源卡中直接进入相应的头文件和源文件是一样的效果。

其它类也是相似的操作进入头文件和源文件。

不管是全局变量还是在全局对象CTestApp theApp;,它们都是在程序运行之前,也就是在入口函数WinMain函数加载之前,就已经为它们分配好了内存空间,作为全局函数,就要调用构造函数创建内存空间。

所以是先运行全局对象CTestApp theApp,调用它的构造函数,然后才运行WinMain。

为什么要定义一个全局对象呢?为什么要让它在WinMain之前完成呢?全局对象theApp又有什么作用?CtestApp是从CwinApp派生出来的,theApp是应用程序对象,是一个全局对象,每一个MFC程序当中有且仅有一个从CwinApp派生出来的类,也只能有一个应用程序类实例化的对象,它就表示了我们应用程序本身。

MFC应用程序的类型

MFC应用‎程序类型
●单文档支持‎文档-视图架构,数据的保存‎--(读取--修改)文档类功能‎--显示(视图类功
能‎),比较方便。

单文档类似‎“记事本”这样的应用‎程序,是文件处理‎软件的开发‎基础,只是每个应‎用程序仅处‎理一个文档‎(与多文档相‎比较)。

●基于对话框‎,主窗口是对‎话框类型,可以方便的‎使用控件,所见即所得‎的编程,比较方
便。

基于对话框‎类似“计算器”这样的应用‎程序,没有需要处‎理的文档,一般是工具‎软件的开发‎基础。

MFC应用‎程序
MFC应用‎程序主要分‎为以下三类‎,对比通常的‎应用程序,变化的地方‎如下:1 MFC的控‎制台程序
2 MFC的动‎态库和静态‎库
3 MFC应用‎程序。

MFC中的MainFrameDlg,App,Doc,View的关系

MFC中的MainFrameDlg,App,Doc,View的关系MFC中的MainFrame Dlg,App,Doc,View的关系MainFrame: 主框架类Dlg是Dialog 的缩写,表示对话框本身App类就是这个SDI作为"程序"的入口,有点像c的Main函数,它不是从CWND中派生出来的。

App表示应用程序本身。

View表示视图类,负责显示数据,提供编辑数据、修改数据的功能。

它是指编辑区里面的事就是那块白色的中间区域,负责绘制和响应一些消息Doc表示文档类,提供对数据的保存和加载。

有点像数据库,保存着编辑数据,用于view的Redraw的时候用,还有保存文件。

一般动态的编辑数据都放在Doc里面。

他也不是从CWND中派生出来的,没有继承MessageBox函数,可以用AfxMessageBox函数。

1) 在View中获得Doc指针2) 在App中获得MainFrame指针3) 在View中获得MainFrame指针4) 获得View(已建立)指针5) 获得当前文档指针6) 获得状态栏与工具栏指针7) 获得状态栏与工具栏变量8) 在Mainframe获得菜单指针9) 在任何类中获得应用程序类10) 从文档类取得视图类的指针(1)11) 在App中获得文档模板指针12) 从文档模板获得文档类指针13) 在文档类中获得文档模板指针14) 从文档类取得视图类的指针(2)15) 从一个视图类取得另一视图类的指针VC中编程对于刚刚开始学习的同学,最大的障碍和问题就是消息机制和指针获取与操作。

其实这些内容基本上是每本VC学习工具书上必讲的内容,而且通过MSDN很多问题都能解决。

下面文字主要是个人在编程中指针使用的一些体会,说的不当的地方请指正。

一般我们使用的框架是VC提供的Wizard生成的MFC App Wizard(exe)框架,无论是多文档还是单文档,都存在指针获取和操作问题。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

MFC中Doc,View,MainFrmae,App各指针的互相获取1) 在View中获得Doc指针2) 在App中获得MainFrame指针3) 在View中获得MainFrame指针4) 获得View(已建立)指针5) 获得当前文档指针6) 获得状态栏与工具栏指针7) 获得状态栏与工具栏变量8) 在Mainframe获得菜单指针9) 在任何类中获得应用程序类10) 从文档类取得视图类的指针(1)11) 在App中获得文档模板指针12) 从文档模板获得文档类指针13) 在文档类中获得文档模板指针14) 从文档类取得视图类的指针(2)15) 从一个视图类取得另一视图类的指针VC中编程对于刚刚开始学习的同学,最大的障碍和问题就是消息机制和指针获取与操作。

其实这些内容基本上是每本VC学习工具书上必讲的内容,而且通过MSDN很多问题都能解决。

下面文字主要是个人在编程中指针使用的一些体会,说的不当的地方请指正。

一般我们使用的框架是VC提供的Wizard生成的MFC App Wizard(exe)框架,无论是多文档还是单文档,都存在指针获取和操作问题。

下面这节内容主要是一般的框架,然后再讲多线程中的指针使用。

使用到的类需要包含响应的头文件。

首先一般获得本类(视,文档,对话框都支持)实例指针this,用this的目的,主要可以通过类中的函数向其他类或者函数中发指针,以便于在非本类中操作和使用本类中的功能。

1)在View中获得Doc指针CYouSDIDoc *pDoc=GetDocument();一个视只能有一个文档。

2) 在App中获得MainFrame指针CWinApp 中的m_pMainWnd变量就是MainFrame的指针也可以:CMainFrame *pMain =(CMainFrame *)AfxGetMainWnd();3) 在View中获得MainFrame指针CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd;4) 获得View(已建立)指针CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd; CyouView *pView=(CyouView *)pMain->GetActiveView();5) 获得当前文档指针CDocument * pCurrentDoc =(CFrameWnd *)m_pMainWnd->GetActiveDocument();6) 获得状态栏与工具栏指针CStatusBar * pStatusBar=(CStatusBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_STATUS_BAR);CToolBar * pToolBar=(CtoolBar *)AfxGetMainWnd()->GetDescendantWindow(AFX_IDW_TOOLBAR);7) 如果框架中加入工具栏和状态栏变量还可以这样(CMainFrame *)GetParent()->m_wndToolBar;(CMainFrame *)GetParent()->m_wndStatusBar;8) 在Mainframe获得菜单指针CMenu *pMenu=m_pMainWnd->GetMenu();9) 在任何类中获得应用程序类用MFC全局函数AfxGetApp()获得。

10) 从文档类取得视图类的指针我是从/soft/program/article/vc/vc405.html学到的,从文档获得视图类指针目的一般为了控制同一文档的多个视图的定位问题,我的体会特别是文字处理CEditView当产生多个视图类时,这个功能是非常需要的。

CDocument类提供了两个函数用于视图类的定位:GetFirstViewPosition()和GetNextView()virtual POSITION GetFirstViewPosition() const;virtual CView* GetNextView(POSITION& rPosition) const;注意:GetNextView()括号中的参数用的是引用方式,因此执行后值可能改变。

GetFirstViewPosition()用于返回第一个视图位置(返回的并非视图类指针,而是一个POSITION类型值),GetNextView()有两个功能:返回下一个视图类的指针以及用引用调用的方式来改变传入的POSITION类型参数的值。

很明显,在Test程序中,只有一个视图类,因此只需将这两个函数调用一次即可得到CTestView的指针如下(需定义一个POSITION结构变量来辅助操作):CTestView* pTestView;POSITION pos=GetFirstViewPosition();pTestView=GetNextView(pos);这样,便可到了CTestView类的指针pTestView.执行完几句后,变量pos=NULL,因为没有下一个视图类,自然也没有下一个视图类的POSITION.但是这几条语句太简单,不具有太强的通用性和安全特征;当象前面说的那样,当要在多个视图为中返回某个指定类的指针时,我们需要遍历所有视图类,直到找到指定类为止。

判断一个类指针指向的是否某个类的实例时,可用IsKindOf()成员函数时行检查,如:pView->IsKindOf(RUNTIME_CLASS(CTestView));即可检查pView所指是否是CTestView类。

有了以上基础,我们已经可以从文档类取得任何类的指针。

为了方便,我们将其作为一个文档类的成员函数,它有一个参数,表示要获得哪个类的指针。

实现如下:view plaincopy to clipboardprint?CView* CTestDoc::GetView(CRuntimeClass* pClass){CView* pView;POSITION pos=GetFirstViewPosition();while(pos!=NULL){pView=GetNextView(pos);if(!pView->IsKindOf(pClass))break;}if(!pView->IsKindOf(pClass)){AfxMessageBox("Connt Locate the View.¥r¥n "); return NULL;}return pView;}CView* CTestDoc::GetView(CRuntimeClass* pClass){CView* pView;POSITION pos=GetFirstViewPosition();while(pos!=NULL){pView=GetNextView(pos);if(!pView->IsKindOf(pClass))break;}if(!pView->IsKindOf(pClass)){AfxMessageBox("Connt Locate the View.¥r¥n ");return NULL;}return pView;}其中用了两次视图类的成员函数IsKindOf()来判断,是因为退出while循环有三种可能:1.pos为NULL,即已经不存在下一个视图类供操作;2.pView已符合要求。

1和2同是满足。

这是因为GetNextView()的功能是将当前视图指针改变成一个视图的位置同时返回当前视图指针,因此pos是pView的下一个视图类的POSITION,完全有可能既是pos==NULL又是pView符合需要。

当所需的视图是最后一个视图是最后一个视图类时就如引。

因此需采用两次判断。

使用该函数应遵循如下格式(以取得CTestView指针为例):CTestView* pTestView=(CTestView*)GetView(RUNTIME_CLASS(CTestView)); RUNTIME_CLASS是一个宏,可以简单地理解它的作用:将类的名字转化为CRuntimeClass为指针。

至于强制类型转换也是为了安全特性考虑的,因为从同一个基类之间的指针类型是互相兼容的。

这种强制类型转换也许并不必要,但能避免一些可能出现的麻烦。

3.从一个视图类取得另一视图类的指针综合1和2,很容易得出视图类之间互相获得指针的方法:就是用文档类作中转,先用1的方法得到文档类的指针,再用2的方法,以文档类的视图定位函数取得另一个视图类。

同样,可以实现成一个函数:(假设要从CTestAView中取得指向其它视图类的指针)view plaincopy to clipboardprint?CView* CTestAView::GetView(CRuntimeClass* pClass){CTestDoc* pDoc=(CTestDoc*)GetDocument();CView* pView;POSITION pos=pDoc->GetFirstViewPosition();while(pos!=NULL){pView=pDoc->GetNextView(pos);if(!pView->IsKindOf(pClass))break;}if(!pView->IsKindOf(pClass)){AfxMessageBox("Connt Locate the View.");return NULL;}return pView;}CView* CTestAView::GetView(CRuntimeClass* pClass){CTestDoc* pDoc=(CTestDoc*)GetDocument();CView* pView;POSITION pos=pDoc->GetFirstViewPosition();while(pos!=NULL){pView=pDoc->GetNextView(pos);if(!pView->IsKindOf(pClass))break;}if(!pView->IsKindOf(pClass)){AfxMessageBox("Connt Locate the View.");return NULL;}return pView;}这个函数和2中的GetView()相比,一是多了第一句以取得文档类指针,二是在GetFirstViewPosition()和GetNextView()前加上了文档类指针,以表示它们是文档类成员函数。

相关文档
最新文档