AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > VC编程

VC 和 MFC 的一些常见问题

51自学网 2015-08-30 http://www.wanshiok.com

如何得到当前视图?

最佳方法是将视图当作一个参数来传递。如果不能这样做,但你确信它是当前激活文档和当前激活视图的话,你也可以得到该视图。具体细节见Visual C++文章Q108587《Get Current CDocument or CView from Anywhere》。

简单说来,用:

  ((CFrameWnd*) AfxGetApp()->m_pMainWnd))->GetActiveDocument()

和:

  ((CFrameWnd*)(AfxGetApp()->m_pMainWnd))->GetActiveView()


来得到文档和视图。一个好的方法是将它们封装在你的CMyDoc和CMyView类的静态函数中,并且核对它们是否属于正确的RUNTIME_CLASS。然而,假如这个视图不是当前激活视图或者你在运行OLE本地激活,这样将不成功。
如何在一个文档中建立多个视图?

CDocTemplate::CreateNewFrame()函数创建MFC MDI应用程序中的文档的附加视图。为了调用该函数,要指定一个指向CDocument对象(指将为之建立视图的文档)的指针和一个指向可从中复制属性的框架窗口的指针。一般情形下,该函数的第二个参数为NULL。

当应用程序调用函数CreateNewFrame()时,该函数就创建一个框架窗口和在该窗口内的视图。框架窗口和它的视图的类型由与CreateNewFrame()函数调用指定的文档相关的文档摸板(CDocTemplate)决定。

Visual C++中的CHKBOOK MFC样例程序也演示了如何为文档建立附加的框架和视图。检查CHKBOOK.CPP文件中的CChkBookApp::OpenDocumentfile()函数。

另一个用函数CreateNewFrame()的例子是MULTVIEW样本程序。

CreateNewFrame()函数建立了一个框架和一个视图,而不仅仅是一个视图。假如CreateNewFrame()函数不能完全符合你的需要,可参考CreateNewFrame()函数的源程序来了解对建立结构和视图所必须的步骤。

如何在MDI程序中得到所有的视图?

你必须用一些文档中没有记载的函数:

CDocument::GetFirstViewPosition(); // DOCCORE.CPP
CDocument::GetNextView(); // DOCCORE.CPP
CMultiDocTemplate::GetFirstDocPosition(); // DOCMULTI.CPP
CMultiDocTemplate::GetNextDoc(); // DOCMULTI.CPP
 

你还需要与CWinApp的成员m_templateList打交道。
注意:在MFC 版本4.0中已改变。现在已经有一个叫CDocManager的类可以帮助你显示所有的视图和文档。请参考《MFC Internals》获得更详细的信息。

如何建立一个可用鼠标拉动的CScrollView类

在CIS上从MSMFC库下载AUTOSV.LZH。这个程序告诉你如何实现一个辅助消息循环来管理鼠标的活动,并提供了钩挂来对代码进行定制。这是一个免费软件。

一定要用视图/文档结构吗?

MFC并不一定要求你使用文档/视图结构。查看HELLO、 MDI和HELLOAPP例子―它们就没有用那种结构。大多数MFC特性都可以在非文档/视图应用程序中得到运用。但是当你不用文档 / 视图结构时,你确实会失去一些特性,例如打印预览和许多OLE特性。

如何得到当前文档?

请详细参阅"如何得到当前视图?"章节。

文档何时被析构?

在SDI程序中,程序退出后文档就被删除。在MDI程序中,与该文档相关的最后一个视图关闭时文档就被删除。为了在SDI和MDI中同时用这个文档,你应该在虚函数DeleteContents()函数中删除该文档的数据,而不是在析构器中。

如何建立多文档?

为了加入对附加文档类型的支持,你可以在CWinApp派生类中创建和注册附加CmultiDocTemplate对象。这种方法已经在MULTDOCS样例程序中得以说明。将一个附加文档类型加入到MFC程序的一般步骤如下:

