现在想要将一个文件夹保存到用户选择的路径下。
我使用了MFC的CFileDialog ,但是目前遇到一个问题,就是在用户选择
的路径下存在与要保存的文件夹同名的文件夹时,点击CFileDialog上的
SAVE按钮后,结果直接进入到该同名文件中,而不是提示“是否覆盖”比如:用户给要保存的文件夹命名为A,弹出路径选择对话框后,用户选择
了D盘,此时D盘正好有一个文件夹名称也为A,点击CFileDialog 上
的"SAVE"按钮,希望提示“是否覆盖”的对话框,而不是直接进入到A文件夹中。
(CFileDialog fileDlg(FALSE, NULL, fileName, 6UL, NULL);)请问有什么方式可以实现咧?
我使用了MFC的CFileDialog ,但是目前遇到一个问题,就是在用户选择
的路径下存在与要保存的文件夹同名的文件夹时,点击CFileDialog上的
SAVE按钮后,结果直接进入到该同名文件中,而不是提示“是否覆盖”比如:用户给要保存的文件夹命名为A,弹出路径选择对话框后,用户选择
了D盘,此时D盘正好有一个文件夹名称也为A,点击CFileDialog 上
的"SAVE"按钮,希望提示“是否覆盖”的对话框,而不是直接进入到A文件夹中。
(CFileDialog fileDlg(FALSE, NULL, fileName, 6UL, NULL);)请问有什么方式可以实现咧?
Causes the Save As dialog box to generate a message box if the selected file already exists. The user must confirm whether to overwrite the file.
按照6楼的设定,试图用钩子函数拦截这个save消息,但是钩子函数根本没有进去,我的电脑是win7系统
fd.m_ofn.Flags|=OFN_FILEMUSTEXIST;
fd.m_ofn.Flags|=OFN_ALLOWMULTISELECT;// must
fd.m_ofn.Flags|=OFN_EXPLORER; // default by Afx
// fd.m_ofn.Flags|=OFN_ENABLEHOOK;// default by Afx
fd.m_ofn.lpfnHook=DNHookProc;//="_AfxCommDlgProc" see"dlgcomm.cpp" <>NULL!
//UINT CALLBACK _AfxCommDlgProc(HWND hWnd,UINT message,
// WPARAM wParam,LPARAM lParam);// for CFileDialog down load
// in debug version there is an error : ASSERT(m_p...==NULL)
UINT CALLBACK DNHookProc(HWND hDlg,UINT uMsg,WPARAM wPar,LPARAM lPar)
{ // hdlg is a child
HWND hWndParent;
CWinApp *pApp=AfxGetApp();
HICON hIcon;
HWND hw; // SHELLDll_defView
HWND hcw;// SysListView32
DWORD dwStyle;
//
if (hDlg == NULL) return 0;
// from "_AfxCommDlgProc()" of the file "dlgcomm.cpp"
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
if (pThreadState->m_pAlternateWndInit != NULL)
// not pThreadState->m_pAlternateWndInit->SubclassWindow(hWnd);
pThreadState->m_pAlternateWndInit = NULL;
//
hWndParent=GetParent(hDlg);// needed
switch (uMsg)
{
case WM_INITDIALOG:
hIcon=pApp->LoadIcon(IDI_ICONDN);
SendMessage(hWndParent,WM_SETICON,(WPARAM)0,(LPARAM)hIcon);
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
DestroyIcon(hIcon);
break;
case WM_NOTIFY:
LPOFNOTIFY lpon=(LPOFNOTIFY)lPar;
UINT Notify=lpon->hdr.code;
if (Notify==CDN_TYPECHANGE ||
Notify==CDN_SELCHANGE )
{ // after window shown
hw=GetDlgItem(hWndParent,0x0461);// SHELLDll_defView
hcw=GetDlgItem(hw,1);// SysListView32
dwStyle=GetWindowLong(hcw,GWL_STYLE);
// change multi-selection of ListView
if (lpon->lpOFN->nFilterIndex==4) // "dll"
{
dwStyle &= ~LVS_SINGLESEL;// Multi
}
else
{
dwStyle |= LVS_SINGLESEL;// Single
}
SetWindowLong(hcw,GWL_STYLE,dwStyle);
}
if (Notify==CDN_FOLDERCHANGE)
{
HWND hLv=GetDlgItem(hWndParent,0x0461);//lst1
if(hLv) SendMessage(hLv,WM_COMMAND,0x7029,0);//ODM_WIEW_ICONS
}
break;
}
return 0;
}
OFN_ALLOWMULTISELECT属性加上,运行起来后,会有个assert错,报的位置是CFileDialog下的;
去掉之后,钩子函数进不去。我之前从网上试了几个钩子函数的例子,都是进不去。后面有人解释说
是Vista系统不支持(MSDN的解释),我的电脑是win7系统,编译环境VS2010,不清楚是不是操作系统的原因。
class CExpFileOpen : public CFileDialog
嗯,是的,现在就是想要拦截到save按钮按下后触发的那个消息。
用SHBrowseForFolder貌似不能设定文件夹的名称?比如用户选择另存为后,想把文件夹保存为
AAA,但是SHBrowseForFolder的编辑框貌似不允许这么干吧
我在派生类里面重载了以下几个函数,可结果却让人失望,真心不知道是什么原因了。。
// only called back if OFN_EXPLORER is set 此标志加上了
virtual void OnInitDone(); //派生类此函数进不去
virtual void OnFileNameChange(); //派生类此函数可以进去
virtual void OnFolderChange(); //派生类此函数可以进去
virtual void OnTypeChange(); //派生类此函数进不去最希望的结果是,按下save按钮后,能够截取到那个按钮按下消息
嗯,是的,现在就是想要拦截到save按钮按下后触发的那个消息。
用SHBrowseForFolder貌似不能设定文件夹的名称?比如用户选择另存为后,想把文件夹保存为
AAA,但是SHBrowseForFolder的编辑框貌似不允许这么干吧
那你另做一个保存对话框好了,比如这样保存名称默认就是源的,要改的自己编辑,点击确定的时候判断是否有覆盖
BOOL CExpFileOpen::OnInitDialog()
{
CFileDialog::OnInitDialog();
// TODO: Add extra initialization here
CFileDialog *Parent=(CFileDialog*)GetParent();// not GWL_WNDPROC
WNDPROC OldDlgProc = (WNDPROC)SetWindowLong(Parent->m_hWnd, DWL_DLGPROC, (LONG)NewDlgProc);
// save it in window
::SetProp(Parent->m_hWnd,"ExpFileOpen",(HANDLE)OldDlgProc);
//////////////////////////////////////////////////
// if no ! dlgFile.m_ofn.lpfnHook=CDN_HookProc;//="_AfxCommDlgProc" see"dlgcomm.cpp" <>NULL!
// for CFileDialog
LRESULT CALLBACK NewDlgProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) //子类化过程
{
}