Win32 - Select Directory Dialog from C/C++

前端 未结 3 2066
我在风中等你
我在风中等你 2020-12-23 18:11

How to select an existing folder (or create new) from a native Win32 application?

Here is a similar question. It has a good answer for C#/.NET. But I want the same t

3条回答
  •  猫巷女王i
    2020-12-23 18:56

    Just as a go to for future users, this article helped me a lot with getting a directory dialog in C++

    http://www.codeproject.com/Articles/2604/Browse-Folder-dialog-search-folder-and-all-sub-fol

    Here is my code (heavily based/taken on the article)

    NOTE: You should be able to copy/paste this into a file / compile it (g++, see VS in ninja edit below) and it'll work.

    #include 
    #include 
    #include 
    #include 
    #include 
    
    static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg, LPARAM lParam, LPARAM lpData)
    {
    
        if(uMsg == BFFM_INITIALIZED)
        {
            std::string tmp = (const char *) lpData;
            std::cout << "path: " << tmp << std::endl;
            SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
        }
    
        return 0;
    }
    
    std::string BrowseFolder(std::string saved_path)
    {
        TCHAR path[MAX_PATH];
    
        const char * path_param = saved_path.c_str();
    
        BROWSEINFO bi = { 0 };
        bi.lpszTitle  = ("Browse for folder...");
        bi.ulFlags    = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
        bi.lpfn       = BrowseCallbackProc;
        bi.lParam     = (LPARAM) path_param;
    
        LPITEMIDLIST pidl = SHBrowseForFolder ( &bi );
    
        if ( pidl != 0 )
        {
            //get the name of the folder and put it in path
            SHGetPathFromIDList ( pidl, path );
    
            //free memory used
            IMalloc * imalloc = 0;
            if ( SUCCEEDED( SHGetMalloc ( &imalloc )) )
            {
                imalloc->Free ( pidl );
                imalloc->Release ( );
            }
    
            return path;
        }
    
        return "";
    }
    
    int main(int argc, const char *argv[])
    {
        std::string path = BrowseFolder(argv[1]);
        std::cout << path << std::endl;
        return 0;
    }
    

    EDIT: I've updated the code to show people how to remember the last selected path and use that.

    Also, for VS, using Unicode character set. replace this line:

    const char * path_param = saved_path.c_str();
    

    With this:

    std::wstring wsaved_path(saved_path.begin(),saved_path.end());
    const wchar_t * path_param = wsaved_path.c_str();
    

    My Test code above is compiled with g++, but doing this fixed it in VS for me.

提交回复
热议问题