用AppWizard来创建一个新的文档类和视图类。
用资源编辑器增加新的资源字串来支持新的文档类。要想知道关于文档样板字符串格式的更多内容,请参阅"如何理解文档样板字符串"。

用资源编辑器增加附加的应用程序图标和菜单资源。注意,这些资源中每一个的ID都必须与在步骤2中创建的文档模板字符串的ID是相同的。这个ID被CmultiDocTemplate类用来识别与附加文档类型相关的资源。

在应用程序的InitInstance()函数中,创建了另一个CMultiDocTemplate对象并且用CWinApp::AddDocTemplate()函数来注册。例如:

CMultiDocTemplate* pDocTemplate2 = new CMultiDocTemplate(
IDR_DOC2TYPE, RUNTIME_CLASS(CDoc2),
RUNTIME_CLASS(CMDIChildWnd),RUNTIME_CLASS(CView2));
AddDocTemplate(pDocTemplate2);

最后,将定制的序列化和绘图代码加入到你的新文档和视图类中。
如何得到一个打开文档的列表?

下面的程序段指明如何得到用CDocTemplate对象建立的所有文档的指针列表。
下面的程序段中,CMyApp由CWinApp派生而来。变量m_templateList是一个CPtrList对象,它是CwinApp的成员变量,包含一个所有文档模板指针的列表。文档模板函数GetFirstDocPosition()和GetNextDoc()被用来在文档模板列表中进行迭代来得到每一个文档模板。

void CMyApp::GetDocumentList(CObList * pDocList)
{
  ASSERT(pDocList->IsEmpty());
  POSITION pos = m_templateList.GetHeadPosition();
  while (pos)
  {
   CDocTemplate* pTemplate =
    (CDocTemplate*)m_templateList.GetNext(pos);
   POSITION pos2 = pTemplate->GetFirstDocPosition();
   while (pos2)
   {
    CDocument * pDocument;
    if ((pDocument=pTemplate->GetNextDoc(pos2)) != NULL)
     pDocList->AddHead(pDocument);
   }
  }
}
 

在参考手册或在线帮助中,有两个CdocTemplate类的公共成员函数没有被说明。然而, 这些公共成员函数在CDocTemplate类中被定义,并且为在打开文档的列表中前后搜索提供了简单的支持。

这些函数如下:


Function virtual POSITION GetFirstDocPosition() const;
调用该函数得到在打开的文档列表中与模板相关联的第一个文档的位置。返回的POSITION的值能够被GetNextDoc成员函数反复使用。

Function Virtual CDocument* GetNextDoc(POSITION& rPosition) const;
rPostion是前面调用GetNextDoc 或GetFirstDocPosition成员函数返回的POSITION值。这个值不能是NULL。调用该函数来在所有打开的文档中进行迭代。该函数返回被rPosition所标识的文档并将rPosition设置为列表中的下一个文档的POSITION值。假如所检索的是列表中的最后一个文档,rPosition将被设为空值。

注意,这仅对MFC3.2版本或更低版本有效,对MFC4.0版本请参考下面:

void CMyApp::DoSomethingToAllDocs()
{
  CObList pDocList;
  POSITION pos = GetFirstDocTemplatePosition();
  while(pos)
  {
   CDocTemplate* pTemplate = GetNextDocTemplate(pos);
   POSITION pos2 = pTemplate->GetFirstDocPosition();
   while(pos2)
   {
    CDocument* pDocument;
    if(pDocument = pTemplate->GetNextDoc(pos2))
     pDocList.AddHead(pDocument);
   }
  }
  if(!pDocList.IsEmpty()){
   pos = pDocList.GetHeadPosition();
  while(pos)
  { 
   //为每一个文档调用CDocument函数
   ( (CDocument*)pDocList.GetNext(pos) )
    ->UpdateAllViews(NULL);
  }
}

如何使我的程序在启动时不创建一个新文档?

在程序的InitInstance中的ProcessShellCommand函数之前加入: cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing

 

 
 
说明
:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。

上一篇:组件对象模型的规则  下一篇:借助DirectDraw技术实现对水波的计算机模拟