Newsgroup: it.comp.programmare.win32
Titolo: SHBrowseForFolder

Come si usa la funzione in oggetto ?
Non mi fareste un piccolo esempio in C\C++ ?
grazie.

 ha scritto nel messaggio
Questa è la versione per il C:
void BrowseForFolders(HWND hwnd, PSTR pszFolderPath, PSTR pszFolderName)
{
    BROWSEINFO bi;
    LPSTR lpBuffer;
    LPITEMIDLIST pidlBrowse;    // PIDL selected by user
    LPMALLOC pMalloc;
    SHGetMalloc(&pMalloc);
    if ((lpBuffer = (LPSTR) pMalloc->lpVtbl->Alloc(pMalloc, MAX_PATH)) ==
NULL)
        return;
    bi.hwndOwner = hwnd;
    bi.pidlRoot = NULL;
    bi.pszDisplayName = lpBuffer;
    bi.lpszTitle = "Selezionare la cartella desiderata";
    bi.ulFlags = BIF_RETURNONLYFSDIRS | 0x0040;
    bi.lpfn = NULL;
    bi.lParam = 0;
    pidlBrowse = SHBrowseForFolder(&bi);
    if (pidlBrowse != NULL) {
        lstrcpy(pszFolderName, lpBuffer);
        if (SHGetPathFromIDList(pidlBrowse, lpBuffer))
            lstrcpy(pszFolderPath, lpBuffer);
        // Free the PIDL returned by SHBrowseForFolder.
        pMalloc->lpVtbl->Free(pMalloc, pidlBrowse);
    }
    // Clean up.
    pMalloc->lpVtbl->Free(pMalloc, lpBuffer);
}
Se la devi usare in C++ devi togliere il puntatore alla Virtual Table
(lpVtbl) ed il primo membro delle chiamate a funzioni COM (che in C++ è
implicito e non è altro che "this").
Lorenzo


OK . Pero' ci sono alcune cose che non mi sono chiare .
Mi spieghi le relazioni fra pMalloc,lpBuffer e pidlBrowse ?
In un mio programma di esempio (che sembra funzionare ) ho fatto cosi
....
   bi.hwndOwner = hwnd;
   bi.pidlRoot = NULL;
   bi.pszDisplayName = lpBuffer;
   bi.lpszTitle = "Selezionare la cartella desiderata";
   bi.ulFlags = BIF_RETURNONLYFSDIRS | 0x0040;
   bi.lpfn = NULL;
   bi.lParam = 0;
   pidlBrowse = SHBrowseForFolder(&bi) ;
   if (pidlBrowse != NULL)    SHGetPathFromIDList(pidlBrowse, lpBuffer))
;
e mi ritorna in lpBuffer il path completo della directory selezionata .
Tuttavia mi viene un dubbio in quanto leggendo la documentazione della
funzione SHBrowseForFolder si afferma che :
    The calling application is responsible for freeing the returned item
identifier list using the shell's task allocator.
Il dubbio e' : lascio qualche risorsa allocata nella memoria con il
codice da
me proposto ?
grazie.


 me proposto ?
Sì, lasci delle risorse allocate. Dal tuo codice non è chiaro come venga
allocato lpBuffer, se lo allochi staticamente non dovresti avere problemi.
Devi però liberare la memoria allocata dalla funzione SHBrowseForFolder.
Infatti tu dichiari un puntatore ad un ITEMIDLIST. Non puoi allocarlo
staticamente perché non puoi prevedere la sua dimensione. Quindi
internamente viene allocata la memoria per contenere l'ITEMIDLIST e ti viene
restituito l'indirizzo. Dopo che lo hai usato devi liberare la memoria, e
devi usare l'allocatore di COM. Puoi utilizzare IMalloc indirettamente senza
inizializzare COM richiedendo un puntatore all'interfaccia con la funzione
SHGetMalloc. Usa il metodo Free applicato a pidlBrowse. Per approfondire
queste tematiche studiati COM e la documentazione relativa allo Shell
Namespace (che tratta gli ITEMIDLIST).
Lorenzo

Lorenzo Novara wrote:

Purtroppo non dispongo del materiale didattico da te menzionato .
Perche' non provi a correggere il mio codice;forse riesco pian piano a capirci
qualcosa di piu.
grazie