再谈 Windows 2000 “打开”文件对话框

不见面看不看

不见面看不看

2016-01-29 11:50

再谈 Windows 2000 “打开”文件对话框,再谈 Windows 2000 “打开”文件对话框

再谈 Windows 2000 “打开”文件对话框

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/cyuyanjiaocheng/)

编译/zxn

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/cyuyanjiaocheng/) 本文代码例子

    不久以前,VC知识库曾探讨过如何在MFC应用中打开Windows 2000风格的“文件/打开”对话框(类似Outlook Express左边的Places Bar)。最近又有许多人问及这方面的问题,也许我在那篇文章中讲的不是很清楚,所以这次在本文中重申这个问题。
     Windows 2000有个新的“Open”对话框(图一),这个对话框的左边有一个Places Bar,要想让这个对话框出现,必须在::GetOpenFileName函数中传递OPENFILENAME结构,这个结构隐藏在MFC的CFileDialog类中。问题是这个结构最新的版本(即Windows 2000中的5.0及以后的版本)有附加的成员,增加它的尺寸。当你(或MFC)调用::GetOpenFileName之前,你必须初始化结构OPENFILENAME的第一个成员-lStructSize-它决定了OPENFILENAME结构的大小。如果你在Windows 2000(_WIN32_WINNT >= 0x0500)中编译,你会得到结构的最新尺寸;如果你在较早的Windows版本中编译,你却得到旧的结构尺寸。

图一 新的“打开”对话框

     当你在Windows 95, Windows 98或Windows NT 4.0运行应用程序的时候,你必须使用旧的结构尺寸。而在Windows 2000中,你既可以使用旧的结构尺寸,也可以使用最新的结构尺寸。如果lStructSize是新的尺寸,Windows 2000打开新风格的对话框。如果lStructSize是旧的尺寸,Windows 2000还检查结构OPENFILENAME中其它的信息:即如果对话框有“钩子”(hook)功能标志(OFN_ENABLEHOOK)或模板标志(OFN_ENABLETEMPLATE),Windows 2000打开旧风格的对话框,否则打开新风格的对话框。这多少使人感觉有些混乱。无论你如何做,MFC42.DLL都被用旧的结构尺寸编译,并且MFC使用一个吊钩过程(OFN_ENABLEHOOK)将对话框连接到你的消息映射......。
     天无绝人之路,一位名叫Michael Lemley哥儿们给了我一个问题的解决方案,其基本思路是:在MFC的CFileDialog中增加一个新成员-m_ofnEx,诱使MFC使用这个成员。为了保证代码能在所有的Windows版本中运行,lStructSize 结构成员必须根据实际运行的Windows版本被正确初始化。Michael的方法有两个地方值得商榷:一个是拷贝大量的MFC代码;一个是运行时检查操作系统版本。修改工作是在新类CFileDialogEx中进行的,

// OPENFILENAME 结构的 Windows 2000 版本struct OPENFILENAMEEX : public OPENFILENAME {   void *        pvReserved;  DWORD         dwReserved;  DWORD         FlagsEx;};// CFileDialog 类的 Windows 2000 版本class CFileDialogEx : public CFileDialog {protected:    OPENFILENAMEEX m_ofnEx; // 新增成员};
    OPENFILENAME 的定义在commdlg.h文件中,而 OPENFILENAMEEX 是模仿 OPENFILENAME 的本地(局部)定义。OPENFILENAMEEX有三个新成员。为了使用这个新结构,CFileDialogEx 重写 DoModal。你必须从CFileDialog 拷贝整个函数到 CFileDialogEx,代码细节如下:
添加 m_ofnEx int CFileDialogEx::DoModal(){......    // 前面是 MFC 代码        // 拷贝 m_ofn ==> m_ofnEx 并设置    memset(&m_ofnEx, 0, sizeof(m_ofnEx));    memcpy(&m_ofnEx, &m_ofn, sizeof(m_ofn));    if (IsWin2000())        m_ofnEx.lStructSize = sizeof(m_ofnEx);    // 使用 m_ofnEx 运行 "打开"或"保存"对话框    int nResult;    if (m_bOpenFileDialog)        nResult = ::GetOpenFileName((OPENFILENAME*)&m_ofnEx);    else        nResult = ::GetSaveFileName((OPENFILENAME*)&m_ofnEx);    // 回拷 m_ofnEx ==> m_ofn    memcpy(&m_ofn, &m_ofnEx, sizeof(m_ofn));   m_ofn.lStructSize = sizeof(m_ofn);......}
    上述代码的基本思路是在调用 GetOpenFileName 或 GetSaveFileName 之前先将 m_ofn 拷贝到 m_ofnEx,调用完成后再拷回去。其中最重要的是其第一个结构成员----lStructSize 按照实际运行的操作系统版本被初始化。获取操作系统版本参见 IsWin2000 函数:
IsWin2000函数实现////////////////////////////////////////////////////////////////// 检测操作系统版本(Windows 2000 或以后)的函数//BOOL IsWin2000 () {   OSVERSIONINFOEX osvi;   BOOL bOsVersionInfoEx;   // 尝试调用 GetVersionE      
展开更多 50%)
分享

猜你喜欢

再谈 Windows 2000 “打开”文件对话框

C语言教程 C语言函数
再谈 Windows 2000 “打开”文件对话框

使用Windows API函数显示打开文件对话框

电脑网络
使用Windows API函数显示打开文件对话框

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

再谈 CFileDialog 对话框的定制

C语言教程 C语言函数
再谈 CFileDialog 对话框的定制

打开windows运行对话框的js

Web开发
打开windows运行对话框的js

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

Windows 文件对话框使用技巧集锦

windows 操作系统
Windows 文件对话框使用技巧集锦

再谈客户区对话框拖动操作

C语言教程 C语言函数
再谈客户区对话框拖动操作

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

轻松实现类VC界面

轻松实现类VC界面

PSV《高达破坏者2》新手入门推荐分享

PSV《高达破坏者2》新手入门推荐分享
下拉加载更多内容 ↓