为了让VC6写出的程序也能与时俱进,其他的GUI且不说,单是这个打开文件对话框就得动下小手术,怎么说也得跟上XP系统的外观吧!但手术的前提是,不能影响文档文件打开后的一些序列化操作,这种要求就是当然不能随便给“打开”弄个命令相应,重新跳出个花哨的文件打开对话框,得弄出MFC对其处理的来龙去脉,经过简单的文件搜索,其脉络如下:
MFC默认处理“打开”菜单命令是CWinApp::OnFileOpen(),除此以外的文档关闭、保存等都是CDocument里的命令函数,为何这个打开要用CWinApp来处理,这个应该是为了利用文档模板来创建文档、视窗、框架提高便利吧,接下来CWinApp::OnFileOpen里调用m_pDocManager->OnFileOpen(),m_pDocManager是CWinApp的一个CDocManager类型指针,从其字面不难理解这是个什么东东,继续跟踪,发现CDocManager::OnFileOpen()主要有如下两个调用
CString newName;
if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,
OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL))
return; // open cancelled
AfxGetApp()->OpenDocumentFile(newName);
至此,应该知道下面该如何入手了,MFC是通过调用DoPromptFileName函数里的CFileDialog dlgFile(bOpenFileDialog)产生那个老土的对话框的,两种方案,一是改下DoPromptFileName里的弹出对话框的代码,这样一劳永逸,但这貌似会违反什么规则,微软如此权威,其源码岂能轻易改变呢,我是不会用此方法的;第二种方法当然就是自己处理菜单命令了,代码如下
void CxxxDoc::OnFileOpen()
{
// TODO: Add your command handler code here
CFileDialog OpenDlg(...);
int structsize=0;
DWORD dwVersion,dwWindowMajorVersion,dwWindowMinorVersion;
dwVersion=GetVersion();
dwWindowMajorVersion=(DWORD)(LOBYTE(LOWORD(dwVersion)));
dwWindowMinorVersion=(DWORD)(HIBYTE(LOWORD(dwVersion)));
if(dwVersion<0x80000000)
structsize=88;
else
structsize=76;
OpenDlg.m_ofn.lStructSize=structsize;
OpenDlg.DoModal();
...
CString newName=OpenDlg.GetPanthName();
AfxGetApp()->OpenDocumentFile(newName);
}
上述代码会使得文件对话框与时俱进了。
对于另存为、保存等操作的弹出对话框,据我跟踪MFC源码,只要重载CDocument的虚函数DoSave,即该函数里调用的
AfxGetApp()->DoPromptFileName(...)按上面同样的处理方式处置即可