News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

SHBrowseForFolder

Started by Mr Earl, February 22, 2006, 10:04:10 AM

Previous topic - Next topic

Mr Earl

I don't understand how to use the ITEMIDLIST to specify a root folder for SHBrowseForFolder.
Does anyone have an example? Thanks.

donkey

All items managed by the Shell are children of the namespace or desktop, an ID list is simply an array of identifying structures that trace the path back to the desktop. There are many functions that use IDLs and many that manipulate them. The easiest are the wrappers found in SHLWAPI.DLL but a much more powerful method uses the IShellFolder interface. For example if you wish to obtain a pointer to the MyDocuments folder using IShellFolder you would use the following...

LOCAL psfDesktop :D
LOCAL pidlDocFile[64] :D
LOCAL chEaten :D

// Get a pointer to the IShellFolder interface
invoke SHGetDesktopFolder, offset psfDesktop

CoInvoke(psfDesktop,IShellFolder.ParseDisplayName,0,0, \
L"::{450d8fba-ad25-11d0-98a8-0800361b1103}",offset chEaten, \
offset pidlDocFile,0)

CoInvoke(psfDesktop, IShellFolder.IUnknown.Release)

invoke SHGetPathFromIDListA,[pidlDocFile],[lpOutput]


The ParseDisplayName method of IShellFolder will return a pidl to any folder that can subsequently be used with SHBrowseForFolder. In this case the MyDocuments folder is identified by a GUID but any UNICODE path name can be substituted and it will return that folders pidl. Remember that you rarely manipulate IDLs directly, most functions only require a pointer to the list and they must be freed after use using IMalloc...

invoke CoGetMalloc,1,offset pIMalloc
CoInvoke(pIMalloc,IMalloc.Free,[pidl])
CoInvoke(pIMalloc,IMalloc.IUnknown.Release)


Ofcourse there are many non-COM functions that are wrappers for these interfaces but for myself at least, I prefer to use the Shell interfaces directly. To use these functions you need the vTables that define the COM interfaces...


Unknown STRUCT
QueryInterface DD ?
AddRef DD ?
Release DD ?
ENDS

IShellFolder STRUCT
IUnknown Unknown <>

ParseDisplayName DD ?
EnumObjects DD ?
BindToObject DD ?
BindToStorage DD ?
CompareIDs DD ?
CreateViewObject DD ?
GetAttributesOf DD ?
GetUIObjectOf DD ?
GetDisplayNameOf DD ?
SetNameOf DD ?
ENDS

IMalloc STRUCT
IUnknown Unknown <>

Alloc DD ?
Realloc DD ?
Free DD ?
GetSize DD ?
DidAlloc DD ? 
HeapMinimize DD ?
ENDS


This is probably way too much information but it is the best way I know to explain it.

Edgar
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

donkey

By the way, CoInvoke is a macro that I wrote for GoAsm, different assemblers have different implementations of the CoInvoke macro so you will have to check to see how to use yours but they all resolve to the same thing...

CoInvoke(%pInterface,%Method,%0,%1,%2,%3,%4,%5,%6,%7,%8,%9) = \
#IF ARGCOUNT = 12 \
push %9 \
#ENDIF \
#IF ARGCOUNT > 10 \
push %8 \
#ENDIF \
#IF ARGCOUNT > 9 \
push %7 \
#ENDIF \
#IF ARGCOUNT > 8 \
push %6 \
#ENDIF \
#IF ARGCOUNT > 7 \
push %5 \
#ENDIF \
#IF ARGCOUNT > 6 \
push %4 \
#ENDIF \
#IF ARGCOUNT > 5 \
push %3 \
#ENDIF \
#IF ARGCOUNT > 4 \
push %2 \
#ENDIF \
#IF ARGCOUNT > 3 \
push %1 \
#ENDIF \
#IF ARGCOUNT > 2 \
push %0 \
#ENDIF \
push [%pInterface] \
mov eax, [%pInterface] \
mov eax,[eax] \
add eax, %Method \
call [eax]
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Mr Earl

Thanks.  I'll take all the info I can get.  Have to chew on that a while.

xandaz

    Hey Donkey. I'm having trouble using COM functions. I need to use GetAttributesOf but dont really know how... Where's the CoInvoke macro. I couldnt find it. help me out will you? Thanks and bye.
    Best regards

ToutEnMasm

There is a sample of SHBrowseForFolder and more, coming with "the ready to use sdk" see  masm32 forum,windows.inc project
It is in
Quote
\sdkrc7\samples\read_shortcut

Glenn9999

Quote from: Mr Earl on February 22, 2006, 10:04:10 AM
I don't understand how to use the ITEMIDLIST to specify a root folder for SHBrowseForFolder.
Does anyone have an example? Thanks.

In studying SHBrowseForFolder, I found you can do a mind-bogglingly large number of things with it, indeed.  Even to the point of having a hard time testing everything.

This is one of them.  The question, though, varies depending on whether you are wanting to specify a special folder or a regular folder.  The root of the matter is finding the PIDL to represent this.

For special folders, you have to pick out the proper CSIDL constant.  For Windows XP, I have 28 of them recorded, and there are more for Windows Vista and Seven.  Once you identify that, you can call SHGetSpecialFolderLocation with the handle, CISDL constant, and return the PIDL you need into that unit of the BrowseInfo parm of SHBrowseForFolder.


SHGetSpecialFolderLocation(FHandle, sflag, IDRoot);
FBrowseInfo.pidlRoot := IDRoot;


Now for a regular root folder, Donkey pretty much covered it.  Get the IDesktopFolder COM instance, and then call ParseDisplayName and place the result into the pidlRoot part of the BrowseInfo parm.