[转载]VC 和 MFC 的一些常见问题

转载 2004年09月06日 19:21:00

VC 和 MFC 的一些常见问题

Microsoft Corporation

版本5.0,97年5月15日

如何抛出(throw)由CUserException派生的异常?

当我试图捕获(catch)一个派生类异常时,我得到以下错误"error C2039:'classCMyException': is not a member of 'CMyException' 'classCMyException': undeclared identifier 'IsKindOf': cannot convert parameter 1 from 'int*' to 'const struct CRuntimeClass*"

你必需通过使用DECLARE_DYNAMIC()和IMPLEMENT_DYNAMIC()宏来使你的CMyException类可以动态地创建。CATCH宏希望能够得到关于被抛出类的运行时刻信息。

异常类一定要从CUserException中派生出来吗?

不,CUserException中的"User"仅仅指用户产生的异常。而把它当作你所能派生的唯一异常是种常见的误解。

如何从HDC建立一个CDC类?

有时Windows API将会给你一个DC句柄,你可以通过它建立一个CDC类。例如:下拉式列表、组合框和按钮。通过hDC你将接收到绘制消息。下面是将HDC转换成你更熟悉的CDC的程序段。你也可以将该技巧用在其他任何MFC类和Windows句柄的转换中。


另一个方法是调用CDC类的FromHandle方法:
            
目前还不清楚哪种方法更优越―使用FromHandle()的错误也许会更少些,因为它不要求你分离(detach)句柄。

如何从磁盘上读取256色位图文件?

当前,MFC并不支持直接读取和显示DIB文件和BMP文件。然而,有很多样例应用程序能够说明如何完成该项任务。第一个例子是MFC样例程序DIBLOOK。样例MULTDOCS用DIBLOOK提供的相同源代码来读取并显示DIB文件和BMP文件。其他两个VC++中附带的例子是SDK软件包中的DIBVIEW程序和SHOWDIB程序。

如何改变一个视图的大小?

通常,你可以调用函数MoveWindow()来改变窗口的大小。在用MFC库开发的应用程序中, 视图是被框架窗口所围绕的一个子窗口。为了改变一个视图的大小,你可以通过调用函数GetParentFrame()来得到框架窗口的指针,然后调用函数MoveWindow()来改变父窗口的大小。当父框架窗口改变大小时,视图也会自动地改变大小来适应父窗口。

如何改变一个CFormView的大小?

要想详细了解的话,你可以看有关Visual C++基础知识的文章Q98598 《Using CFormView in SDI and MDI Applications》。基本上,在从CFormView类派生出来的类中,你必须覆盖函数OnInitialUpdate()。其他有关建立CFormView的细节问题,可以从该文章中获得。

在类ClikethisView中声明如下函数:
  

在ClikethisView的代码中,函数如下:

  
  
 

如何使用一个文档模板的新视图?

在用AppWizard创建的应用程序中,你有两种选择:改变当前视图的派生关系或者建立一个新视图并且在你的MDI程序中同时利用新视图和原先的视图。


为了创建一个新视图,你可以用ClassWizard由CView派生一个新的类。当新类创建以后,利用新视图或修改由AppWizard提供的视图,两者的步骤是相同的。


修改视类的头文件,从而将所有对CView类的引用改名为你所想要的名称。本例中的类由CScrollView派生而来。通常,这个步骤包括对类的改变,视类将由如下方式派生而来:
class CMyView : public CScrollView


修改视类的实现文件,从而将所有对CView的引用改名为你所想要的名称。这包括将IMPLEMENT_DYNCREATE那一行的语句改为:
IMPLEMENT_DYNCREATE(CMyView, CScrollView)


将BEGIN_MESSAGE_MAP那一行的语句改为:
BEGIN_MESSAGE_MAP(CMyView, CScrollView)


并且将其他所有的CView改成CScrollView.


