Obsuga okienka pozwalajcego na przegldanie katalogw.

       Naley skorzysta z funkcji SHBrowseForFolder. Przekazuje si jej struktur BROWSEINFO, ktra okrela zachowanie okienka. Po zamkniciu okienka dialogowego SHBrowseForFolder zwraca wskanik do listy ID (PIDL) okrelajcej wybrany folder. 

      Aby wydoby ciek wybranego folderu trzeba uy funkcji SHGetPathFromIDList, ktra konwertuje obiekt PIDL do stringu (pamitaj doczy w nagwku: #include <SHLOBJ.H>): 

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    BROWSEINFO    info;
    char          szDir[MAX_PATH];
    char          szDisplayName[MAX_PATH];
    LPITEMIDLIST  pidl;
    LPMALLOC      pShellMalloc;

    if(SHGetMalloc(&pShellMalloc) == NO_ERROR)
    {
        memset(&info, 0x00,sizeof(info));
        info.hwndOwner = Handle;                 
        info.pidlRoot  = 0;                      
        info.pszDisplayName = szDisplayName;     
        info.lpszTitle = "Tytu okna";         
        info.ulFlags   = BIF_RETURNONLYFSDIRS;   
        info.lpfn = 0;                           

        // pokazuje okno dialogowe
        pidl = SHBrowseForFolder(&info);

        // pidl = NULL gdy anulowano.
        // pidl <> NULL gdy zostanie wybrany folder
        if(pidl)
        {
            // prba konwersji pidl do stringu
            // zwraca true przy sukcesie
            if(SHGetPathFromIDList(pidl, szDir))
            {
                // ustawia Label1 na ciek folderu
                Label1->Caption = szDir;
            }

            // ustawia Label2 na tytu folderu
            Label2->Caption = info.pszDisplayName;

            pShellMalloc->Free(pidl);
        }
        pShellMalloc->Release();
    }
}
       SHBrowseForFolder zwraca obiekt PIDL, jest on alokowany przez alokatora zada. Kiedy PIDL jest ju niepotrzebny musi zosta zwolniony przez tego alokatora. Musisz uzyska referencje do niego poprzez wywoanie funkcji SHGetMalloc. Funkcja zwraca wskanik do obiektu COM IMalloc. Jeeli COM jest Ci obcy, to potraktuj obiekt IMalloc jako zwyky obiekt C++, posiadajcy metody, ktre moesz wywoa. My potrzebujemy metody Free, zwalniajcej obiekt PIDL. Poniszy pseudokod pokazuje zalenoci midzy metodami COM a zwykym kodem C++. 

kod COM                            ekwiwalent C++ 

LPMALLOC pShellMalloc;            // potraktuj pShellMalloc jako obiekt
SHGetMalloc(&pShellMalloc);       // obsugujcy polecenia new i delete
                                  // dla zada systemowych

LPITEMIDLIST  pidl;                Tpidl *pidl;
pidl = SHBrowseForFolder(...);     pidl = new Tpidl();

pShellMalloc->Free(pidl);          delete pidl;

pShellMalloc->Release();
       Struktura BROWSEINFO pozwala Ci kontrolowa wygld i zachowanie okna dialogowego SHBrowseForFolder: 

typedef struct {
    HWND          hwndOwner;
    LPCITEMIDLIST pidlRoot;
    LPSTR         pszDisplayName;
    LPCSTR        lpszTitle;
    UINT          ulFlags;
    BFFCALLBACK   lpfn;
    LPARAM        lParam;
    int           iImage;
} BROWSEINFO;
hwndOwner: Okrela uchwyt okna bdcego wacicielem okienka dialogowego. Jeeli podasz waciciela, okienko dialogowe bdzie okienkiem modalnym; dopki bdzie ono wywietlane, uytkownik nie bdzie mg podejmowa adnych akcji w programie. Po okreleniu waciciela na pasku zada nie bdzie osobnej ikony dla okienka dialogowego. Natomiast w przypadku podania argumentu NULL, okienko dialogowe bdzie si zachowywa jak osobne okno nie bdce czci programu. 

