The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: OldTimer on August 28, 2008, 04:50:30 AM

Title: BrowseForFolder remembers last position
Post by: OldTimer on August 28, 2008, 04:50:30 AM
    If you'd like your Browse For Folder screen to automatically scroll down to the users previous selection you can try the code snippet below.  Just 2 shell API's and no COMplicated stuff.   Sorry, Windows XP or later.

   The global field 'ChosenFolderName' is the users previously chosen folder obtained from SHGetPathFromIDList.

.data?
ChosenFolderNane  db  260 dup(?)     ; if not prviously specified
.code

In Browse For Folder you will need :-

; specify the user proc
   mov    bi.lpfn,offset cbBrowse
; start folder tree at the Desktop
   mov    bi.pidlRoot,0
                  ~~~~~~~~~~~~~~
   invoke SHGetPathFromIDList,lpIDList,lpBuffer
   invoke lstrcpy,addr ChosenFolderName,lpBuffer      ; <--- new line

; #################################################

.data
Shell32     db    'Shell32.dll',0
CreateIL    db    'ILCreateFromPathA',0
FreeIL      db    'ILFree',0
.code

cbBrowse proc hWin   :DWORD,
              uMsg   :DWORD,
              lParam :DWORD,
              lpData :DWORD

LOCAL hShell32    :DWORD
LOCAL lpPidl      :DWORD
LOCAL FreeILaddr  :DWORD

; folder tree is ready for display
  .if uMsg == BFFM_INITIALIZED
    mov   eax,offset ChosenFolderName ; previous selection
    .if byte ptr [eax] !=0
      invoke GetModuleHandleA,addr Shell32 ; Shell32.dll is already loaded
      .if eax !=0
        mov    hShell32,eax
        invoke GetProcAddress,hShell32,offset FreeIL
        .if eax !=0
          mov  FreeILaddr,eax
          invoke GetProcAddress,hShell32,addr CreateIL
          .if eax !=0
            push   offset ChosenFolderName
            call   eax          ; ILCreateFromPathA
            .if eax !=0
              mov    lpPidl,eax ; Success
              invoke SendMessage,hWin,BFFM_SETSELECTION,
                                 FALSE,lpPidl
              push   lpPidl
              call   FreeILaddr  ; release Pidl memory
            .endif
          .endif
        .endif
      .endif
    .endif
  .endif
  ret

cbBrowse endp

; ##############################################################

A bit easier to follow than Microsoft's example :-

hr = pDesktopFolder->lpVtbl->ParseDisplayName \
      (pDesktopFolder,NULL,NULL,olePath,&chEaten,&pidl,&dwAttributes)

Les.
Title: Re: BrowseForFolder remembers last position
Post by: akane on August 28, 2008, 08:27:44 AM
To avoid global variables and be compatible up to win95, I'm using the lParam member of BROWSEINFO, that points to the full folder path to be selected. The lpData parameter of our callback is always equal to BROWSEINFO.lParam.