Newsgroup: it.comp.lang.visual-basic
Titolo: ? aiuto per BRROWEINFO

Sto tentando di documentare l'API SHBrowseForFolder, devo utilizzare la
struttura BROWSEINFO
   In questa struttura, il membro "pidlRoot" dovrebbe consentirmi l'accesseo
solo alle cartelle della directory indicata.
Qualcuno potrebbe inviare un esempio su come funziona questo membro???
Grazie per l'aiuto.

 solo alle cartelle della directory indicata.
In genere si procede in questo modo.
Apri il Dialog dalla root con una procedura tipo:
Dim lpIDList As Long
Dim strBuf As String
Dim lpBrowseInfo As BROWSEINFO
   With lpBrowseInfo
      .pIDLRoot = 0
      .hWndOwner = hWndOwner
      .lpszTitle = lstrcat(lpszTitle, "")
      ' passo il puntatore con lstrcat, ma è indifferente.
      .ulFlags = BIF_RETURNONLYFSDIRS
   End With
   'ottieni l'ITEMIDLIST dalla funzione. E' l'ID della
   'subdir selezionata
   lpIDList = SHBrowseForFolder(lpBrowseInfo)
   'ottieni il nome del path con la successiva chiamata
   'SHGetPathFromIDList fa quallo che il nome suggerisce
   '(immagino che già lo sai, lo dico per un motivo...)
   If lpIDList Then
      strBuf = String$(255, 0)
      SHGetPathFromIDList lpIDList, strBuf
      BrowseForFolder = Left$(strBuf, (InStr(1, strBuf, Chr$(0)) - 1))
   End If
Con l'ID ottenuto è poi facile richiamare la funzione
SHBrowseForFolder per iniziare il browsing dall'ID
precedente impostando la struttura
   With BInfo
      .pIDLRoot = lpIDList    'ID ricevuto in precedenza
      .hWndOwner = hWndOwner
      .lpszTitle = lstrcat(lpszTitle, "")
      .ulFlags = BIF_RETURNONLYFSDIRS
   End With
   'A questo il browsing inizia dal folder selezionato
   'in precedenza
   lpIDList = SHBrowseForFolder(lpBrowseInfo)
Non mi ricordo comunque - e mi ricollego a quello che
dicevo prima - se esiste un modo di ottenere a priori
l'ID di un folder in base al suo path. Non esiste una
funzione, per dire, GetIDListFromPath Non so
se c'è il modo di conoscere un ID prima di utilizzare
SHBrowseForFolder. Se mi viene in mente ti faccio
sapere.

 Qualcuno potrebbe inviare un esempio su come funziona questo membro???
Ho trovato alcuni sistemi per impostare la directory predefinita
Il primo utilizzando una funzione non documentata:
Public Declare Function SHSimpleIDListFromPath Lib _
   "shell32" Alias "#162" _
   (ByVal szPath As String) As Long
Ritorna il PIDL del path specificato; è il valore che si può
assegnare al membro .pidlRoot. C'è da tenere presente
che la funzione non è documentata, per cui non è assicurato
che si troverà sempre all'ordinale #162. Inoltre non c'è una
definizione W per il formato wide Unicode di NT. Fai tu.
Altro metodo è quello di utilizzare il membro .lpfn passandogli
l'indirizzo di una callback che in fase di inizializzazione della
finestra indichi il folder da pre-selezionare.
Nell'SDK la callback è definita come:
Public Function BrowseCallbackProc(ByVal hWnd As Long, _
    ByVal uMsg As Long, _
    ByVal lParam As Long, _
    ByVal lpData As Long) As Long
Se uMsg è = BFFM_INITIALIZED (=1) è possibile inviare
un messaggio BFFM_SETSELECTION alla finestra (hWnd).
Con lParam impostato a True, lpData è il puntatore alla stringa
contenente il path da pre-impostare.
    Call SendMessage(hWnd, BFFM_SETSELECTIONA, _
        True, ByVal lpData)
Ovviamente, essendo una callback, lpData è l'equivalente
del membro .lParam della struttura BROWSEINFO, ossia
è necessario specificare il path nella struttura, non è possibile
passarlo ex-novo in lpData.
Nota1: Il membro .lParam è un puntatore (long); lo si ottiene
con VarPtr o con la funzione CopyMemory. Il path quando
viene passato a una funzione dell'API, non deve avere lo
slash finale (per chi non lo sa).
Nota2: nell'SDK che ho, la spiegazione del metodo di
assegnazione del parametro lParam della callback è sballata.
Sarà un refuso, ma è assolutamente fuorviante; parla di un
wParam inesistente e altre amenità.
Nota3: (per chi non lo sapesse). L'indicatore PIDL restituito
da SHBrowseForFolder deve essere "liberato" tramite la
funzione CoTaskMemFree()
Ultimo metodo
La funzione GetFileInformationByHandle ritorna nei membri
.nFileIndexHigh e nFileIndexLow della struttura passata, il
l'high-order word e il low-order word del PIDL del file o
della directory indicata. E' possibile trasformare i due dati
nel PIDL da specificare in .pidlRoot
Public Type BY_HANDLE_FILE_INFORMATION
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    dwVolumeSerialNumber As Long
    nFileSizeHigh As Long
    nFileSizeLow As Long
    nNumberOfLinks As Long
    nFileIndexHigh As Long
    nFileIndexLow As Long
End Type
Public Declare Function GetFileInformationByHandle _
    Lib "kernel32" Alias "GetFileInformationByHandle" _
    (ByVal hFile As Long, _
    lpFileInformation As BY_HANDLE_FILE_INFORMATION) _
    As Long