pidlRoot: Okrela pocztkowy katalog, uytkownik nie moe cofn si powyej tego katalogu. 

pszDisplayName: Tu zostaje zapisany tytu wybranego katalogu. Powiniene wskaza ten parametr na bufor, ktry jest w stanie przechowa co najmniej MAX_PATH znakw. Tytu katalogu nie jest tym samym co cieka dostpu. 

lpszTitle: Ten parametr pozwala wywietli dowolny tekst nad drzewem katalogw. 

ulFlags: Pozwalaj wybra typy przegldanych folderw. Moliwe wartoci to: 



BIF_BROWSEFORCOMPUTER  Przegldanie otoczenia sieciowego.
BIF_BROWSEFORPRINTER   Przegldanie drukarek sieciowych.
BIF_DONTGOBELOWDOMAIN  Zapobiega wywietlaniu folderw sieciowych
                       lecych poniej poziomu domeny.
BIF_RETURNONLYFSDIRS   Zwraca dyski i katalogi.
BIF_RETURNFSANCESTORS  Zwraca przodkw systemu plikw (co to jest??)
BIF_STATUSTEXT         Wywietla tekst na okienku dialogowym.
lpfn: Wskanik do funkcji callback. Przykad poniej. 

lParam: Warto uywana w funkcji callback. 

iImage: Wybrany folder bdzie posiada jak skojarzon ikon. Po zamkniciu okienka dialogowego iImage bdzie zawiera liczb cakowit. Ta warto to indeks ikony w systemowej ImageList. 

       Uycie funkcji callback SHBrowseForFolder 

       Funkcja callback pozwala modyfikowa zachowanie okienka dialogowego. Na przykad, moesz za jej pomoc wcza i wycza przycisk OK, moesz take przej do konkretnego folderu, bd wywietli tekst stanu. 

       Oto przykadowy kod demonstrujcy uycie funkcji callback. Ten kod wywietla tekst stanu, inicjalizuje okienko dialogowe w ustalonym katalogu i wywietla w kontrolce TLabel aktualnie wybrany folder. 

int __stdcall BrowseProc(HWND hwnd,UINT uMsg, LPARAM lParam, LPARAM lpData )
{
    char szDir[MAX_PATH];

    switch(uMsg)
    {
        case BFFM_INITIALIZED:
            SendMessage(hwnd, BFFM_SETSTATUSTEXT,0, (LPARAM)"Inny tekst");

            // Ustaw pocztkowy katalog, jeli WPARAM jest TRUE
            // to LPARAM jest stringiem zawierajcym ciek,
            // gdy WPARAM jest FALSE, wtedy LPARAM to PIDL
			
    SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)"C:\\Windows");
            break;
        case BFFM_SELCHANGED:
            if(SHGetPathFromIDList((LPITEMIDLIST)lParam, szDir))
                Form1->Label3->Caption = szDir;
            break;
    }
    return 0;
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    BROWSEINFO    info;
    char          szDir[MAX_PATH];
    char          szDisplayName[MAX_PATH];
    LPITEMIDLIST  pidl;
    LPMALLOC      pShellMalloc;

    if(SHGetMalloc(&pShellMalloc) == NO_ERROR)
    {
        memset(&info, 0x00, sizeof(info));
        info.hwndOwner = 0;
        info.pidlRoot  = NULL;
        info.pszDisplayName = szDisplayName;
        info.lpszTitle = "Tytu okienka";
        info.ulFlags   = BIF_RETURNONLYFSDIRS|BIF_STATUSTEXT;
        info.lpfn      = BrowseProc;             

        pidl = SHBrowseForFolder(&info);

        if(pidl)
        {
            if(SHGetPathFromIDList(pidl, szDir))
            {
                Label1->Caption = szDir;
            }

            Label2->Caption = info.pszDisplayName;

            pShellMalloc->Free(pidl);
            pShellMalloc->Release();
        }
    }
}

rdo: BCBDEV.com
 
Tumaczenie:  
 
 
 
 
 
