我的代码如下,
CString str;
str.LoadString(IDS_SUPPORTED_FILES);
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY
|OFN_ALLOWMULTISELECT|OFN_EXPLORER,
str,pWnd);
if(dlg.DoModal()==IDOK)
{
POSITION pos=dlg.GetStartPosition();
while(pos!=NULL)
{
CString str=dlg.GetNextPathName(pos);
OpenFile(str,FALSE);
}
} 但是产生的还是老样子的对话框.
如果不用CFileDialog,而用API我知道怎么作.问题是用了MFC,我也添加了OFN_EXPLORER(这个是mfc默认的),但是还是那个对话框,好难看.
CString str;
str.LoadString(IDS_SUPPORTED_FILES);
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY
|OFN_ALLOWMULTISELECT|OFN_EXPLORER,
str,pWnd);
if(dlg.DoModal()==IDOK)
{
POSITION pos=dlg.GetStartPosition();
while(pos!=NULL)
{
CString str=dlg.GetNextPathName(pos);
OpenFile(str,FALSE);
}
} 但是产生的还是老样子的对话框.
如果不用CFileDialog,而用API我知道怎么作.问题是用了MFC,我也添加了OFN_EXPLORER(这个是mfc默认的),但是还是那个对话框,好难看.
解决方案 »
- 这样的脚本该如何编写
- ListControl 复选框变化如何通知主窗口
- 求助!关于单步调试中的问题!
- IWebBrowser2 的指针,能指向一个iframe么?怎么做到?
- media play 入门问题
- 在程序里用SQL创建表很简单,那么创建数据库呢??
- 寻求帮助,善良的人进!
- MFC实现图片格式转换的小问题
- 我在D版中看到VC++6.0中文版是一张盘还带语言帮助,不知是不是真的,能买吗?多谢!多谢!
- 我把一段用TC写的压缩代码加入了我的MFC工程中(ADD TO PROJECT)可是在编译时出现如下错误
- 求类似msn界面源代码或相关资料,高分相送!
- 在对话框中加入了一个richedit控件,程序运行后出现错误,编译时没有问题。
CString str;
str.LoadString(IDS_SUPPORTED_FILES);
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY
|OFN_ALLOWMULTISELECT|OFN_EXPLORER,
str,pWnd);
/////////////////////////////////////////////////
dlg.m_ofn.Flags=OFN_FILEMUSTEXIST|
OFN_EXPLORER|
OFN_ALLOWMULTISELECT |
//OFN_ENABLEHOOK|
OFN_HIDEREADONLY; if(dlg.DoModal()==IDOK)
{
POSITION pos=dlg.GetStartPosition();
while(pos!=NULL)
{
CString str=dlg.GetNextPathName(pos);
OpenFile(str,FALSE);
}
}
我用debug发现是没有OFN_ENABLEHOOK标志,但是添加上了后,assert虽然没了,新的界面也换成就得了。
在一个MFC应用中得到新风格的对话框的唯一的办法是完全绕开CFileDialog,直接调用GetOpenFileName,并且不使用hook过程。我也知道这样可以,但是,我前面已经说了,我只要添加上OFN_ENABLEHOOK标志,就可以出来新的对话框,只不过在debug下会出assert,released却没有问题,debug下忽略也可以。所以,我认为应该可以用CFileDialog的。我的问题是怎样用CFileDialog实现
DWORD lStructSize;
HWND hwndOwner;
HINSTANCE hInstance;
LPCTSTR lpstrFilter;
LPTSTR lpstrCustomFilter;
DWORD nMaxCustFilter;
DWORD nFilterIndex;
LPTSTR lpstrFile;
DWORD nMaxFile;
LPTSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCTSTR lpstrInitialDir;
LPCTSTR lpstrTitle;
DWORD Flags;
WORD nFileOffset;
WORD nFileExtension;
LPCTSTR lpstrDefExt;
LPARAM lCustData;
LPOFNHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
#if (_WIN32_WINNT >= 0x0500)
void * pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif // (_WIN32_WINNT >= 0x0500)
} OPENFILENAME, *LPOPENFILENAME;
仔细看看新的SDK中OPENFILENAME结构的定义,你就会明白要在mfc程序
产生新式的有我的电脑\我的文档等的对话框,必须满足几个条件:
1) win2K操作系统及以上
2) 定义_WIN32_WINNT 0x0500或以上
在mfc程序的stdafx.h中定义(在所有include之前)
#define _WIN32_WINNT 0x0500
3)必须应用新的sdk,这个可以在微软sdk网站上下载并安装
4)CFileDialog中的m_ofn必须应用新的OPENFILENAME结构
且m_ofn.lStructSize 是 sizeof(OPENFILENAME) 而不是 OPENFILENAME_SIZE_VERSION_400
后者不包括三个附加字段
在vc6上第4点除了写派生类外无法做到,因为无法替换m_ofn的类型
可以在做到第2第3点后尝试写如下程序
CFileDialog f(TRUE);
f.m_ofn.lStructSize = sizeof(f.m_ofn);
f.DoModal();
就可以看到新式对话框,但f析构时会出错
在vc7上只要做到第2点即可,或者干脆去掉_WIN32_WINNT的定义,此时他的缺省值
就是0x0500
换言之,你如果不想用派生类,恐怕就得升到vs.net了
CFileDialog f(TRUE);
f.m_ofn.lStructSize = sizeof(f.m_ofn);
f.DoModal();
没有用,还是老对话框.问题是我只要设置了OFN_ENABLEHOOK标志,就可以出来新的对话框,只不过在debug下会出assert,released却没有问题,debug下忽略也可以。所以,我认为应该可以用CFileDialog的。
When you run your app, you must have the old size when running on Windows 95, Windows 98, or Windows NT® 4.0. On Windows 2000, you can have either the old or new size. If lStructSize is the new size, Windows 2000 runs the new dialog. If it's the old size, Windows examines other information in OPENFILENAME: if the dialog has a hook function (OFN_ENABLEHOOK) or template (OFN_ENABLETEMPLATE), it runs the old dialog; otherwise it runs the new one.
msdn上的解决方案,还是派生了一个CFileDialogEx类,不过上面有完整的代码.
下面我贴出来.
头文件FileDialogEx.h
////////////////////////////////////////////////////////////////
// MSDN -- August 2000
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual C++ 6.0, runs on Windows 98 and probably NT too.
//
#pragma once// Windows 2000 version of OPENFILENAME.
// The new version has three extra members.
// This is copied from commdlg.h
//
struct OPENFILENAMEEX : public OPENFILENAME {
void * pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
};/////////////////////////////////////////////////////////////////////////////
// CFileDialogEx: Encapsulate Windows-2000 style open dialog.
//
class CFileDialogEx : public CFileDialog {
DECLARE_DYNAMIC(CFileDialogEx)
public:
CFileDialogEx(BOOL bOpenFileDialog, // TRUE for open, FALSE for FileSaveAs
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL); // override
virtual int DoModal();protected:
OPENFILENAMEEX m_ofnEx; // new Windows 2000 version of OPENFILENAME virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult); // virtual fns that handle various notifications
virtual BOOL OnFileNameOK();
virtual void OnInitDone();
virtual void OnFileNameChange();
virtual void OnFolderChange();
virtual void OnTypeChange(); DECLARE_MESSAGE_MAP()
//{{AFX_MSG(CFileDialogEx)
//}}AFX_MSG
};
实现文件FileDialogEx.cpp:
////////////////////////////////////////////////////////////////
// MSDN -- August 2000
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Largely based on original implementation by Michael POSThttp://expert.csdn.net/Expert/reply.C++ 6.0, runs on Windows 98 and probably NT too.
//
// CFileDialogEx implements a CFileDialog that uses the new Windows
// 2000 style open/save dialog. Use companion class CDocManagerEx in an
// MFC framework app.
//
#include "stdafx.h"
#include <afxpriv.h>
#include "FileDialogEx.h"#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endifstatic BOOL IsWin2000();IMPLEMENT_DYNAMIC(CFileDialogEx, CFileDialog)CFileDialogEx::CFileDialogEx(BOOL bOpenFileDialog, LPCTSTR lpszDefExt,
LPCTSTR lpszFileName, DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :
CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName,
dwFlags, lpszFilter, pParentWnd)
{
}
BEGIN_MESSAGE_MAP(CFileDialogEx, CFileDialog)
//{{AFX_MSG_MAP(CFileDialogEx)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()BOOL IsWin2000()
{
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx; // Try calling GetVersionEx using the OSVERSIONINFOEX structure,
// which is supported on Windows 2000.
//
// If that fails, try using the OSVERSIONINFO structure. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
{
// If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO. osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
return FALSE;
} switch (osvi.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT: if ( osvi.dwMajorVersion >= 5 )
return TRUE; break;
}
return FALSE;
}//////////////////
// DoModal override copied mostly from MFC, with modification to use
// m_ofnEx instead of m_ofn.
//
int CFileDialogEx::DoModal()
{
ASSERT_VALID(this);
ASSERT(m_ofn.Flags & OFN_ENABLEHOOK);
ASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook // zero out the file buffer for consistent parsing later
ASSERT(AfxIsValidAddress(m_ofn.lpstrFile, m_ofn.nMaxFile));
DWORD nOffset = lstrlen(m_ofn.lpstrFile)+1;
ASSERT(nOffset <= m_ofn.nMaxFile);
memset(m_ofn.lpstrFile+nOffset, 0, (m_ofn.nMaxFile-nOffset)*sizeof(TCHAR)); // WINBUG: This is a special case for the file open/save dialog,
// which sometimes pumps while it is coming up but before it has
// disabled the main window.
HWND hWndFocus = ::GetFocus();
BOOL bEnableParent = FALSE;
m_ofn.hwndOwner = PreModal();
AfxUnhookWindowCreate();
if (m_ofn.hwndOwner != NULL && ::IsWindowEnabled(m_ofn.hwndOwner))
{
bEnableParent = TRUE;
::EnableWindow(m_ofn.hwndOwner, FALSE);
} _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
ASSERT(pThreadState->m_pAlternateWndInit == NULL); if (m_ofn.Flags & OFN_EXPLORER)
pThreadState->m_pAlternateWndInit = this;
else
AfxHookWindowCreate(this); memset(&m_ofnEx, 0, sizeof(m_ofnEx));
memcpy(&m_ofnEx, &m_ofn, sizeof(m_ofn));
if (IsWin2000())
m_ofnEx.lStructSize = sizeof(m_ofnEx); int nResult;
if (m_bOpenFileDialog)
nResult = ::GetOpenFileName((OPENFILENAME*)&m_ofnEx);
else
nResult = ::GetSaveFileName((OPENFILENAME*)&m_ofnEx); memcpy(&m_ofn, &m_ofnEx, sizeof(m_ofn));
m_ofn.lStructSize = sizeof(m_ofn); if (nResult)
ASSERT(pThreadState->m_pAlternateWndInit == NULL);
pThreadState->m_pAlternateWndInit = NULL; // WINBUG: Second part of special case for file open/save dialog.
if (bEnableParent)
::EnableWindow(m_ofnEx.hwndOwner, TRUE);
if (::IsWindow(hWndFocus))
::SetFocus(hWndFocus); PostModal();
return nResult ? nResult : IDCANCEL;
}//////////////////
// When the open dialog sends a notification, copy m_ofnEx to m_ofn in
// case handler function is expecting updated information in the
// OPENFILENAME struct.
//
BOOL CFileDialogEx::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
memcpy(&m_ofn, &m_ofnEx, sizeof(m_ofn));
m_ofn.lStructSize = sizeof(m_ofn); return CFileDialog::OnNotify( wParam, lParam, pResult);
}////////////////////////////////////////////////////////////////
// The following functions are provided for testing purposes, to
// demonstrate that they in fact called; ie, that MFC's internal dialog
// proc is hooked up properly. Delete them if you like.
//
BOOL CFileDialogEx::OnFileNameOK()
{
TRACE(_T("CFileDialogEx::OnFileNameOK\n"));
return CFileDialog::OnFileNameOK();
}void CFileDialogEx::OnInitDone()
{
TRACE(_T("CFileDialogEx::OnInitDone\n"));
CFileDialog::OnInitDone();
}void CFileDialogEx::OnFileNameChange()
{
TRACE(_T("CFileDialogEx::OnFileNameChange\n"));
CFileDialog::OnFileNameChange();
}void CFileDialogEx::OnFolderChange()
{
TRACE(_T("CFileDialogEx::OnFolderChange\n"));
CFileDialog::OnFolderChange();
}void CFileDialogEx::OnTypeChange()
{
TRACE(_T("OnTypeChange(), index = %d\n"), m_ofn.nFilterIndex);
CFileDialog::OnTypeChange();
}