Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > как задать выбранную папку в диалоге выбора папки?


Автор: zkv 3.9.2006, 21:37
собственно сам диалог обзора вызывается без проблем, а вот как сделать, чтобы при старте диалога уже была бы выбрана определенная папка.

если через  BROWSEINFO::pidlRoot передать стартовую папку, то в диалоге отображаются, только ее содержимое, а надо задать именно папку, которая выбрана при старте диалога (т.е. чтобы все  каталоги имеющиеся на компе в диалоге присутствовали).

и вообще есть ли в MFC какая нибудь альтернатива SHBrowseForFolder() ? Что то неприятно с ним работать smile неужели нет чего нибудь похожего на CFileDialog? 

Автор: zkv 4.9.2006, 00:26
и еще, на форуме несколько раз задавали вопрос об использовании CFileDialog для открытия каталога, но ответа так и не последовало (я не нашел во всяком случае), так можно использовать или нет?

Автор: Damarus 4.9.2006, 01:25
Цитата(zkv @  3.9.2006,  22:37 Найти цитируемый пост)
собственно сам диалог обзора вызывается без проблем, а вот как сделать, чтобы при старте диалога уже была бы выбрана определенная папка.

Код

#include <windows.h>
#include <shlobj.h>
#include <iostream>

BOOL CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
    if (uMsg == BFFM_INITIALIZED)
        SendMessage(hWnd, BFFM_SETSELECTION, TRUE, lpData);

    return FALSE;
}

int wmain(int argc, wchar_t* argv[], wchar_t* envp[])
{
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    BROWSEINFO bi = { 0 };
    bi.ulFlags = BIF_NEWDIALOGSTYLE;
    bi.lpfn    = BrowseCallbackProc;
    bi.lParam  = LPARAM(L"C:\\Program Files");
    SHBrowseForFolder(&bi);

    CoUninitialize();
}


Автор: zkv 4.9.2006, 03:05
Damarus спасибо за столь развернутый пример, только у меня почему то работает только в таком варианте (мне сгодится и так, привожу для сведения):
Код

#include <windows.h>
#include <shlobj.h>

BOOL CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
    if (uMsg == BFFM_INITIALIZED)
        SendMessage(hWnd, BFFM_SETSELECTION, 
                                      FALSE,   //будет рассматривать lpData как id
                                      lpData); //здесь id 
    return FALSE;
}
int wmain(int argc, wchar_t* argv[], wchar_t* envp[])
{
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    BROWSEINFO bi = { 0 };
    WCHAR wstr[] = L"c:\\Program Files\\";    //требуемый путь, \ на конце обязательна :)
    LPITEMIDLIST    pidl;                    //сюда запишем
    pidl = SHSimpleIDListFromPath( wstr );  //id папки
    bi.ulFlags = BIF_NEWDIALOGSTYLE;        //тут маленькие проблемки, но разберусь
    bi.lpfn    = BrowseCallbackProc;        //
    bi.lParam  = LPARAM(pidl);              //отправляем id вместо имени
    SHBrowseForFolder(&bi);
    CoUninitialize();
}

как все непросто оказывается, неужели в MFC нет ничего проще, не верится, что для открытия файла сделали класс (CFileDialog), а для папки ничего нет. 
Повторюсь, кто-нибудь знает наверняка, что использовать CFileDialog для открытия каталога не получится?

Автор: Earnest 4.9.2006, 07:20
Теоретически можно, но требуются доработки: нужно запретить заходить в листовые папки, обработать выбор папки как выбор, а не как вход в нее и т.д. И все равно получается костыль. Когда-то очень давно именно так и делала. Но потом стала использовать SHBrowse: стандартное средство все-таки. Пользоваться напрямую, конечно, неудобно, но кто мешает обернуть это дело в класс или в функцию?

Автор: Damarus 4.9.2006, 09:55
Цитата(zkv @  4.9.2006,  04:05 Найти цитируемый пост)
Damarus спасибо за столь развернутый пример, только у меня почему то работает только в таком варианте (мне сгодится и так, привожу для сведения):

zkv, то есть код, который я привёл (без изменений), у тебя не работает smile Странно. В чём это выражается smile  У меня этот код нормально работает.

Автор: zkv 4.9.2006, 12:46
Цитата(Damarus @  4.9.2006,  09:55 Найти цитируемый пост)
zkv, то есть код, который я привёл (без изменений), у тебя не работает smile Странно. В чём это выражается smile  У меня этот код нормально работает. 


Damarus, выражается в том, что нужная папка просто не выбирается, диалог появляется нормально, 
в коде
Код

BOOL CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
    if (uMsg == BFFM_INITIALIZED)
        SendMessage(hWnd, BFFM_SETSELECTION, 
                                      TRUE,   //будет рассматривать lpData как LPWSTR
                                                  // (или LPСWSTR  не помню точно :) )
                                      lpData); 
    return FALSE;
}

перед SendMessage смотрел на значение lpData, туда все правильно доходит, а как дальше проследить не знаю smile
пробовал менять bi.ulFlags, не помогло, добавлял/прибавлял '\\' в конец пути, тоже глухо, получилось только так, как показано в моем вариатнте выше, причем мой вариант работает нормально только при сброшеном флаге  BIF_NEWDIALOGSTYLE, но меня это устраивает, "ненормальность"  работы заключается в том, что если указать к примеру "c:\\" или любой другой диск то он выбирается, а если добавить к пути какую нибудь папку к примеру "c:\\Program Files\\" (пробовал как со слешем на конце, так и без него), то опять таки не выбирается ничего. Работаю в 2003 студии. 

Всем спасибо за помощь

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)