Solved

How to open a File Browse Dialog

Posted on 2004-10-26
1,790 Views
Last Modified: 2013-11-20
How can I create a File browsing dialog that returns the directory chosen?

I tried this:

http://www.codeproject.com/dialog/cfolderdialog.asp?df=100&forumid=3533&select=957565

but can't get it to work (errors are posted at the bottom of that page)

thanks!
0
Question by:galneweinhaw
    9 Comments
     
    LVL 86

    Expert Comment

    by:jkr
    Usually, you'd use 'SHBrowseForFolder()' to do that, e.g.

    #include <shlobj.h>

    void PickFolder ( CString& strFolder)
    {

        LPMALLOC    pMalloc;    /* Gets the Shell's default allocator */

        if  (   ::SHGetMalloc   (   &pMalloc)   ==  NOERROR)
            {
                BROWSEINFO      bi;
                char            pszBuffer   [   MAX_PATH];
                LPITEMIDLIST    pidl;

                // Get help on BROWSEINFO struct - it's got all the bit settings.
                bi.hwndOwner        =   GetSafeHwnd();
                bi.pidlRoot         =   NULL;
                bi.pszDisplayName   =   pszBuffer;
                bi.lpszTitle        =   _T("Select a Folder");
                bi.ulFlags          =   0;
                bi.lpfn             =   NULL;
                bi.lParam           =   0;

                // This next call issues the dialog box.
                if  (   pidl    =   ::SHBrowseForFolder (   &bi))
                    {
                        if  (   ::SHGetPathFromIDList   (   pidl, pszBuffer))
                            {
                                // At this point pszBuffer contains the selected folder */
                                              strFolder = pszBuffer;
                             }

                        // Free the PIDL allocated by SHBrowseForFolder.
                        pMalloc->Free   (   pidl);
                    }

                // Release the shell's allocator.        
                pMalloc->Release();    
            }    
    }
    0
     

    Author Comment

    by:galneweinhaw
    That works great!

    is there any way for me to specify the folder the browse window starts in? (without restricting the browsing by using a root)

    thanks
    0
     
    LVL 86

    Expert Comment

    by:jkr
    http://www.codeproject.com/dialog/folderbrowser.asp ("How to show a dialog to let users browse for and select a folder") describes that issu epretty well, and better than I could do.
    0
     
    LVL 5

    Assisted Solution

    by:Nass89
    Hi,
    Have a look at "Q179378" "HOWTO: Browse for Folders from the Current Directory"
    in MSDN.

    Good Luck!
    0
     

    Author Comment

    by:galneweinhaw
    I tried the codeproject thing but it's giving me this error...

    Compiling...
    UpdateIESDlg.cpp
    O:\ENGINEERING\SHARED\PHOTOMET\PROGRAMS\OTHER PROGRAMS\UPDATEIES\UpdateIES\UpdateIESDlg.cpp(302) : error C2440: '=' : cannot convert from 'int (__stdcall CUpdateIESDlg::*)(struct HWND__ *,unsigned int,long,long)' to 'int (__stdcall *)(struct HWND__
    *,unsigned int,long,long)'
            There is no context in which this conversion is possible
    O:\ENGINEERING\SHARED\PHOTOMET\PROGRAMS\OTHER PROGRAMS\UPDATEIES\UpdateIES\UpdateIESDlg.cpp(312) : warning C4390: ';' : empty controlled statement found; is this the intent?
    Error executing cl.exe.
    Creating browse info file...

    UpdateIES.exe - 1 error(s), 1 warning(s)


    The first occurs here:
    bi.lpfn = BrowseCallbackProc;

    The warning here:
            if(SUCCEEDED(SHGetMalloc(&pMalloc)) && pMalloc);
            pMalloc->Free(pidl);  
            pMalloc->Release();


    thanks for the help.
    0
     
    LVL 86

    Accepted Solution

    by:
    Nass89 is right http://support.microsoft.com/default.aspx?scid=kb;en-us;179378 ("How To Browse for Folders from the Current Directory") has an easier example. With the above code, that should be

    INT CALLBACK BrowseCallbackProc(HWND hwnd,
                                    UINT uMsg,
                                    LPARAM lp,
                                    LPARAM pData)
    {
       TCHAR szDir[MAX_PATH];

       switch(uMsg)
       {
       case BFFM_INITIALIZED:
          if (GetCurrentDirectory(sizeof(szDir)/sizeof(TCHAR), szDir))
          {
             // WParam is TRUE since you are passing a path.
             // It would be FALSE if you were passing a pidl.
             SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)szDir);
          }
          break;

       case BFFM_SELCHANGED:
          // Set the status window to the currently selected path.
          if (SHGetPathFromIDList((LPITEMIDLIST) lp ,szDir))
          {
             SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);
          }
          break;
       }
       return 0;
    }

    void PickFolder ( CString& strFolder)
    {

       LPMALLOC    pMalloc;    /* Gets the Shell's default allocator */

       if  (   ::SHGetMalloc   (   &pMalloc)   ==  NOERROR)
           {
               BROWSEINFO      bi;
               char            pszBuffer   [   MAX_PATH];
               LPITEMIDLIST    pidl;

               // Get help on BROWSEINFO struct - it's got all the bit settings.
               bi.hwndOwner        =   GetSafeHwnd();
               bi.pidlRoot         =   NULL;
               bi.pszDisplayName   =   pszBuffer;
               bi.lpszTitle        =   _T("Select a Folder");
               bi.ulFlags          =   0;
               bi.lpfn             =   BrowseCallbackProc;
               bi.lParam           =   0;

               // This next call issues the dialog box.
               if  (   pidl    =   ::SHBrowseForFolder (   &bi))
                   {
                       if  (   ::SHGetPathFromIDList   (   pidl, pszBuffer))
                           {
                               // At this point pszBuffer contains the selected folder */
                                      strFolder = pszBuffer;
                            }

                       // Free the PIDL allocated by SHBrowseForFolder.
                       pMalloc->Free   (   pidl);
                   }

               // Release the shell's allocator.        
               pMalloc->Release();    
           }    
    }
    0
     

    Author Comment

    by:galneweinhaw
    Thanks to both of you for the help

    unfortunately I am still getting this error using the code above:


    error C2440: '=' : cannot convert from 'int (__stdcall CUpdateIESDlg::*)(struct HWND__ *,unsigned int,long,long)' to 'int (__stdcall *)(struct HWND__ *,unsigned int,long,long)' There is no context in which this conversion is possible


    It is occuring at this line:
    bi.lpfn             =   BrowseCallbackProc;



    Also getting the error:
    error C2660: 'SendMessageA' : function does not take 4 parameters

    from lines:
    SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)szDir);
    //and
    SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);

    thanks again.
    0
     
    LVL 86

    Expert Comment

    by:jkr
    >>error C2440: '=' : cannot convert from

    The browse callback cannot be a non-static member of CUpdateIESDlg - either make that not a member function or declare it as 'static'.

    >>error C2660: 'SendMessageA' : function does not take 4 parameters

    The compiler thinks you are referring to CWnd::SendMessage() - use

    ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)szDir);
    //and
    ::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);

    to resolve this ambiguity.
    0
     

    Author Comment

    by:galneweinhaw
    Thanks jkr,

    working great.

    How do I post a follow-up question?

    My directory name is so long it is wrapping and getting hidden behind the tree-view.
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone. Privacy Policy Terms of Use

    Featured Post

    Do You Know the 4 Main Threat Actor Types?

    Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

    Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
    If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
    This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
    how to add IIS SMTP to handle application/Scanner relays into office 365.

    875 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    15 Experts available now in Live!

    Get 1:1 Help Now