初始化C++类成员和在你的MFC应用中加入位置栏
alog除m_ofn外还有其它数据成员,它们将被新的OPENFILENAME的成员覆盖。不再耽搁了,我开始使用极端的方法避开这个问题。我考虑可以做些什么,类似于MFC中使用CpropertyPage那样。PROPSHEETPAGE和PROPSHEETHEADER的大小在从Windows 95到Windows 98的过程中的某处增加了,这是为了支持wizard风格的页面。为了支持新膨胀的结构,MFC提供了CpropertyPageEx和CpropertySheetEx。最初的类(不带Ex的)仍然使用旧的结构;而新的类使用新的结构。这是一种杂凑,尤其是因为afxdlgs.h具有自己的旧的结构的定义(AFX_ OLDPROPSHEETPAGE和AFX_OLDPROPSHEETHEADER),但是这样却行得通。
我对CfileDialog做了同样的事情。首先我派生一个新的CfileDialogEx类,它带有一个新的m_ofn,包含着新的OPENFILENAMEEX结构,我模仿0x500版本加以定义。我加入这3个新的成员并且使用m_ofn.重写了CfileDialog函数。不幸的是,因为大多数的MFC代码是固定的,没有任何虚拟功能,这就意味着复制原来的整个类。但是我已经下了决心。 在我认为已经找到了m_ofn出现的所有地方以后,我重写了它,高高兴兴的编译了我的代码(在Windows 98上),然后运行——结果发现我得到的仍是旧风格的对话框。而起,有一个谜团我忘了考虑:如果Windows 2000使用lStructSize来决定运行那个Open对话框,为什么Windows 98的应用程序(象Notepad)在Windows 2000下运行时得到了新的对话框呢?啊!随Windows 98出现的NOTEPAD.EXE显然在lStructSize 上有旧的OPENFILENAME的大小,因此Windows 2000必须使用lStructSize之外的某种东西来决定运行那个对话框。 到这里,我决定回过头去重新考虑问题。我将MFC放到一边,尝试直接调用GetOpenFileName。我重写了我的应用程序的OnFileOpen: void CMyApp::OnFileOpen()
因为贯穿本练习,我使用了旧的0x400版本的SDK文件(因为我希望应用程序既可以在Windows 2000上运行,也可以在Windows 9x上运行),ofn.lStructSize就有了旧的大小。当我编译并运行时,我在Windows 98上得到了旧的对话框,而在Windows 2000上得到了新的对话框——就象Notepad一样!因此可以说,实际上,Windows 2000足够精明的为旧的应用使用新的对话框——但不是旧的MFC应用。它毫无意义。一个MFC应用的不同之处在哪里呢? 一定是标志。为了发现真相,我在OPENFILENAME结构中手工添加了不同的标志,直到我的程序产生了不带Places栏目的旧风格的窗口。你瞧,当我为ofn.Flags加入标志OFN_ENABLEHOOK时,我的对话框回到了从前。我将此奇怪的行为报告给Redmondtonians,他们证实“这种行为是设计的”。 那么,Windows 2000判断OPENFILENAME的大小以及对话框是否使用hook过程。如果OPENFILENAME有旧的大小,Windows 2000使用OFN_ENABLEHOOK来决定运行哪个对话框。如果OPENFILENAME使用hook过程(或者设置了ORN_ENABLETEMPLATE),Windows 2000按照旧的风格显示对话框;否则,显示新的对话框。这就解释了为什么MFC应用显示了旧的对话框——因为CfileDialog,就象所有MFC的公用对话框一样,使用hook过程。这是MFC将公用对话框嵌入它的消息映射系统的方式,它用同样的方式使用AfxWndProc嵌入其它的窗口。 现在你看到了结果:你给迷惑了。在一个MFC应用中得到新风格的对话框的唯一的办法是完全绕开CfileDialog,直接调用GetOpenFileName,并且不使用hook过程。即使你用新的SDK文件和WINVER = 0x500编译你的应用,你仍不能使用MFC,因为它的库 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |