现在想要将一个文件夹保存到用户选择的路径下。
我使用了MFC的CFileDialog ,但是目前遇到一个问题,就是在用户选择
的路径下存在与要保存的文件夹同名的文件夹时,点击CFileDialog上的
SAVE按钮后,结果直接进入到该同名文件中,而不是提示“是否覆盖”比如:用户给要保存的文件夹命名为A,弹出路径选择对话框后,用户选择
了D盘,此时D盘正好有一个文件夹名称也为A,点击CFileDialog 上
的"SAVE"按钮,希望提示“是否覆盖”的对话框,而不是直接进入到A文件夹中。
(CFileDialog fileDlg(FALSE, NULL, fileName, 6UL, NULL);)请问有什么方式可以实现咧?

解决方案 »

  1.   

    OFN_OVERWRITEPROMPT 
     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. 
      

  2.   

    构造对象时flag 与 OFN_OVERWRITEPROMPT 进行或运算
      

  3.   

    CFileDialog 是选择文件用的,如果要识别或操作目录,需要使用钩子函数,设置OFN_ENABLEHOOK风格,并在lpfnHook成员中指定钩子函数。
      

  4.   

    属性设置OFN_OVERWRITEPROMPT 后,但只对单个的文件能够有同名提示,我这边是文件夹
    按照6楼的设定,试图用钩子函数拦截这个save消息,但是钩子函数根本没有进去,我的电脑是win7系统
      

  5.   

    vc6例子
    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;
    }
      

  6.   


    OFN_ALLOWMULTISELECT属性加上,运行起来后,会有个assert错,报的位置是CFileDialog下的;
    去掉之后,钩子函数进不去。我之前从网上试了几个钩子函数的例子,都是进不去。后面有人解释说
    是Vista系统不支持(MSDN的解释),我的电脑是win7系统,编译环境VS2010,不清楚是不是操作系统的原因。
      

  7.   

    文件夹的话最好用SHBrowseForFolder,覆盖提示应该是你自己的程序处理吧
      

  8.   

    不用hook 可以 派生
    class CExpFileOpen : public CFileDialog
      

  9.   


    嗯,是的,现在就是想要拦截到save按钮按下后触发的那个消息。
    用SHBrowseForFolder貌似不能设定文件夹的名称?比如用户选择另存为后,想把文件夹保存为
    AAA,但是SHBrowseForFolder的编辑框貌似不允许这么干吧
      

  10.   

    我尝试了网上给出的一些例子,按道理讲CFileDialog的几个虚函数在子类中应该都可以被重载和响应,
    我在派生类里面重载了以下几个函数,可结果却让人失望,真心不知道是什么原因了。。
    // only called back if OFN_EXPLORER is set   此标志加上了
    virtual void OnInitDone();   //派生类此函数进不去
    virtual void OnFileNameChange(); //派生类此函数可以进去
    virtual void OnFolderChange(); //派生类此函数可以进去
    virtual void OnTypeChange(); //派生类此函数进不去最希望的结果是,按下save按钮后,能够截取到那个按钮按下消息
      

  11.   


    嗯,是的,现在就是想要拦截到save按钮按下后触发的那个消息。
    用SHBrowseForFolder貌似不能设定文件夹的名称?比如用户选择另存为后,想把文件夹保存为
    AAA,但是SHBrowseForFolder的编辑框貌似不允许这么干吧
    那你另做一个保存对话框好了,比如这样保存名称默认就是源的,要改的自己编辑,点击确定的时候判断是否有覆盖
      

  12.   

    要子类化
    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) //子类化过程 

    }