This article explains how you can easily create a namespace extension with lots of features without doing lots of work by using some undocumented shell functions.
Index FunctionsThis article explains how you can easily create a namespace extension with lots of features without doing lots of work by using some undocumented shell functions. The most noticeable function is SHCreateShellFolderViewEx, which creates the view for you and creates all interfaces you need for displaying the contents of your folder. You can modify the behaviour of the folder by implementing a callback function. This is how Microsoft implements its own namespace extensions.
Introduction to the windows shellThe windows shell is built around COM interfaces. The browser ("explorer") calls interfaces that are implemented by a number of DLL's and these DLL's can call back into the interfaces of the browser. You can extend the behaviour of the browser by plugging in your own DLL that implements the needed interfaces.
The householding of the DLL's is maintained in the registry, as is usual for COM objects.
The shell namespaceThe shell namespace is a collection of folders that contain items. These items can in turn be folders, generating a tree structure. This ressembles the directory tree structure that is found in a file system, but should not be confused with it.
The top of the shell namespace tree is the Desktop folder. This folder contains "my computer", which in turn contains the drives on your computer. The part of the shell namespace that represents a drive looks almost the same as the directory structure on that drive, but is not exactly the same. The drive can contain additional items and existing items may look very different in the shell namespace.
Shell extensionsThe DLL's that are plugged into the shell are called shell extensions. There are several kinds of shell extensions:
Every item in a folder is identified by an identifier, just like every file or directory on a drive is identified by a filename. This identifier is called a Pidl.
For someone who uses the shell to browse the namespace, a pidl is just an opaque structure that gets passed around without having any meaning.
Someone who implements a part of the namespace assigns a meaning to the pidls for his part of the namespace. The pidl is a variable-sized structure that can contain anything the implementor wants to put in. The pidl usually caches all information that is frequently needed. In a directory structure, the pidl contains the long and short filename and some other stuff.
Structure of a pidlA item id consists of 2 parts: the length and the data. The length comes first and is the total length of the item (including the length part itself). The data is opaque to the user and only has meaning to the implementor of the namespace.
Multiple item ids are concatenated to form a pidl. A pidl is a series of concatenated item ids, ending with an id with length 0.
Absolute and relative pidlsA filename can be absolute or relative: An absulute filename is fully qualified (e.g. "c:\winnt\system32\shell32.dll"). A relative filename is relative to the directory in which it resides.
The same goes for a pidl. A pidl can be absolute or relative. The root for an absolute pidl is the desktop. A relative pidl is relative to a specific folder in the namespace.
Designing your pidlsIf you implement your own namespace extension, you will have to design your own pidls.
The easiest way to assign a meaning to your pidls is by defining a struct that contains all the information you need.
You must be able to determine if a pidl that is passed to you is really a valid pidl. You can do this by starting the pidl with a signature (a few bytes that are always the same).
The pidl should contain all information that will frequently be needed and that takes some time to find out. You should always store the name and all texts that are stored in the different columns in the details view, unless you can derive them easily.
Your pidl should contain one field that uniquely identifies the item. This can be a handle, an ID,...
You will be the only one who decides wether two pidls are for the same item. You will do that through your IShellFolder
's CompareIDs. Return 0 for pidls that represent the same object, and 1 or -1 for pidls that represent different objects (even if you don't care how they are sorted).
All pidls should always be allocated and freeed by the Shell Allocater.
You can retrieve the Shell Allocator by calling SHGetMalloc
.
Shortcuts for allocating and freeing pidls are provided by the functions SHAlloc and ILFree.
Pidl functions SHAllocWINSHELLAPI LPVOID WINAPI SHAlloc(UINT cb);Description
Allocates cb bytes of memory using the Shell Allocator
ParametersA pointer to the block of memory that was allocated
ILFreeWINSHELLAPI void WINAPI ILFree(LPITEMIDLIST pidl);Description
Frees a pidl using the Shell Allocator
I have no idea why there is both a SHfree function and an
ILFreefunction. They are probably exactly the same.
ILCloneWINSHELLAPI LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl);Description
Creates a copy of the passed in pidl
A pointer to the newly created copy of the pidl
The new pidl is allocated using the Shell Allocator. You should free it by calling ILFree.
ILAppendIDWINSHELLAPI LPITEMIDLIST WINAPI ILAppendID(LPITEMIDLIST pidl, LPCITEMIDLIST item,BOOL bEnd);Description
Appends a new item identifier to an existing pidl
This function destroys the passed in complex pidl.
ILCloneFirstWINSHELLAPI LPITEMIDLIST WINAPI ILCloneFirst(LPCITEMIDLIST pidl);Description
Creates a new pidl that contains the first item id of a complex pidl
A newly created pidl that contains the first item id of the passed in complex pidl
The new pidl is allocated with the Shell Allocator. You should free it by calling ILFree.
ILCombineWINSHELLAPI LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl, LPCITEMIDLIST pidlsub);Description
Concatenates two complex pidls
The newly created pidl
The passed in pidls are not destroyed. The newly created pidl is allocated using the Shell Allocator. You should free it by calling ILFree. This function is useful if you have a relative pidl of an item and the absolute pidl of its parent folder. The function returns the absolute pidl of the item.
ILCreateFromPath RemarksI didn't find out the exact signature of this function yet.
ILFindChildWINSHELLAPI LPITEMIDLIST WINAPI ILFindChild(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);Description
Compares the elements of a complex pidl
If at least the first item id is the same, returns the location of the first item id in pidl2 that doesn't match pidl1. NULL if pidl2 is shorter than pidl1
I never tested this function. The signature and description may not be correct.
ILFindLastIDWINSHELLAPI LPITEMIDLIST WINAPI ILFindLastID)(LPCITEMIDLIST pidl);Description
Finds the position of the last item id in a pidl
A pointer to the last item id in the passed in pidl
You can call ILClone(ILFindLastID(pidl)) to create a relative pidl out of an absolute pidl.
ILGetDisplayName RemarksI didn't find out the exact signature of this function yet.
ILGetNextWINSHELLAPI LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl);Description
This function finds the location of the second item id in a complex pidl
The position of the next item id in the pidl The pidl itself is the first item id, the next one is the second.
You can use ILClone(ILFindNextID(pidl)) to obtain a pidl of an item that is relative to the first parent folder. This can be very useful if you were passed a complex pidl in you IShellFolder implementation. You can split off the first item id, bind a new shell folder to this id and the,n pass this new folder the remainder of the pidl.
ILGetSizeWINSHELLAPI UINT WINAPI ILGetSize(LPCITEMIDLIST pidl);Description
Calculates the full size of a pidl
The total size of the passed in pidl in bytes, including the zero terminator
ILGlobalClone RemarksI didn't find out the exact signature of this function yet.
ILGlobalFree RemarksI didn't find out the exact signature of this function yet.
ILIsEqualWINSHELLAPI BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);Description
Tests two pidls for equality
Zero if the two pidls are different, nonzero if the pidls are equal
ILIsParent RemarksI didn't find out the exact signature of this function yet.
ILLoadFromStream RemarksI didn't find out the exact signature of this function yet.
ILRemoveLastIDWINSHELLAPI BOOL WINAPI ILRemoveLastID(LPCITEMIDLIST pidl);Description
Removes the last item identifier from a complex pidl
Nonzero if successful, zero otherwise
This function modifies the passed in pidl by setting the last item id's byte count to zero.
To create a new pidl without the last item id, you would have to call ILRemoveLastID(ILClone(pidl)).
I didn't find out the exact signature of this function yet.
Object modelThe shell is browsed by a Shell Browser object, which is implemented by the browser, usually Windows Explorer. This browser traverses the namespace.
The namespace is made up of Shell Folders. A Shell Folder is an object that represents a virtual folder, i.e. a filesystem directory or a namespace extension folder. The items of a Shell Folder are enumerated by an Item Enumerator. This object simply enumerates the pidls of objects.
The contents of a Shell Folder are viewed by a Shell View. The Shell View is a window that usually displays a list of items. A group of items (e.g. the items that are selected in a Shell View) is represented by a UI Object.
The Shell BrowserThe Shell Browser is the application that browses the namespace (Windows Explorer). The Shell Browser implements the interface IShellBrwoser. You will never implement this interface yourself.
Shell FoldersShell Folders represent folders in the namespace. They create new Shell Folders for their items and they create UI Objects. They provide information on their items. A Shell Folder implements a namespace extension.
Interfaces implemented by Shell FoldersA shell folder should implement IShellFolder
, IPersistFolder
, IDropTarget
, IExtractIcon
and IShellDetails
.
The IShellFolder
interface is used for getting information on items in a folder and as a factory for creating Item Enumerators, Shell Views and UI Objects. Most IShellFolder methods take pidls as parameters. These pidls are always relative to the Shell Folder.
The IPersistfolder
interface is only used to pass the shell folder its own absolute pidl.
The IDropTarget
interface is a standard OLE interface that is used for drag and drop.
The IExtractIcon
interface is used to get the icon for an item.
The IShellDetails
interface is used for communication with the Shell View. It provides some extra information about how to display items in a multi-column list: the titles for the columns and the details to fill in in these columns.
All these interfaces are well documented, except IShellDetails
. This interface is described later.
An item enumerator makes it possible to enumerate all items in a Shell Folder.
An Item Enumerator implements IEnumIDList. This is a common IEnumXXX
interface. This interface is well documented.
UI Objects handle user interaction with items. They implement shell extensions other than namespace extensions.
Possible UI objects are context menu handlers, property sheet handlers, infotip handlers.
UI Objects must be able to handle multiple selection.
Interfaces implemented by UI ObjectsUI Objects implement some are all of the following interfaces:IObjectWithSite
, IExternalConnection
, IShellExtInit
, IDataSource
, IContextMenu
, IShellPropSheetExt
and IQueryInfo
.
IObjectWithSite
is a standard OLE interface that is used for setting up communication between an object and the container in which it resides. In this case the container is the Shell Browser. You can omit thhis interface.
IExternalConnection
is used for maintaining strong locks on an object. This interface is needed because the object may be marshalled to another proces (e.g. during drag and drop).
You can omit this interface. In that case, OLE will provide a default interface for you.
IShellExtInit
is implemented by property sheet handlers and context menu handlers. These should always implement the interface. The IShellExtInit
interface only has one method Initialize, which is used for setting the context of the shell extension.
IDataSource
is a standard OLE interface. It is used mainly for drag and drop and for copy and paste. You can think of the IDataSource
interface as a way of serializing the set of items.
If your namespace extension has more than one folder, you can implement your own clip formats. The IDataSource
interface is too complex to be fully covered here.
Besides its obvious usage as a source of information for displaying a context menu, the IContextMenu
interface is used for some other purposes: When the user presses a standard button in the toolbar, IContextMenu::InvokeCommand
will be invoked with a verb. This verb will be a word like cut, copy, paste, delete or properties.
The IContextMenu
interface is also used to add items to the main menu of the browser's window. When QueryContextMenu
is called, you should add commands to the menu that have identifiers of the form idCmdFirst
+ SOME_CONSTANT
. When InvokeCommand
is called, the identifier SOME_CONSTANT
will be passed.
The IShellPropSheetExt
interface is used for displaying property pages.
The IQueryInfo
interface is used for displaying info tips when the mouse is moved over an item.
All these interfaces are well documented.
Shell ViewsShell views are the windows that display a shell folder's contents. Shell views implement IShellView
and some additional interfaces. Instead of implementing this object yourself, you should call SHCreateShellFolderViewEx
. This function creates the Shell View for you.
Besides the
IUnknown
functions, the
IShellDetails
interface has two functions:
GetDetailsOf
and
ColumnClick
.
HRESULT STDMETHODCALLTYPE GetDetailsOf(LPCITEMIDLIST pidl, UINT col, SHColInfo *data);Description
If pidl equals NULL, this function retrieves information about a column in the Shell View. Otherwise, it retrieves the information to display in a particular column of the view for a given pidl.
Return S_OK if you filled in the details, E_FAIL otherwise.
If pidl equals NULL, you should return S_OK for all columns that you support and E_FAIL for an index that is too large. This is how the Shell View will know how many columns to display.
HRESULT STDMETHODCALLTYPE ColumnClick(UINT col);Description
This function is called when the user clicks the title of a column.
You should send a SFVM_REARRANGE message to the owner of the view window.
You can use the function SHShellFolderView_Message to send the meassage. The window handle of the owner of the view window is passed to you in IShellFolder::CreateViewObject
. This is the time to save this handle.
The lparam that you should pass to SHShellFolderView_Message is the index of the column that was clicked (i.e. the col parameter).
After calling SHSHellFolderView_Message, IShellFolder::CompareIDs
will be called with an lParam that equals the index of the column that was clicked. This is contrary to the Microsoft documentation, which states that this lParam will always be zero and should be ignored.
WINSHELLAPI HRESULT WINAPI SHCreateShellFolderViewEx(LPSHELLVIEWDATA psvcbi, LPVOID *ppv);Description
This is the most interesting function I discovered. This function enables you to use the same mechanism as Microsoft for displaying the contents of your namespace extensions.
This function creates the Shell View for you, including the most important interfaces like IShellView
.
This function makes sure you will handle everything the way you should. It provides an easy interface for otherwise difficult tasks like changing the toolbar.
When calling this function, you pass a callback function that gets called to handle all kinds of events, enabling you to customize the shell view.
Call this function from your IShellFolder
's CreateViewObject
when riid is IID_IShellView
.
typedef struct _SHELLVIEWDATA { DWORD dwSize; LPSHELLFOLDER pShellFolder; DWORD dwUserParam; LPCITEMIDLIST pidl; DWORD dwEventId; SHELLVIEWPROC pCallBack; DWORD viewmode; } SHELLVIEWDATA, * LPSHELLVIEWDATA;Members:
dwSize
: sizeof(SHELLVIEWDATA)
pShellFolder
: Pointer to the shell folder that is creating a view objectdwUserParam
: A user-defined value that will be passed back in the callback functionpidl
: The absolute pidl of the folder that is being vieweddwEventId
: any combination of the SHCNE_
constants as described in the SHChangeNotify function. These are the notifications that should be handled by the view object.pCallback
: Pointer to your callback function (described later)viewmode
: NF_INHERITVIEW
or NF_LOCALVIEW
HRESULT CALLBACK SHELLVIEWPROC(DWORD dwUserParam, LPSHELLFOLDER psf, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);Description
This is the prototype of a function you should implement yourself. You pass a pointer to this function in SHCreateShellFolderViewEx.
CreateViewObject
. This owner is actually the parent of the view window. All messages are always sent to this owner window, so i don't really see the use of this hwnd parameter.This is the function that enables you to modify the behavior of the shell view. You can add toolbar buttons, change the menu and react on several events, all from within this function. This function is typically a large switch on uMsg. Te values for uMsg and the corresponding wParam
and lParam
are described below. The uMsg values all have a name that starts with SFVCB_
.
This message is sent when the user presses one of the toolbar buttons that you added.
The wParam value is the command id that you assigned to this toolbar button. Maybe you should use
LOWORD(wParam)
.
SFVCB_GETTOOLBARTIP DescriptionThis message is sent either when a tooltip is needed for a toolbar button or when a text label is needed if the toolbar displays text labels beneath the buttons.
This is the command ID, like in SFVCB_INVOKECOMMAND.
lParam is a pointer to a unicode buffer that will receive the text string.
This is the length of the buffer in unicode characters.
RemarksYou will typically callLo
<NOBR>adStringW(hInstance, ID_YOUR_COMMAND, (LPSTR)lParam,
HIWORD(wParam))</NOBR>
to react on this message. SFVCB_GETTOOLBARINFO DescriptionThis message allows you to change the toolbar. It is sent when the list view is first shown.
Pointer to a
SFVCB_TOOLBARINFOstructure to be filled in.
If you return
S_OK
, you will get a
SFVCB_ADDTOOLBARITEMS
message that allows you to provide the details of the buttons.
SFVCB_ADDTOOLBARITEMS DescriptionThis message is sent if you return
S_OK
to the
SFVCB_GETTOOLBARINFO
message. It is sent once to fill in details for all buttons.
This is a constant you should add to your command IDs, much like in
IContextMenu
. When the user presses a toolbar button, you will receive the ID you filled in minus this constant.
Pointer to an array of
SFVCB_TOOLBARBUTTONINFOstructures. The size of the array is equal to the number of buttons that was supplied in
SFVCB_GETTOOLBARINFO
.
SFVCB_INITMENUPOPUP DescriptionI don't know the exact meaning of this message.
SFVCB_SELECTIONCHANGED DescriptionThis message is sent when the selection changes in the list view.
Pointer to a
SFVCB_SELECTINFOstructure.
If the user selects/deselects multiple items at a time (e.g. using Shift), the message will be sent for every item.
SFVCB_DRAWMENUITEM DescriptionI don't know the exact meaning of this message.
SFVCB_MEASUREMENUITEM DescriptionI don't know the exact meaning of this message.
SFVCB_EXITMENULOOP DescriptionI don't know the exact meaning of this message.
SFVCB_VIEWRELEASE DescriptionI don't know the exact meaning of this message.
SFVCB_GETNAMELENGTH DescriptionI don't know the exact meaning of this message. The message is sent when beginning label edit.
SFVCB_CHANGENOTIFY DescriptionThis message is sent when
SHChangeNotify
is called for one of the items in the shell folder that is represented by this view.
Pointer to an array of the two pidls that were passed to
SHChangeNotify
.
The dwEventID that represents the event (e.g.
SHCNE_RENAMEITEM
)
SFVCB_WINDOWCREATED DescriptionThis message is sent when the window is created
The
HWND
of the newly created window
SFVCB_WINDOWCLOSING DescriptionI don't know the exact meaning of this message.
SFVCB_LISTREFRESHED DescriptionI don't know the exact meaning of this message.
SFVCB_WINDOWFOCUSED DescriptionThis message is sent to inform you that the list view has received the focus.
SFVCB_REGISTERCOPYHOOK DescriptionI don't know the exact meaning of this message.
SFVCB_COPYHOOKCALLBACK DescriptionI don't know the exact meaning of this message.
SFVCB_GETDETAILSOF DescriptionThis message is sent to if you don't implement
IShellDetails.
Pointer to a
SFVCB_COLUMNINFOSTRUCTstructure. The
STRRET
has to be filled in.
The column for which the info is requested.
The pidl in the
SFVCB_COLUMNINFOSTRUCTstructure will be NULL to request the title of a column.
SFVCB_COLUMNCLICK DescriptionThis message is sent if you don't implement
IShellDetails.
The index of the column that was clicked
The default implementation would be
SHShellFolderView_Message(hWndCabinet,
SFVM_REARRANGE, wParam) where hWndCabinet is the window handle that was passes in
IShellFolder::GetViewObjectOf
.
SFVCB_GETCHANGENOTIFYPIDL DescriptionUse this message to change the pidl to watch for change notifications. This is only useful of you will call
SHChangeNotify
with another pidl than the one specified in
SHCreateShellFolderViewEx
.
Pointer to a complex pidl to be filled in
It seems that specifying a NULL pidl is just the same as failing the message. You will probably never use this one.
SFVCB_COLUMNCLICK2 DescriptionThe same as
SFVCB_COLUMNCLICK
, but called when you do implement
IShellDetails.
typedef struct { DWORD fJustify; INT nWidth; STRRET text; } SHColInfo, *PSHCOLINFO;SFVCB_COLUMNINFOSTRUCT
typedef struct tag_SFVCB_COLUMNINFOSTRUCT { LPCITEMIDLIST pidl; SHColInfo sci; } SFVCB_COLUMNINFOSTRUCT, *LPSFVCB_COLUMNINFOSTRUCT;SFVCB_TOOLBARINFO
typedef struct tag_SFVCB_TOOLBARINFO { DWORD dwNumItems; DWORD dwPos; } SFVCB_TOOLBARINFO;SFVCB_TOOLBARBUTTONINFO
typedef struct tag_SFVCB_TOOLBARBUTTONINFO { DWORD dwBitmap; DWORD dwCommand; DWORD dwFlags; DWORD reserved1; DWORD reserved2; } SFVCB_TOOLBARBUTTONINFO;SFVCB_SELECTINFO
typedef struct tag_SFVCB_SELECTINFO { DWORD reserved; DWORD dwFLAGS; LPITEMIDLIST pidl; } SFVCB_SELECTINFO;The function SHShellFolderView_Message The function
WINSHELLAPI int WINAPI SHShellFolderView_Message(HWND hwndCabinet, UINT uMsg, LPARAM lParam);Description
This function can be used to send some special messages to the cabinet window. These messages have mostly to do with gatherring information about items and changing some attributes of some items.
ParametersIShellFolder::CreateViewObject
SFVM_
constants that are described laterSFVM_REARRANGE
for that. SFVM_REARRANGEThis message indicates that the user has clicked a column in the header of the list control. The list needs to be rearranged.
lParamThe index of the column on which to sort (starting at 0). This value will be passes to IShellFolder::CompareIDs
. SFVM_GETARRANGECOLUMNTo be done. SFVM_ADDOBJECTTo be done. SFVM_GETITEMCOUNT DescriptionUsed to retrieve the number of items in the list.
Return valueThe number of items in the list SFVM_GETITEMPIDLTo be done. SFVM_REMOVEOBJECT DescriptionUse this message to remove an item from the list.
lParamlParam is a relative pidl of the object to remove. You can specify NULL to remove all items. SFVM_UPDATEOBJECTTo be done. SFVM_SETREDRAWTo be done. SFVM_GETSELECTEDOBJECTS DescriptionUse this message to retrieve an array of pidls for all selected objects.
lParam is actually of type
(LPITEMID **)
. It is a pointer to a pointer that receives the address of an array of pidls. Use
SFVM_GETSELECTEDCOUNT
to learn the size of this array.
SFVM_ISDROPONSOURCETo be done.
SFVM_MOVEICONSTo be done.
SFVM_GETDRAGPOINTTo be done.
SFVM_GETDROPPOINTTo be done.
SFVM_SETOBJECTPOSTo be done.
SFVM_ISDROPONBACKGROUNDTo be done.
SFVM_CUTOBJECTSTo be done.
SFVM_TOGGLEAUTOARRANGETo be done.
SFVM_LINEUPICONSTo be done.
SFVM_GETAUTOARRANGETo be done.
SFVM_GETSELECTEDCOUNT DescriptionThis message can be used to learn how many items are selected in the list.
Return valueThe number of selected items SFVM_GETITEMSPACINGTo be done. SFVM_REFRESHOBJECTTo be done. SFVM_SETCLIPBOARDPOINTSTo be done. Shell messagesThere are some undocumented messages that can be sent to a cabinet window. This is again the window that is passed as hwndOwner in IShellFolder::CreateViewObject. CWM_SETPATH wParamA combination of one or more of the flagsCSP_HANDLE
and CSP_REPOST
. CSP_REPOST
indicates the message should not be handled immediately.
If
CSP_HANDLE
is specified, lParam is a
HGLOBAL
that contains a string. This memory will be freed when the message is handled.
Otherwise, lParam points to a string.
CWM_WANTIDLE MacroThis message can be sent using the following macro:
FileCabinet_WantIdle(_hwnd, _user, _lpidlproc)
Use this message if you created a window using
SHCreateShellFolderViewExand you want to do idle processing in your window.
wParam (the _user in the macro) is a user-defined value that will be passed to the idle proc.
lParam (the _lpidlproc in the macro) is the idle proc that should be called. This function is of the type
FCIDLEPROC
.
non-zero if successful, zero otherwise
CWM_GETSETCURRENTINFO MacroFileCabinet_GetSetCurrentInfo(_hwnd, _bSet, _lpfs)
This message is used to retrieve or change the current folder settings.
wParamwParam is the_bSet
in the macro. If it is zero, the settings are being retrieved. Otherwise, they are being set.
lParamlParam is the _lpfs in the macro. It points to a FOLDERSETTINGS
structure that contains the values to set or receives the current values, depending on wParam. CWM_SELECTITEM MacroFileCabinet_SelectItem(_hwnd, _bSel, _lpidl)
DescriptionUse this message to select/deselect an item.
wParamwParam is the _bSel in the macro. If it is zero, the item is selected. Otherwise, the item is deselected.
lParamlParam is the _lpidl in the macro. It is the pidl of the item to select/deselect. Use NULL to select/deselect all items. CWM_STOPWAITING MacroFileCabinet_StopWaiting(_hwnd
)
One source defines the same message as
CWM_SELECTITEMSTR
. I don't know which one is right.
CWM_GETISHELLBROWSER MacroFileCabinet_GetIShellBrowser(_hwnd)
Returns an
IShellBrowser
interface pointer of the shell browser that created the window.
The returned IShellFolder interface is not AddRef'ed, so you should not call Release on the interface. This message is sent frequently by all microsoft namespace extensions and is the most important one. This message is described in the Microsoft Knowledge Base article Q157247.
CWM_TESTPATHTo be done.
CWM_STATECHANGETo be done.
CWM_GETPATHTo be done.
FCIDLEPROCtypedef BOOL (CALLBACK *FCIDLEPROC)(void FAR *lpsv, UINT uID);Description
This is the idle proc that will be called if you send
CWM_WANTIDLE
.
ParamaetersCWM_WANTIDLE
Return zero if your idle-time processing has finished.
Remarksyou should make this function as short as possible. To perform multiple tasks, process one atomic task in every call and return non-zero until all jobs are finished.
Some helper functions ShlExtInitvoid ShlExtInit()Description
Performs dynamic binding to the shell32 functions.
ShlExtUninitvoid ShlExtUninit()Description
Cleans up the dynamic binding that was set up by ShlExtInit.
ILCreateLPITEMIDLIST ILCreate(LPVOID pData, DWORD dwLen)Description
Allocates and initializes a simple pidl
ParametersThe newly created pidl
ILGetCountint ILGetCount(LPCITEMIDLIST pidl)Description
calculates teh number of item IDs in a complex pidl
ParametersThe number of item IDs that make up this complex pidl
PrintInterfaceNamevoid PrintInterfaceName(REFIID riid)Description
Sends the name of an interface to the debugger
Useful to trace QueryInterface calls
ParametersBOOL IsInterfaceSupported(IUnknown *punk, REFIID riid)Description
Determines wether an object supports a given interface
ParametersNon-zero if the interface is supported, zero otherwise.
PrintSupportedInterfacesvoid PrintSupportedInterfaces(IUnknown *punk)Description
Sends the names of all interfaces of an object to the debugger.
When you receive an interface while debugging, this function can come in very handy.
ParametersIUnknown
interface of the object for which to print the interfacesYou don't have to do anything in your code to implement a web view. You only have to create your web page and link your class id to it in the registry.
The web pageYou should base your web page on the web pages that are created by Microsoft. On windows NT, you can find them in the directory winnt\web. A typical example is folder.htt, the web page for a normal folder. Just copy this web page and edit it to suit your needs.
There is one little problem: Microsoft changed the look of these web pages with every release of Windows, so you would have to provide separate web pages for all operating system versions.
Registry enteriesExplorer will rely on the class id that is returned by your
IPersistFolder
's
GetClassID
. As you know (and is very well documented), all information about your class is gathered in HKEY_CLASSES_ROOT\CLSID\{yourclassid}. There should already be a subkey shellex. In this shellex, you should create a subkey ExtShellFolderView, which again contains a subkey {5984FFE0-28D4-11CF-AE66-08002B2E1262}. In this subkey, you create an entry with the name PersistMoniker. It's value should be the full path of your web page.
ReferencesMost of this stuff wasn't invented by me. You can find more information on the following locations:
You should also take a look at the shlext.h header file. It contains some information that is not included on this page.
FeedbackIf you use the information on this page, you will probably discover things that are still missing here. You can see that there are lots of "to be done" bits. It is important to make that information available, so that you make the life of other developers a little easier. Please send me all your comments, sugestions and discoveries by
emailor leave comments on the codeproject site. All new discoveries will be available on my
home pageas soon as possible, and major updates will be posted on the codeproject site.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.3