home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1997 May
/
Pcwk0597.iso
/
borland
/
cb
/
setup
/
cbuilder
/
data.z
/
SHLOBJ.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1997-02-28
|
42KB
|
955 lines
{*******************************************************}
{ }
{ Delphi Runtime Library }
{ Windows 32bit API Interface Unit }
{ }
{ Copyright (c) 1996 Borland International }
{ }
{*******************************************************}
unit ShlObj;
interface
uses Windows, OLE2, CommCtrl, ShellAPI, RegStr, Messages;
{ Object identifiers in the explorer's name space (ItemID and IDList)
All the items that the user can browse with the explorer (such as files,
directories, servers, work-groups, etc.) has an identifier which is unique
among items within the parent folder. Those identifiers are called item
IDs (SHITEMID). Since all its parent folders have their own item IDs,
any items can be uniquely identified by a list of item IDs, which is called
an ID list (ITEMIDLIST).
ID lists are almost always allocated by the task allocator (see some
description below as well as OLE 2.0 SDK) and may be passed across
some of shell interfaces (such as IShellFolder). Each item ID in an ID list
is only meaningful to its parent folder (which has generated it), and all
the clients must treat it as an opaque binary data except the first two
bytes, which indicates the size of the item ID.
When a shell extension -- which implements the IShellFolder interace --
generates an item ID, it may put any information in it, not only the data
with that it needs to identifies the item, but also some additional
information, which would help implementing some other functions efficiently.
For example, the shell's IShellFolder implementation of file system items
stores the primary (long) name of a file or a directory as the item
identifier, but it also stores its alternative (short) name, size and date
etc.
When an ID list is passed to one of shell APIs (such as SHGetPathFromIDList),
it is always an absolute path -- relative from the root of the name space,
which is the desktop folder. When an ID list is passed to one of IShellFolder
member function, it is always a relative path from the folder (unless it
is explicitly specified). }
const
CLSID_ShellDesktop: TGUID = (
D1:$00021400; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
CLSID_ShellLink: TGUID = (
D1:$00021401; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
IID_IContextMenu : TGUID = (
D1:$000214E4; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
IID_IShellFolder : TGUID = (
D1:$000214E6; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
IID_IShellExtInit : TGUID = (
D1:$000214E8; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
IID_IShellPropSheetExt : TGUID = (
D1:$000214E9; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
IID_IExtractIcon : TGUID = (
D1:$000214EB; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
IID_IShellLink : TGUID = (
D1:$000214EE; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
IID_IShellCopyHook : TGUID = (
D1:$000214EF; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
IID_IFileViewer : TGUID = (
D1:$000214F0; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
IID_IEnumIDList : TGUID = (
D1:$000214F2; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
IID_IFileViewerSite : TGUID = (
D1:$000214F3; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
type
{ TSHItemID -- Item ID }
PSHItemID = ^TSHItemID;
TSHItemID = packed record { mkid }
cb: Word; { Size of the ID (including cb itself) }
abID: array[0..0] of Byte; { The item ID (variable length) }
end;
{ TItemIDList -- List if item IDs (combined with 0-terminator) }
PItemIDList = ^TItemIDList;
TItemIDList = packed record { idl }
mkid: TSHItemID;
end;
{ Task allocator API }
{ All the shell extensions MUST use the task allocator (see OLE 2.0
programming guild for its definition) when they allocate or free
memory objects (mostly ITEMIDLIST) that are returned across any
shell interfaces. There are two ways to access the task allocator
from a shell extension depending on whether or not it is linked with
OLE32.DLL or not (virtual; stdcall; abstractly for efficiency).
(1) A shell extension which calls any OLE API (i.e., linked with
OLE32.DLL) should call OLE's task allocator (by retrieving
the task allocator by calling CoGetMalloc API).
(2) A shell extension which does not call any OLE API (i.e., not linked
with OLE32.DLL) should call the shell task allocator API (defined
below), so that the shell can quickly loads it when OLE32.DLL is not
loaded by any application at that point. }
{ !!! Notes:
In next version of Windowso release, SHGetMalloc will be replaced by
the following macro.
#define SHGetMalloc(ppmem) CoGetMalloc(MEMCTX_TASK, ppmem) }
// !!! function SHGetMalloc(var ppMalloc: IMalloc): HResult;
function SHGetMalloc(var ppMalloc: IMalloc): HResult; stdcall;
{ IContextMenu interface }
{ [OverView] }
{ The shell uses the IContextMenu interface in following three cases.
case-1: The shell is loading context menu extensions.
When the user clicks the right mouse button on an item within the shell's
name space (i.g., file, directory, server, work-group, etc.), it creates
the default context menu for its type, then loads context menu extensions
that are registered for that type (and its base type) so that they can
add extra menu items. Those context menu extensions are registered at
HKCR\beginProgIDend\shellex\ContextMenuHandlers.
case-2: The shell is retrieving a context menu of sub-folders in extended
name-space.
When the explorer's name space is extended by name space extensions,
the shell calls their IShellFolder::GetUIObjectOf to get the IContextMenu
objects when it creates context menus for folders under those extended
name spaces.
case-3: The shell is loading non-default drag and drop handler for directories.
When the user performed a non-default drag and drop onto one of file
system folders (i.e., directories), it loads shell extensions that are
registered at HKCR\beginProgIDend\DragDropHandlers. }
{ [Member functions] }
{ IContextMenu::QueryContextMenu }
{ This member function may insert one or more menuitems to the specified
menu (hmenu) at the specified location (indexMenu which is never be -1).
The IDs of those menuitem must be in the specified range (idCmdFirst and
idCmdLast). It returns the maximum menuitem ID offset (ushort) in the
'code' field (low word) of the scode.
The uFlags specify the context. It may have one or more of following
flags.
CMF_DEFAULTONLY: This flag is passed if the user is invoking the default
action (typically by double-clicking, case 1 and 2 only). Context menu
extensions (case 1) should not add any menu items, and returns NOERROR.
CMF_VERBSONLY: The explorer passes this flag if it is constructing
a context menu for a short-cut object (case 1 and case 2 only). If this
flag is passed, it should not add any menu-items that is not appropriate
from a short-cut.
A good example is the 'Delete' menuitem, which confuses the user
because it is not clear whether it deletes the link source item or the
link itself.
CMF_EXPLORER: The explorer passes this flag if it has the left-side pane
(case 1 and 2 only). Context menu extensions should ignore this flag.
High word (16-bit) are reserved for context specific communications
and the rest of flags (13-bit) are reserved by the system. }
{ IContextMenu::InvokeCommand }
{ This member is called when the user has selected one of menuitems that
are inserted by previous QueryContextMenu member. In this case, the
LOWORD(lpici->lpVerb) contains the menuitem ID offset (menuitem ID -
idCmdFirst).
This member function may also be called programmatically. In such a case,
lpici->lpVerb specifies the canonical name of the command to be invoked,
which is typically retrieved by GetCommandString member previously.
Parameters in lpci:
cbSize -- Specifies the size of this structure (sizeof(*lpci))
hwnd -- Specifies the owner window for any message/dialog box.
fMask -- Specifies whether or not dwHotkey/hIcon paramter is valid.
lpVerb -- Specifies the command to be invoked.
lpParameters -- Parameters (optional)
lpDirectory -- Working directory (optional)
nShow -- Specifies the flag to be passed to ShowWindow (SW_*).
dwHotKey -- Hot key to be assigned to the app after invoked (optional).
hIcon -- Specifies the icon (optional). }
{ IContextMenu::GetCommandString }
{ This member function is called by the explorer either to get the
canonical (language independent) command name (uFlags == GCS_VERB) or
the help text ((uFlags & GCS_HELPTEXT) != 0) for the specified command.
The retrieved canonical string may be passed to its InvokeCommand
member function to invoke a command programmatically. The explorer
displays the help texts in its status bar; therefore, the length of
the help text should be reasonably short (<40 characters).
Parameters:
idCmd -- Specifies menuitem ID offset (from idCmdFirst)
uFlags -- Either GCS_VERB or GCS_HELPTEXT
pwReserved -- Reserved (must pass NULL when calling, must ignore when called)
pszName -- Specifies the string buffer.
cchMax -- Specifies the size of the string buffer. }
const
{ QueryContextMenu uFlags }
CMF_NORMAL = $00000000;
CMF_DEFAULTONLY = $00000001;
CMF_VERBSONLY = $00000002;
CMF_EXPLORE = $00000004;
CMF_RESERVED = $FFFF0000; { View specific }
{ GetCommandString uFlags }
GCS_VERB = $00000000; { canonical verb }
GCS_HELPTEXT = $00000001; { help text (for status bar) }
GCS_VALIDATE = $00000002; { validate command exists }
CMDSTR_NEWFOLDER = 'NewFolder';
CMDSTR_VIEWLIST = 'ViewList';
CMDSTR_VIEWDETAILS = 'ViewDetails';
CMIC_MASK_HOTKEY = SEE_MASK_HOTKEY;
CMIC_MASK_ICON = SEE_MASK_ICON;
CMIC_MASK_FLAG_NO_UI = SEE_MASK_FLAG_NO_UI;
CMIC_MASK_MODAL = $80000000; { Internal }
// CMIC_VALID_SEE_FLAGS = !!! not found -> SEE_VALID_CMIC_FLAGS; ( Internal }
type
PCMInvokeCommandInfo = ^TCMInvokeCommandInfo;
TCMInvokeCommandInfo = packed record
cbSize: DWORD; { must be sizeof(CMINVOKECOMMANDINFO) }
fMask: DWORD; { any combination of CMIC_MASK_* }
hwnd: HWND; { might be NULL (indicating no owner window) }
lpVerb: LPCSTR; { either a string of MAKEINTRESOURCE(idOffset) }
lpParameters: LPCSTR; { might be NULL (indicating no parameter) }
lpDirectory: LPCSTR; { might be NULL (indicating no specific directory) }
nShow: Integer; { one of SW_ values for ShowWindow() API }
dwHotKey: DWORD;
hIcon: THandle;
end;
IContextMenu = class(IUnknown)
function QueryContextMenu(Menu: HMENU;
indexMenu, idCmdFirst, idCmdLast, uFlags: UINT): HResult; virtual; stdcall; abstract;
function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; virtual; stdcall; abstract;
function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
pszName: LPSTR; cchMax: UINT): HResult; virtual; stdcall; abstract;
end;
{ Interface: IShellExtInit }
{ The IShellExtInit interface is used by the explorer to initialize shell
extension objects. The explorer (1) calls CoCreateInstance (or equivalent)
with the registered CLSID and IID_IShellExtInit, (2) calls its Initialize
member, then (3) calls its QueryInterface to a particular interface (such
as IContextMenu or IPropSheetExt and (4) performs the rest of operation. }
{ [Member functions] }
{ IShellExtInit.Initialize }
{ This member function is called when the explorer is initializing either
context menu extension, property sheet extension or non-default drag-drop
extension.
Parameters: (context menu or property sheet extension)
pidlFolder -- Specifies the parent folder
lpdobj -- Spefifies the set of items selected in that folder.
hkeyProgID -- Specifies the type of the focused item in the selection.
Parameters: (non-default drag-and-drop extension)
pidlFolder -- Specifies the target (destination) folder
lpdobj -- Specifies the items that are dropped (see the description
about shell's clipboard below for clipboard formats).
hkeyProgID -- Specifies the folder type. }
type
IShellExtInit = class(IUnknown)
function Initialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
hKeyProgID: HKEY): HResult; virtual; stdcall; abstract;
end;
{=========================================================================== }
{ Interface: IShellPropSheetExt }
{ The explorer uses the IShellPropSheetExt to allow property sheet
extensions or control panel extensions to add additional property
sheet pages. }
{ [Member functions] }
{ IShellPropSheetExt.AddPages }
{ The explorer calls this member function when it finds a registered
property sheet extension for a particular type of object. For each
additional page, the extension creates a page object by calling
CreatePropertySheetPage API and calls lpfnAddPage.
Parameters:
lpfnAddPage -- Specifies the callback function.
lParam -- Specifies the opaque handle to be passed to the callback function. }
{ IShellPropSheetExt.ReplacePage }
{ The explorer never calls this member of property sheet extensions. The
explorer calls this member of control panel extensions, so that they
can replace some of default control panel pages (such as a page of
mouse control panel).
Parameters:
uPageID -- Specifies the page to be replaced.
lpfnReplace Specifies the callback function.
lParam -- Specifies the opaque handle to be passed to the callback function. }
type
IShellPropSheetExt = class(IUnknown)
function AddPages(lpfnAddPage: TFNAddPropSheetPage; lParam: LPARAM): HResult; virtual; stdcall; abstract;
function ReplacePage(uPageID: UINT; lpfnReplaceWith: TFNAddPropSheetPage;
lParam: LPARAM): HResult; virtual; stdcall; abstract;
end;
{ IExtractIcon interface }
{ This interface is used in two different places in the shell.
Case-1: Icons of sub-folders for the scope-pane of the explorer.
It is used by the explorer to get the 'icon location' of
sub-folders from each shell folders. When the user expands a folder
in the scope pane of the explorer, the explorer does following:
(1) binds to the folder (gets IShellFolder),
(2) enumerates its sub-folders by calling its EnumObjects member,
(3) calls its GetUIObjectOf member to get IExtractIcon interface
for each sub-folders.
In this case, the explorer uses only IExtractIcon.GetIconLocation
member to get the location of the appropriate icon. An icon location
always consists of a file name (typically DLL or EXE) and either an icon
resource or an icon index.
Case-2: Extracting an icon image from a file
It is used by the shell when it extracts an icon image
from a file. When the shell is extracting an icon from a file,
it does following:
(1) creates the icon extraction handler object (by getting its CLSID
under the beginProgIDend\shell\ExtractIconHanler key and calling
CoCreateInstance requesting for IExtractIcon interface).
(2) Calls IExtractIcon.GetIconLocation.
(3) Then, calls IExtractIcon.Extract with the location/index pair.
(4) If (3) returns NOERROR, it uses the returned icon.
(5) Otherwise, it recursively calls this logic with new location
assuming that the location string contains a fully qualified path name.
From extension programmer's point of view, there are only two cases
where they provide implementations of IExtractIcon:
Case-1) providing explorer extensions (i.e., IShellFolder).
Case-2) providing per-instance icons for some types of files.
Because Case-1 is described above, we'll explain only Case-2 here.
When the shell is about display an icon for a file, it does following:
(1) Finds its ProgID and ClassID.
(2) If the file has a ClassID, it gets the icon location string from the
'DefaultIcon' key under it. The string indicates either per-class
icon (e.g., 'FOOBAR.DLL,2') or per-instance icon (e.g., '%1,1').
(3) If a per-instance icon is specified, the shell creates an icon
extraction handler object for it, and extracts the icon from it
(which is described above).
It is important to note that the shell calls IExtractIcon.GetIconLocation
first, then calls IExtractIcon.Extract. Most application programs
that support per-instance icons will probably store an icon location
(DLL/EXE name and index/id) rather than an icon image in each file.
In those cases, a programmer needs to implement only the GetIconLocation
member and it Extract member simply returns S_FALSE. They need to
implement Extract member only if they decided to store the icon images
within files themselved or some other database (which is very rare). }
{ [Member functions] }
{ IExtractIcon.GetIconLocation }
{ This function returns an icon location.
Parameters:
uFlags [in] -- Specifies if it is opened or not (GIL_OPENICON or 0)
szIconFile [out] -- Specifies the string buffer buffer for a location name.
cchMax [in] -- Specifies the size of szIconFile (almost always MAX_PATH)
piIndex [out] -- Sepcifies the address of UINT for the index.
pwFlags [out] -- Returns GIL_* flags
Returns:
NOERROR, if it returns a valid location; S_FALSE, if the shell use a
default icon.
Notes: The location may or may not be a path to a file. The caller can
not assume anything unless the subsequent Extract member call returns
S_FALSE.
if the returned location is not a path to a file, GIL_NOTFILENAME should
be set in the returned flags. }
{ IExtractIcon.Extract }
{ This function extracts an icon image from a specified file.
Parameters:
pszFile [in] -- Specifies the icon location (typically a path to a file).
nIconIndex [in] -- Specifies the icon index.
phiconLarge [out] -- Specifies the HICON variable for large icon.
phiconSmall [out] -- Specifies the HICON variable for small icon.
nIconSize [in] -- Specifies the size icon required (size of large icon)
LOWORD is the requested large icon size
HIWORD is the requested small icon size
Returns:
NOERROR, if it extracted the from the file.
S_FALSE, if the caller should extract from the file specified in the
location. }
const
{ GetIconLocation() input flags }
GIL_OPENICON = $0001 { allows containers to specify an 'open' look };
GIL_FORSHELL = $0002 { icon is to be displayed in a ShellFolder };
{ GetIconLocation() return flags }
GIL_SIMULATEDOC = $0001 { simulate this document icon for this };
GIL_PERINSTANCE = $0002 { icons from this class are per instance (each file has its own) };
GIL_PERCLASS = $0004 { icons from this class per class (shared for all files of this type) };
GIL_NOTFILENAME = $0008 { location is not a filename, must call .Extract };
GIL_DONTCACHE = $0010 { this icon should not be cached };
type
IExtractIcon = class(IUnknown) { exic }
function GetIconLocation(uFlags: UINT; szIconFile: LPSTR; cchMax: UINT;
var piIndex: Integer; var pwFlags: UINT): HResult; virtual; stdcall; abstract;
function Extract(pszFile: LPCSTR; nIconIndex: UINT; var phiconLarge: HICON;
var phiconSmall: HICON; nIconSize: UINT): HResult; virtual; stdcall; abstract;
end;
{ IShellLink Interface }
const
{ IShellLink.Resolve fFlags }
SLR_NO_UI = $0001;
SLR_ANY_MATCH = $0002;
SLR_UPDATE = $0004;
{ IShellLink.GetPath fFlags }
SLGP_SHORTPATH = $0001;
SLGP_UNCPRIORITY = $0002;
type
IShellLink = class(IUnknown) { sl }
function GetPath(pszFile: LPSTR; cchMaxPath: Integer;
var pfd: TWin32FindData; fFlags: DWORD): HResult; virtual; stdcall; abstract;
function GetIDList(var ppidl: PItemIDList): HResult; virtual; stdcall; abstract;
function SetIDList(pidl: PItemIDList): HResult; virtual; stdcall; abstract;
function GetDescription(pszName: LPSTR; cchMaxName: Integer): HResult; virtual; stdcall; abstract;
function SetDescription(pszName: LPSTR): HResult; virtual; stdcall; abstract;
function GetWorkingDirectory(pszDir: LPSTR; cchMaxPath: Integer): HResult; virtual; stdcall; abstract;
function SetWorkingDirectory(pszDir: LPSTR): HResult; virtual; stdcall; abstract;
function GetArguments(pszArgs: LPSTR; cchMaxPath: Integer): HResult; virtual; stdcall; abstract;
function SetArguments(pszArgs: LPSTR): HResult; virtual; stdcall; abstract;
function GetHotkey(var pwHotkey: Word): HResult; virtual; stdcall; abstract;
function SetHotkey(wHotkey: Word): HResult; virtual; stdcall; abstract;
function GetShowCmd(var piShowCmd: Integer): HResult; virtual; stdcall; abstract;
function SetShowCmd(iShowCmd: Integer): HResult; virtual; stdcall; abstract;
function GetIconLocation(pszIconPath: LPSTR; cchIconPath: Integer;
var piIcon: Integer): HResult; virtual; stdcall; abstract;
function SetIconLocation(pszIconPath: LPSTR; iIcon: Integer): HResult; virtual; stdcall; abstract;
function SetRelativePath(pszPathRel: LPSTR; dwReserved: DWORD): HResult; virtual; stdcall; abstract;
function Resolve(Wnd: HWND; fFlags: DWORD): HResult; virtual; stdcall; abstract;
function SetPath(pszFile: LPSTR): HResult; virtual; stdcall; abstract;
end;
{ ICopyHook Interface }
{ The copy hook is called whenever file system directories are
copy/moved/deleted/renamed via the shell. It is also called by the shell
on changes of status of printers.
Clients register their id under STRREG_SHEX_COPYHOOK for file system hooks
and STRREG_SHEx_PRNCOPYHOOK for printer hooks.
the CopyCallback is called prior to the action, so the hook has the chance
to allow, deny or cancel the operation by returning the falues:
IDYES - means allow the operation
IDNO - means disallow the operation on this file, but continue with
any other operations (eg. batch copy)
IDCANCEL - means disallow the current operation and cancel any pending
operations
arguments to the CopyCallback
hwnd - window to use for any UI
wFunc - what operation is being done
wFlags - and flags (FOF_*) set in the initial call to the file operation
pszSrcFile - name of the source file
dwSrcAttribs - file attributes of the source file
pszDestFile - name of the destiation file (for move and renames)
dwDestAttribs - file attributes of the destination file }
type
ICopyHook = class(IUnknown) { sl }
function CopyCallback(Wnd: HWND; wFunc, wFlags: UINT; pszSrcFile: LPSTR;
dwSrcAttribs: DWORD; pszDestFile: LPSTR; dwDestAttribs: DWORD): UINT; virtual; stdcall; abstract;
end;
{ IFileViewerSite Interface }
type
IFileViewerSite = class(IUnknown)
function SetPinnedWindow(Wnd: HWND): HResult; virtual; stdcall; abstract;
function GetPinnedWindow(var Wnd: HWND): HResult; virtual; stdcall; abstract;
end;
{ IFileViewer Interface }
{ Implemented in a FileViewer component object. Used to tell a
FileViewer to PrintTo or to view, the latter happening though
ShowInitialize and Show. The filename is always given to the
viewer through IPersistFile. }
type
PFVShowInfo = ^TFVShowInfo;
TFVShowInfo = packed record
{ Stuff passed into viewer (in) }
cbSize: DWORD; { Size of structure for future expansion... }
hwndOwner: HWND; { who is the owner window. }
iShow: Integer; { The show command }
{ Passed in and updated (in/Out) }
dwFlags: DWORD; { flags }
rect: TRECT; { Where to create the window may have defaults }
punkRel: IUNKNOWN; { Relese this interface when window is visible }
{ Stuff that might be returned from viewer (out) }
strNewFile: array[0..MAX_PATH-1] of TOleChar; { New File to view. }
end;
const
{ Define File View Show Info Flags. }
FVSIF_RECT = $00000001; { The rect variable has valid data. }
FVSIF_PINNED = $00000002; { We should Initialize pinned }
FVSIF_NEWFAILED = $08000000; { The new file passed back failed
to be viewed. }
FVSIF_NEWFILE = $80000000; { A new file to view has been returned }
FVSIF_CANVIEWIT = $40000000; { The viewer can view it. }
type
IFileViewer = class(IUnknown)
function ShowInitialize(fsi: IFileViewerSite): HResult; virtual; stdcall; abstract;
function Show(var pvsi: TFVShowInfo): HResult; virtual; stdcall; abstract;
function PrintTo(pszDriver: LPSTR; fSuppressUI: BOOL): HResult; virtual; stdcall; abstract;
end;
const
STRRET_WSTR = $0000;
STRRET_OFFSET = $0001;
STRRET_CSTR = $0002;
type
{ record for returning strings from IShellFolder member functions }
PSTRRet = ^TStrRet;
TStrRet = packed record
uType: UINT; { One of the STRRET_* values }
case Integer of
0: (pOleStr: LPWSTR); { OLESTR that will be freed }
1: (uOffset: UINT); { Offset into SHITEMID (ANSI) }
2: (cStr: array[0..MAX_PATH-1] of Char); { Buffer to fill in }
end;
{ SHGetPathFromIDList }
{ This function assumes the size of the buffer (MAX_PATH). The pidl
should point to a file system object. }
function SHGetPathFromIDList(pidl: PItemIDList; pszPath: LPSTR): BOOL; stdcall;
{ SHGetSpecialFolderLocation }
{ Caller should call SHFree to free the returned pidl. }
const
{ registry entries for special paths are kept in : }
REGSTR_PATH_SPECIAL_FOLDERS = REGSTR_PATH_EXPLORER + '\Shell Folders';
CSIDL_DESKTOP = $0000;
CSIDL_PROGRAMS = $0002;
CSIDL_CONTROLS = $0003;
CSIDL_PRINTERS = $0004;
CSIDL_PERSONAL = $0005;
CSIDL_FAVORITES = $0006;
CSIDL_STARTUP = $0007;
CSIDL_RECENT = $0008;
CSIDL_SENDTO = $0009;
CSIDL_BITBUCKET = $000A;
CSIDL_STARTMENU = $000B;
CSIDL_DESKTOPDIRECTORY = $0010;
CSIDL_DRIVES = $0011;
CSIDL_NETWORK = $0012;
CSIDL_NETHOOD = $0013;
CSIDL_FONTS = $0014;
CSIDL_TEMPLATES = $0015;
function SHGetSpecialFolderLocation(hwndOwner: HWND; nFolder: Integer;
var ppidl: PItemIDList): HResult; stdcall;
{ SHBrowseForFolder API }
type
TFNBFFCallBack = function(Wnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): Integer stdcall;
PBrowseInfo = ^TBrowseInfo;
TBrowseInfo = packed record
hwndOwner: HWND;
pidlRoot: PItemIDList;
pszDisplayName: LPSTR; { Return display name of item selected. }
lpszTitle: LPCSTR; { text to go in the banner over the tree. }
ulFlags: UINT; { Flags that control the return stuff }
lpfn: TFNBFFCallBack;
lParam: LPARAM; { extra info that's passed back in callbacks }
iImage: Integer; { output var: where to return the Image index. }
end;
const
{ Browsing for directory. }
BIF_RETURNONLYFSDIRS = $0001 { For finding a folder to start document searching };
BIF_DONTGOBELOWDOMAIN = $0002 { For starting the Find Computer };
BIF_STATUSTEXT = $0004;
BIF_RETURNFSANCESTORS = $0008;
BIF_BROWSEFORCOMPUTER = $1000 { Browsing for Computers. };
BIF_BROWSEFORPRINTER = $2000 { Browsing for Printers };
{ message from browser }
BFFM_INITIALIZED = 1;
BFFM_SELCHANGED = 2;
{ messages to browser }
BFFM_SETSTATUSTEXT = (WM_USER + 100);
BFFM_ENABLEOK = (WM_USER + 101);
BFFM_SETSELECTION = (WM_USER + 102);
function SHBrowseForFolder(var lpbi: TBrowseInfo): PItemIDList; stdcall;
{ SHLoadInProc }
{ When this function is called, the shell calls CoCreateInstance
(or equivalent) with CLSCTX_INPROC_SERVER and the specified CLSID
from within the shell's process and release it immediately. }
function SHLoadInProc(rclsid: TCLSID): HRESULT; stdcall;
{ IEnumIDList interface }
{ IShellFolder.EnumObjects member returns an IEnumIDList object. }
type
IEnumIDList = class(IUnknown)
function Next(celt: ULONG; var rgelt: PItemIDList;
var pceltFetched: ULONG): HResult; virtual; stdcall; abstract;
function Skip(celt: ULONG): HResult; virtual; stdcall; abstract;
function Reset: HResult; virtual; stdcall; abstract;
function Clone(var ppenum: IEnumIDList): HResult; virtual; stdcall; abstract;
end;
{ IShellFolder interface }
{ [Member functions] }
{ IShellFolder.BindToObject(pidl, pbc, riid, ppvOut)
This function returns an instance of a sub-folder which is specified
by the IDList (pidl).
IShellFolder.BindToStorage(pidl, pbc, riid, ppvObj)
This function returns a storage instance of a sub-folder which is
specified by the IDList (pidl). The shell never calls this member
function in the first release of Win95.
IShellFolder.CompareIDs(lParam, pidl1, pidl2)
This function compares two IDLists and returns the result. The shell
explorer always passes 0 as lParam, which indicates 'sort by name'.
It should return 0 (as CODE of the scode), if two id indicates the
same object; negative value if pidl1 should be placed before pidl2;
positive value if pidl2 should be placed before pidl1.
IShellFolder.CreateViewObject(hwndOwner, riid, ppvOut)
This function creates a view object of the folder itself. The view
object is a difference instance from the shell folder object.
IShellFolder.GetAttributesOf(cidl, apidl, prgfInOut)
This function returns the attributes of specified objects in that
folder. 'cidl' and 'apidl' specifies objects. 'apidl' contains only
simple IDLists. The explorer initializes *prgfInOut with a set of
flags to be evaluated. The shell folder may optimize the operation
by not returning unspecified flags.
IShellFolder.GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut)
This function creates a UI object to be used for specified objects.
The shell explorer passes either IID_IDataObject (for transfer operation)
or IID_IContextMenu (for context menu operation) as riid.
IShellFolder.GetDisplayNameOf
This function returns the display name of the specified object.
If the ID contains the display name (in the locale character set),
it returns the offset to the name. Otherwise, it returns a pointer
to the display name string (UNICODE), which is allocated by the
task allocator, or fills in a buffer.
IShellFolder.SetNameOf
This function sets the display name of the specified object.
If it changes the ID as well, it returns the new ID which is
alocated by the task allocator. }
const
{ IShellFolder.GetDisplayNameOf/SetNameOf uFlags }
SHGDN_NORMAL = 0; { default (display purpose) }
SHGDN_INFOLDER = 1; { displayed under a folder (relative) }
SHGDN_FORPARSING = $8000; { for ParseDisplayName or path }
{ IShellFolder.EnumObjects }
SHCONTF_FOLDERS = 32; { for shell browser }
SHCONTF_NONFOLDERS = 64; { for default view }
SHCONTF_INCLUDEHIDDEN = 128; { for hidden/system objects }
{ IShellFolder.GetAttributesOf flags }
SFGAO_CANCOPY = DROPEFFECT_COPY; { Objects can be copied }
SFGAO_CANMOVE = DROPEFFECT_MOVE; { Objects can be moved }
SFGAO_CANLINK = DROPEFFECT_LINK; { Objects can be linked }
SFGAO_CANRENAME = $00000010; { Objects can be renamed }
SFGAO_CANDELETE = $00000020; { Objects can be deleted }
SFGAO_HASPROPSHEET = $00000040; { Objects have property sheets }
SFGAO_DROPTARGET = $00000100; { Objects are drop target }
SFGAO_CAPABILITYMASK = $00000177;
SFGAO_LINK = $00010000; { Shortcut (link) }
SFGAO_SHARE = $00020000; { shared }
SFGAO_READONLY = $00040000; { read-only }
SFGAO_GHOSTED = $00080000; { ghosted icon }
SFGAO_DISPLAYATTRMASK = $000F0000;
SFGAO_FILESYSANCESTOR = $10000000; { It contains file system folder }
SFGAO_FOLDER = $20000000; { It's a folder. }
SFGAO_FILESYSTEM = $40000000; { is a file system thing (file/folder/root) }
SFGAO_HASSUBFOLDER = $80000000; { Expandable in the map pane }
SFGAO_CONTENTSMASK = $80000000;
SFGAO_VALIDATE = $01000000; { invalidate cached information }
SFGAO_REMOVABLE = $02000000; { is this removeable media? }
type
IShellFolder = class(IUnknown)
function ParseDisplayName(hwndOwner: HWND;
pbcReserved: Pointer; lpszDisplayName: POLESTR; var pchEaten: ULONG;
var ppidl: PItemIDList; var dwAttributes: ULONG): HResult; virtual; stdcall; abstract;
function EnumObjects(hwndOwner: HWND; grfFlags: DWORD;
var EnumIDList: IEnumIDList): HResult; virtual; stdcall; abstract;
function BindToObject(pidl: PItemIDList; pbcReserved: Pointer;
const riid: TIID; var ppvOut: Pointer): HResult; virtual; stdcall; abstract;
function BindToStorage(pidl: PItemIDList; pbcReserved: Pointer;
riid: TIID; var ppvObj: Pointer): HResult; virtual; stdcall; abstract;
function CompareIDs(lParam: LPARAM;
pidl1, pidl2: PItemIDList): HResult; virtual; stdcall; abstract;
function CreateViewObject(hwndOwner: HWND; riid: TIID;
var ppvOut: Pointer): HResult; virtual; stdcall; abstract;
function GetAttributesOf(cidl: UINT; var apidl: PItemIDList;
var rgfInOut: UINT): HResult; virtual; stdcall; abstract;
function GetUIObjectOf(hwndOwner: HWND; cidl: UINT; var apidl: PItemIDList;
riid: TIID; var prgfInOut: UINT; var ppvOut: Pointer): HResult; virtual; stdcall; abstract;
function GetDisplayNameOf(pidl: PItemIDList; uFlags: DWORD;
var lpName: TStrRet): HResult; virtual; stdcall; abstract;
function SetNameOf(hwndOwner: HWND; pidl: PItemIDList; lpszName: POLEStr;
uFlags: DWORD; var ppidlOut: PItemIDList): HResult; virtual; stdcall; abstract;
end;
{ Helper function which returns a IShellFolder interface to the desktop
folder. This is equivalent to call CoCreateInstance with CLSID_ShellDesktop. }
function SHGetDesktopFolder(var ppshf: IShellFolder): HResult; stdcall;
const
{ Clipboard format which may be supported by IDataObject from system
defined shell folders (such as directories, network, ...). }
CFSTR_SHELLIDLIST = 'Shell IDList Array'; { CF_IDLIST }
CFSTR_SHELLIDLISTOFFSET = 'Shell Object Offsets'; { CF_OBJECTPOSITIONS }
CFSTR_NETRESOURCES = 'Net Resource'; { CF_NETRESOURCE }
CFSTR_FILEDESCRIPTOR = 'FileGroupDescriptor'; { CF_FILEGROUPDESCRIPTOR }
CFSTR_FILECONTENTS = 'FileContents'; { CF_FILECONTENTS }
CFSTR_FILENAME = 'FileName'; { CF_FILENAME }
CFSTR_PRINTERGROUP = 'PrinterFriendlyName'; { CF_PRINTERS }
CFSTR_FILENAMEMAP = 'FileNameMap'; { CF_FILENAMEMAP }
{ CF_OBJECTPOSITIONS }
DVASPECT_SHORTNAME = 2; { use for CF_HDROP to get short name version }
type
{ format of CF_NETRESOURCE }
PNResArray = ^TNResArray;
TNResArray = packed record { anr }
cItems: UINT;
nr: array[0..0] of TNetResource;
end;
{ format of CF_IDLIST }
PIDA = ^TIDA;
TIDA = packed record
cidl: UINT; { number of relative IDList }
aoffset: array[0..0] of UINT; { [0]: folder IDList, [1]-[cidl]: item IDList }
end;
const
{ FILEDESCRIPTOR.dwFlags field indicate which fields are to be used }
FD_CLSID = $0001;
FD_SIZEPOINT = $0002;
FD_ATTRIBUTES = $0004;
FD_CREATETIME = $0008;
FD_ACCESSTIME = $0010;
FD_WRITESTIME = $0020;
FD_FILESIZE = $0040;
FD_LINKUI = $8000; { 'link' UI is prefered }
type
PFileDescriptor = ^TFileDescriptor;
TFileDescriptor = packed record { fod }
dwFlags: DWORD;
clsid: TCLSID;
sizel: TSize;
pointl: TPoint;
dwFileAttributes: DWORD;
ftCreationTime: TFileTime;
ftLastAccessTime: TFileTime;
ftLastWriteTime: TFileTime;
nFileSizeHigh: DWORD;
nFileSizeLow: DWORD;
cFileName: array[0..MAX_PATH-1] of Char;
end;
{ format of CF_FILEGROUPDESCRIPTOR }
PFileGroupDescriptor = ^TFileGroupDescriptor;
TFileGroupDescriptor = packed record { fgd }
cItems: UINT;
fgd: array[0..0] of TFileDescriptor;
end;
{ format of CF_HDROP and CF_PRINTERS, in the HDROP case the data that follows
is a double null terinated list of file names, for printers they are printer
friendly names }
PDropFiles = ^TDropFiles;
TDropFiles = packed record
pFiles: DWORD; { offset of file list }
pt: TPoint; { drop point (client coords) }
fNC: BOOL; { is it on NonClient area }
{ and pt is in screen coords }
fWide: BOOL; { WIDE character switch }
end;
{ File System Notification APIs }
const
{ File System Notification flags }
SHCNE_RENAMEITEM = $00000001;
SHCNE_CREATE = $00000002;
SHCNE_DELETE = $00000004;
SHCNE_MKDIR = $00000008;
SHCNE_RMDIR = $00000010;
SHCNE_MEDIAINSERTED = $00000020;
SHCNE_MEDIAREMOVED = $00000040;
SHCNE_DRIVEREMOVED = $00000080;
SHCNE_DRIVEADD = $00000100;
SHCNE_NETSHARE = $00000200;
SHCNE_NETUNSHARE = $00000400;
SHCNE_ATTRIBUTES = $00000800;
SHCNE_UPDATEDIR = $00001000;
SHCNE_UPDATEITEM = $00002000;
SHCNE_SERVERDISCONNECT = $00004000;
SHCNE_UPDATEIMAGE = $00008000;
SHCNE_DRIVEADDGUI = $00010000;
SHCNE_RENAMEFOLDER = $00020000;
SHCNE_FREESPACE = $00040000;
SHCNE_ASSOCCHANGED = $08000000;
SHCNE_DISKEVENTS = $0002381F;
SHCNE_GLOBALEVENTS = $0C0581E0; { Events that dont match pidls first }
SHCNE_ALLEVENTS = $7FFFFFFF;
SHCNE_INTERRUPT = $80000000; { The presence of this flag indicates }
{ that the event was generated by an }
{ interrupt. It is stripped out before }
{ the clients of SHCNNotify_ see it. }
{ uFlags & SHCNF_TYPE is an ID which indicates what dwItem1 and dwItem2 mean }
SHCNF_IDLIST = $0000; { PItemIDList }
SHCNF_PATH = $0001; { path name }
SHCNF_PRINTER = $0002; { printer friendly name }
SHCNF_DWORD = $0003; { DWORD }
SHCNF_TYPE = $00FF;
SHCNF_FLUSH = $1000;
SHCNF_FLUSHNOWAIT = $2000;
{ APIs }
procedure SHChangeNotify(wEventId: Longint; uFlags: UINT;
dwItem1, dwItem2: Pointer); stdcall;
procedure SHAddToRecentDocs(uFlags: UINT; pv: Pointer); stdcall;
function SHGetInstanceExplorer(var ppUnk: IUnknown): HResult; stdcall;
{ SHAddToRecentDocs }
const
SHARD_PIDL = $00000001;
SHARD_PATH = $00000002;
implementation
const
shell32 = 'shell32.dll';
function SHGetMalloc; external shell32 name 'SHGetMalloc';
function SHGetPathFromIDList; external shell32 name 'SHGetPathFromIDList';
function SHGetSpecialFolderLocation; external shell32 name 'SHGetSpecialFolderLocation';
function SHBrowseForFolder; external shell32 name 'SHBrowseForFolder';
function SHLoadInProc; external shell32 name 'SHLoadInProc';
function SHGetDesktopFolder; external shell32 name 'SHGetDesktopFolder';
procedure SHChangeNotify; external shell32 name 'SHChangeNotify';
procedure SHAddToRecentDocs; external shell32 name 'SHAddToRecentDocs';
function SHGetInstanceExplorer; external shell32 name 'SHGetInstanceExplorer';
{ !!! function SHGetMalloc(var ppMalloc: IMalloc): HResult;
begin
Result := CoGetMalloc(MEMCTX_TASK, ppMalloc);
end; }
end.