MFC的CFileDialog和几个类之间的关系

学习了一段时间MFC了,原来总是模仿别人的程序做。不知其所以然,后面发现这些问题必须要解决。始终不可能迷迷糊糊的过关,于是乎在网上对一些函数进行了查找,并且结合之间的理解整理一下。主要是整理整理之间的思路。

一、CFileDialog

参考:http://blog.sina.com.cn/s/blog_4618b1720100edq8.html

1:构造

CFileDialog是常用的打开图形的对话框类,其一般的构造函数形式如下:

CFileDialog( BOOL bOpenFileDialog, LPCTSTRlpszDefExt = NULL, LPCTSTRlpszFileName = NULL, DWORDdwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTRlpszFilter = NULL, CWnd*pParentWnd = NULL );

在这里说明一下一些参数的含义:

第一个bOpenFileDialog为True时为打开对话框,为false为保存对话框。

第二个 lpszDefExt  是默认的后缀,lpszFileName 是默认的文件名字,这两个可以构成默认的打开和保存对象。当然其分开组合会更加多样化。

第三个dwFlags 这个是很重要的一个参数,其可以设置是打开文档的各种方式,其中最常用的就是选择多文档还是单文档。

第四个lpszFilter 这个也是重要的一个参数,其表示要过滤的打开文档。

第五个pParentWnd 不常用,默认为NULL。

2:修改

对于创建好了的CFlieDialog可以通过m_ofn结构体进行修改。其有一个很重要的参数lpstrFile,这个参数是用于保存Dialog本身以外的一些缓存信息。因为CFileDialog的内置文件缓存长度只有200,所以设定一个文件缓存来保证缓存的有效性(注意:必须先初始化为0)。其他常用的还有nMaxFile等等,这些可以通过VAssitX提示得到。

3:应用

CFileDialog定义了很多有用的函数,这些都可以通过VAssitX提示得到。注意在这里面他自己定义的或者说是常用的是通过加粗黑体表示的

其中常用的函数有:

CString CFileDialog::GetPathName( ) 得到完整的文件名,包括目录名和扩展名如:c:\test\test1.txt

CString CFileDialog::GetFileName( ) 得到完整的文件名,包括扩展名如:test1.txt
CString CFileDialog::GetExtName( ) 得到完整的文件扩展名,如:txt
CString CFileDialog::GetFileTitle ( ) 得到完整的文件名,不包括目录名和扩展名如:test1
POSITION CFileDialog::GetStartPosition( ) 对于选择了多个文件的情况得到第一个文件位置。
CString CFileDialog::GetNextPathName( POSITION& pos ) 对于选择了多个文件的情况得到下一个文件位置,并同时返回当前文件名。但必须已经调用过POSITION CFileDialog::GetStartPosition( )来得到最初的POSITION变量。

注意:其中GetStartPosition()和GetNextPathName()是必须在dwFlags选择多文档的时候才可以进行。他们的含义是得到选择的第一个和下一个文档的位置,如果是单文档就没有GetNextPathName()这一说了。

二、MFC中几个类之间的关系

参考:http://www.vckbase.com/index.php/wv/459

1:大关系
第一App类和CMainFrame类是第一级的,下面的CChildFrame类是第二级的, Doc类和View类是第三级的。但是App类不是和其他几个类一个系统的,他是用于整体管理的老大。第一级和第三级之间的上向下的联系必须通过第二级,而上向就不用,因为使用的是全局函数
1) View类和Doc类
a:View类中获得Doc类

CYouSDIDoc *pDoc=GetDocument();一个视只能有一个文档。
注注意:这里默认的是当前活动视图调用GetDocument,如果框架中有多个视图,可以通过选择视图来调用GetDocument函数,总之这里其实是View类的成员函数,这里理解类和对象的关系十分重要。

 b:Doc类中获得View类

CDocument类提供了两个函数用于视图类的定位:GetFirstViewPosition()和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类。
有了以上基础,我们已经可以从文档类取得任何类的指针。为了方便,我们将其作为一个文档类的成员函数,它有一个参数,表示要获得哪个类的指针。实现如下:

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\nhttp://www.VCKBASE.com");
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为指针。
至于强制类型转换也是为了安全特性考虑的,因为从同一个基类之间的指针类型是互相兼容的。这种强制类型转换也许并不必要,但能避免一些可能出现的麻烦。

c:View类获得View类

从一个视图类取得另一视图类的指针 综合1和2,很容易得出视图类之间互相获得指针的方法:就是用文档类作中转,先用1的方法得到文档类的指针,再用2的方法,以文档类的视图定位函数取得另一个视图类。同样,可以实现成一个函数:
(假设要从CTestAView中取得指向其它视图类的指针)

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()前加上了文档类指针,以表示它们是文档类成员函数。
有了此函数;当要从CTestAView中取得CTestBView的指针时,只需如下:

CTestBView* pTestbView=(CTestView*)GetView(RUNTIME_CLASS(CTestBView));


2):View类和MainFrame类

a:View获得MainFrame

这里是下级获得上级,一般只能借助全局函数。这里用CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd;

或者CMainFrame *pMain =(CMainFrame *)AfxGetMainWnd();

b:在MainFrame中获得View

这里是上级获得下级,可以用上级本身的函数就可以了。这里是用m_pMainWnd。

CMainFrame* pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd;//获得第一级

CMDIChildWnd* pChild=pMainFrame->MDIGetActive();//获得第二级

CyouView *pView=(CyouView *)pChild->GetActiveView();//获得第三级


3):Doc类和MainFrame类

a:Doc类中获得MainFrame类

同理,直接只能用全局函数。这里CMainFrame *pMain=(CmaimFrame *)AfxGetApp()->m_pMainWnd;

CMainFrame *pMain =(CMainFrame *)AfxGetMainWnd();

b:MainFrame类中获得Doc类

CDocument * pCurrentDoc =(CFrameWnd *)m_pMainWnd->MDIGetActive()->GetActiveDocument();


4):获得应用程序

用MFC全局函数AfxGetApp()获得

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值