假如你修改的视图是由AppWizard生成的,那么就不需要作更多的修改了。而如果你在创建一个新视图,先在CWinApp::InitInstance()函数中找到对AddDocTemplate()函数的调用。AddDocTemplate()函数的第三个参数是RUNTIME_CLASS(CSomeView),用CMyView来代替CSomeView,就可以将当前视图改为新视图。在MDI应用程序中,你可以增加第二个AddDocTemplate()函数调用来使用多视图类型,将RUNTIME_CLASS(CSomeView)改为RUNTIME_CLASS (CMyView)。

要想获得更多的信息请参阅Q99562中相关文章《Switching Views in a Single Document Interface Program》 。

如何改变视图的背景色?

你可以通过处理WM_ERASEBKGND消息来改变CView、CFrameWnd或CWnd对象的背景色。请看如下的程序段:

  
  
而我则用如下方法解决这个问题:
  

如何得到当前视图?

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

简单说来,用:

      

和:

      

来得到文档和视图。一个好的方法是将它们封装在你的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程序中得到所有的视图?

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

   
  

你还需要与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()函数来注册。例如:

最后,将定制的序列化和绘图代码加入到你的新文档和视图类中。 

如何得到一个打开文档的列表?

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

  
  

在参考手册或在线帮助中,有两个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版本请参考下面:

  

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

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

VC 和 MFC 的一些常见问题

 如何抛出(throw)由CUserException派生的异常? 当我试图捕获(catch)一个派生类异常时,我得到以下错误"error C2039:classCMyException: is no...
  • clovejava
  • clovejava
  • 2006-09-07 14:04:00
  • 442

VC和MFC的一些常见问题

  VC和MFC的一些常见问题 2002-11-2 ...
  • JamesXing
  • JamesXing
  • 2007-08-03 14:23:00
  • 687

转载一篇超牛的文章,给自己留个纪念

前言 我2002年大学毕业,一转眼就已过去两年多。这两年多来,我接触了三教九流的人,经历了五花八门的事,懵懵懂懂地走了很多弯路,跌跌撞撞地收获了几丝精彩。不知不觉之中,很多原本认为是真理的东西瓦解成了...
  • zhouhong0801
  • zhouhong0801
  • 2008-03-11 15:20:00
  • 6300

vc常见问题

  • 2008年03月22日 13:53
  • 131KB
  • 下载

vc6无需编译预览对话框布局界面的办法

在想查看vc6对话框界面布局结果时,你可能会去编译运行一下程序,然后观察结果,其实这样速度比较慢,因为有改动就会重新编译。切换到对话框布局界面,这时菜单里会多出Layout菜单,单击它,在下拉菜单里单...
  • chinaboyzyq
  • chinaboyzyq
  • 2016-09-27 10:45:22
  • 576

c语言模块化(转载)

C语言模块化 (转载)  在C语言的应用领域,如通讯领域和嵌入式系统领域,一个的软件项目通常包含很多复杂的功能,实现这个项目不是一个程序员单枪匹马可以胜任的,往往需要一个团队的有效合作,另外,在一个以...
  • Albinzhiyu
  • Albinzhiyu
  • 2011-06-20 17:28:00
  • 459

MFC框架界面开发(三):多文档界面

介绍多文档界面中,一个主框架内可以有多个子框架。每个子框架可以看成是一个单文档的主框架。...
  • qq_21445981
  • qq_21445981
  • 2017-10-17 20:30:27
  • 218

博客被封杀,暂时使用此博客。

百度博客被封杀了,所有文章丢失! 暂时使用CSDN的。之前做过连接的兄弟请留言,我会添加上去! 谢谢~...
  • god_7z1
  • god_7z1
  • 2011-01-20 21:48:00
  • 776

k3一些常见问题集锦

  • 2010年06月28日 17:28
  • 3.31MB
  • 下载

servlet的一些问题和解答

1.servlet是什么 2.servlet的生命周期以及和CGI的区别 3.重定向和请求转发 4.如何实现servlet的单线程模式 5.servlet页面间对象传递的方法有几种 6.JS...
  • u010215407
  • u010215407
  • 2016-05-11 19:06:03
  • 1327
收藏助手
不良信息举报
您举报文章:[转载]VC 和 MFC 的一些常见问题
举报原因:
原因补充:

(最多只允许输入30个字)