home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / WIN / Programa / FILEEXP.ZIP / SHELLOBJ.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-07-24  |  45.7 KB  |  1,039 lines

  1. Unit ShellOBJ;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows,
  7.   Messages,
  8.   SysUtils,
  9.   OLE2,
  10.   COMMCTRL,
  11.   ShellAPI,
  12.   REGSTR;
  13.  
  14.  
  15. {=========================================================================== }
  16. { Object identifiers in the explorer's name space (ItemID and IDList) }
  17. {  All the items that the user can browse with the explorer (such as files, }
  18. { directories, servers, work-groups, etc.) has an identifier which is unique }
  19. { among items within the parent folder. Those identifiers are called item }
  20. { IDs (SHITEMID). Since all its parent folders have their own item IDs, }
  21. { any items can be uniquely identified by a list of item IDs, which is called }
  22. { an ID list (ITEMIDLIST). }
  23.              
  24. {  ID lists are almost always allocated by the task allocator (see some }
  25. { description below as well as OLE 2.0 SDK) and may be passed across }
  26. { some of shell interfaces (such as IShellFolder). Each item ID in an ID list }
  27. { is only meaningful to its parent folder (which has generated it), and all }
  28. { the clients must treat it as an opaque binary data except the first two }
  29. { bytes, which indicates the size of the item ID. }
  30.  
  31. {  When a shell extension -- which implements the IShellFolder interace -- }
  32. { generates an item ID, it may put any information in it, not only the data }
  33. { with that it needs to identifies the item, but also some additional }
  34. { information, which would help implementing some other functions efficiently. }
  35. { For example, the shell's IShellFolder implementation of file system items }
  36. { stores the primary (long) name of a file or a directory as the item }
  37. { identifier, but it also stores its alternative (short) name, size and date }
  38. { etc. }
  39.  
  40. {  When an ID list is passed to one of shell APIs (such as SHGetPathFromIDList), }
  41. { it is always an absolute path -- relative from the root of the name space, }
  42. { which is the desktop folder. When an ID list is passed to one of IShellFolder }
  43. { member function, it is always a relative path from the folder (unless it }
  44. { is explicitly specified). }
  45.  
  46. const
  47.  CLSID_ShellDesktop: TGUID = (
  48.        D1:$00021400; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  49.  CLSID_ShellLink: TGUID = (
  50.        D1:$00021401; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  51.  
  52.  IID_IContextMenu : TGUID = (
  53.        D1:$000214E4; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  54.  IID_IShellFolder : TGUID = (
  55.        D1:$000214E6; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  56.  IID_IShellExtInit : TGUID = (
  57.        D1:$000214E8; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  58.  IID_IShellPropSheetExt : TGUID = (
  59.        D1:$000214E9; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  60.  IID_IExtractIcon : TGUID = (
  61.        D1:$000214EB; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  62.  IID_IShellLink : TGUID = (
  63.        D1:$000214EE; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  64.  IID_IShellCopyHook : TGUID = (
  65.        D1:$000214EF; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  66.  IID_IFileViewer : TGUID = (
  67.        D1:$000214F0; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  68.  IID_IEnumIDList : TGUID = (
  69.        D1:$000214F2; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  70.  IID_IFileViewerSite : TGUID = (
  71.        D1:$000214F3; D2:$0000; D3:$0000; D4:($C0,$00,$00,$00,$00,$00,$00,$46));
  72.  
  73. { SHITEMID -- Item ID }
  74. type
  75.   PSHItemID = ^TSHItemID;
  76.   TSHItemID = record        { mkid }
  77.     cb:word;             { Size of the ID (including cb itself) }
  78.     abID:array[0..0] of BYTE;        { The item ID (variable length) }
  79.     end;
  80.  
  81. { ITEMIDLIST -- List if item IDs (combined with 0-terminator) }
  82.   PItemIDList = ^TItemIDList;
  83.   TItemIDList = record { idl }
  84.      mkid: TSHITEMID;
  85.      end;
  86.  
  87. {=========================================================================== }
  88. { Task allocator API }
  89. {  All the shell extensions MUST use the task allocator (see OLE 2.0 }
  90. { programming guild for its definition) when they allocate or free }
  91. { memory objects (mostly ITEMIDLIST) that are returned across any }
  92. { shell interfaces. There are two ways to access the task allocator }
  93. { from a shell extension depending on whether or not it is linked with }
  94. { OLE32.DLL or not (virtual; stdcall; abstractly for efficiency). }
  95.  
  96. { (1) A shell extension which calls any OLE API (i.e., linked with }
  97. {  OLE32.DLL) should call OLE's task allocator (by retrieving }
  98. {  the task allocator by calling CoGetMalloc API). }
  99.  
  100. { (2) A shell extension which does not call any OLE API (i.e., not linked }
  101. {  with OLE32.DLL) should call the shell task allocator API (defined }
  102. {  below), so that the shell can quickly loads it when OLE32.DLL is not }
  103. {  loaded by any application at that point. }
  104.  
  105. { Notes: }
  106. {  In next version of Windowso release, SHGetMalloc will be replaced by }
  107. { the following macro. }
  108.  
  109. { #define SHGetMalloc(ppmem)   CoGetMalloc(MEMCTX_TASK, ppmem) }
  110.  
  111. {=========================================================================== }
  112.  
  113.  
  114. function SHGetMalloc(var ppMalloc: IMALLOC):HResult;
  115.  
  116. {=========================================================================== }
  117. { IContextMenu interface }
  118. { [OverView] }
  119. {  The shell uses the IContextMenu interface in following three cases. }
  120.  
  121. { case-1: The shell is loading context menu extensions. }
  122. {   When the user clicks the right mouse button on an item within the shell's }
  123. {  name space (i.g., file, directory, server, work-group, etc.), it creates }
  124. {  the default context menu for its type, then loads context menu extensions }
  125. {  that are registered for that type (and its base type) so that they can }
  126. {  add extra menu items. Those context menu extensions are registered at }
  127. {  HKCR\beginProgIDend\shellex\ContextMenuHandlers. }
  128.  
  129. { case-2: The shell is retrieving a context menu of sub-folders in extended }
  130. {   name-space. }
  131. {   When the explorer's name space is extended by name space extensions, }
  132. {  the shell calls their IShellFolder::GetUIObjectOf to get the IContextMenu }
  133. {  objects when it creates context menus for folders under those extended }
  134. {  name spaces. }
  135.  
  136. { case-3: The shell is loading non-default drag and drop handler for directories. }
  137. {   When the user performed a non-default drag and drop onto one of file }
  138. {  system folders (i.e., directories), it loads shell extensions that are }
  139. {  registered at HKCR\beginProgIDend\DragDropHandlers. }
  140.  
  141. { [Member functions] }
  142.  
  143. { IContextMenu::QueryContextMenu }
  144. {  This member function may insert one or more menuitems to the specified }
  145. {  menu (hmenu) at the specified location (indexMenu which is never be -1). }
  146. {  The IDs of those menuitem must be in the specified range (idCmdFirst and }
  147. {  idCmdLast). It returns the maximum menuitem ID offset (ushort) in the }
  148. {  'code' field (low word) of the scode. }
  149.  
  150. {  The uFlags specify the context. It may have one or more of following }
  151. {  flags. }
  152.  
  153. {  CMF_DEFAULTONLY: This flag is passed if the user is invoking the default }
  154. {  action (typically by double-clicking, case 1 and 2 only). Context menu }
  155. {  extensions (case 1) should not add any menu items, and returns NOERROR. }
  156.  
  157. {  CMF_VERBSONLY: The explorer passes this flag if it is constructing }
  158. {  a context menu for a short-cut object (case 1 and case 2 only). If this }
  159. {  flag is passed, it should not add any menu-items that is not appropriate }
  160. {  from a short-cut. }
  161. {  A good example is the 'Delete' menuitem, which confuses the user }
  162. {  because it is not clear whether it deletes the link source item or the }
  163. {  link itself. }
  164.  
  165. {  CMF_EXPLORER: The explorer passes this flag if it has the left-side pane }
  166. {   (case 1 and 2 only). Context menu extensions should ignore this flag. }
  167.  
  168. {  High word (16-bit) are reserved for context specific communications }
  169. {  and the rest of flags (13-bit) are reserved by the system. }
  170.  
  171.  
  172. { IContextMenu::InvokeCommand }
  173.  
  174. {   This member is called when the user has selected one of menuitems that }
  175. {  are inserted by previous QueryContextMenu member. In this case, the }
  176. {  LOWORD(lpici->lpVerb) contains the menuitem ID offset (menuitem ID - }
  177. {  idCmdFirst). }
  178.  
  179. {   This member function may also be called programmatically. In such a case, }
  180. {  lpici->lpVerb specifies the canonical name of the command to be invoked, }
  181. {  which is typically retrieved by GetCommandString member previously. }
  182.  
  183. {  Parameters in lpci: }
  184. {    cbSize -- Specifies the size of this structure (sizeof(*lpci)) }
  185. {    hwnd   -- Specifies the owner window for any message/dialog box. }
  186. {    fMask  -- Specifies whether or not dwHotkey/hIcon paramter is valid. }
  187. {    lpVerb -- Specifies the command to be invoked. }
  188. {    lpParameters -- Parameters (optional) }
  189. {    lpDirectory  -- Working directory (optional) }
  190. {    nShow -- Specifies the flag to be passed to ShowWindow (SW_*). }
  191. {    dwHotKey -- Hot key to be assigned to the app after invoked (optional). }
  192. {    hIcon -- Specifies the icon (optional). }
  193.  
  194.  
  195. { IContextMenu::GetCommandString }
  196.  
  197. {   This member function is called by the explorer either to get the }
  198. {  canonical (language independent) command name (uFlags == GCS_VERB) or }
  199. {  the help text ((uFlags & GCS_HELPTEXT) != 0) for the specified command. }
  200. {  The retrieved canonical string may be passed to its InvokeCommand }
  201. {  member function to invoke a command programmatically. The explorer }
  202. {  displays the help texts in its status bar; therefore, the length of }
  203. {  the help text should be reasonably short (<40 characters). }
  204.  
  205. {  Parameters: }
  206. {   idCmd -- Specifies menuitem ID offset (from idCmdFirst) }
  207. {   uFlags -- Either GCS_VERB or GCS_HELPTEXT }
  208. {   pwReserved -- Reserved (must pass NULL when calling, must ignore when called) }
  209. {   pszName -- Specifies the string buffer. }
  210. {   cchMax -- Specifies the size of the string buffer. }
  211.  
  212. {=========================================================================== }
  213.  
  214. const
  215.    { QueryContextMenu uFlags }
  216.    CMF_NORMAL             = $00000000;
  217.    CMF_DEFAULTONLY        = $00000001;
  218.    CMF_VERBSONLY          = $00000002;
  219.    CMF_EXPLORE            = $00000004;
  220.    CMF_RESERVED           = $ffff0000      { View specific };
  221.  
  222.    { GetCommandString uFlags }
  223.    GCS_VERB         =$00000000     { canonical verb };
  224.    GCS_HELPTEXT     =$00000001     { help text (for status bar) };
  225.    GCS_VALIDATE     =$00000002     { validate command exists };
  226.  
  227.    CMDSTR_NEWFOLDER    = 'NewFolder';
  228.    CMDSTR_VIEWLIST     = 'ViewList';
  229.    CMDSTR_VIEWDETAILS  = 'ViewDetails';
  230.  
  231.    CMIC_MASK_HOTKEY       = SEE_MASK_HOTKEY;
  232.    CMIC_MASK_ICON         = SEE_MASK_ICON;
  233.    CMIC_MASK_FLAG_NO_UI   = SEE_MASK_FLAG_NO_UI;
  234.    CMIC_MASK_MODAL         =$80000000        (* ; Internal *);
  235.  
  236.   (*!! CMIC_VALID_SEE_FLAGS   = SEE_VALID_CMIC_FLAGS;   (* ; Internal *)
  237.  
  238.  
  239. type
  240.   PCMInvokeCommandInfo = ^TCMInvokeCommandInfo;
  241.   TCMInvokeCommandInfo = record
  242.      cbSize:DWORD;        { must be sizeof(CMINVOKECOMMANDINFO) }
  243.      fMask:DWORD;         { any combination of CMIC_MASK_* }
  244.      hwnd:HWND;           { might be NULL (indicating no owner window) }
  245.      lpVerb:LPCSTR;       { either a string of MAKEINTRESOURCE(idOffset) }
  246.      lpParameters:LPCSTR; { might be NULL (indicating no parameter) }
  247.      lpDirectory:LPCSTR;  { might be NULL (indicating no specific directory) }
  248.      nShow:integer;           { one of SW_ values for ShowWindow() API }
  249.  
  250.      dwHotKey:DWORD;
  251.      hIcon:THANDLE;
  252.      end;
  253.  
  254.   IContextMenu = class(IUnknown)
  255.     function QueryContextMenu(Menu:HMENU; indexMenu:UINT;
  256.                               idCmdFirst:UINT;idCmdLast:UINT;
  257.                               uFlags:UINT):HResult; virtual; stdcall; abstract;
  258.  
  259.     function InvokeCommand(lpici: PCMINVOKECOMMANDINFO): HResult; virtual; stdcall; abstract;
  260.  
  261.     function GetCommandString(idCmd:UINT; uType:UINT; var pwReserved:UINT;
  262.                               pszName:LPSTR; cchMax:UINT):HResult; virtual; stdcall; abstract;
  263.     end;
  264.  
  265. {=========================================================================== }
  266.  
  267. { Interface: IShellExtInit }
  268.  
  269. {  The IShellExtInit interface is used by the explorer to initialize shell }
  270. { extension objects. The explorer (1) calls CoCreateInstance (or equivalent) }
  271. { with the registered CLSID and IID_IShellExtInit, (2) calls its Initialize }
  272. { member, then (3) calls its QueryInterface to a particular interface (such }
  273. { as IContextMenu or IPropSheetExt and (4) performs the rest of operation. }
  274.  
  275.  
  276. { [Member functions] }
  277.  
  278. { IShellExtInit::Initialize }
  279.  
  280. {  This member function is called when the explorer is initializing either }
  281. { context menu extension, property sheet extension or non-default drag-drop }
  282. { extension. }
  283.  
  284. {  Parameters: (context menu or property sheet extension) }
  285. {   pidlFolder -- Specifies the parent folder }
  286. {   lpdobj -- Spefifies the set of items selected in that folder. }
  287. {   hkeyProgID -- Specifies the type of the focused item in the selection. }
  288.  
  289. {  Parameters: (non-default drag-and-drop extension) }
  290. {   pidlFolder -- Specifies the target (destination) folder }
  291. {   lpdobj -- Specifies the items that are dropped (see the description }
  292. {    about shell's clipboard below for clipboard formats). }
  293. {   hkeyProgID -- Specifies the folder type. }
  294.  
  295. {=========================================================================== }
  296.  
  297. type
  298.     IShellExtInit = class(IUnknown)
  299.       function Initialize(pidlFolder:PItemIDList;
  300.                           lpdobj: IDataObject;
  301.                           hKeyProgID:HKEY):HResult; virtual; stdcall; abstract;
  302.     end;
  303.  
  304. {=========================================================================== }
  305.  
  306. { Interface: IShellPropSheetExt }
  307.  
  308. {  The explorer uses the IShellPropSheetExt to allow property sheet }
  309. { extensions or control panel extensions to add additional property }
  310. { sheet pages. }
  311.  
  312.  
  313. { [Member functions] }
  314.  
  315. { IShellPropSheetExt::AddPages }
  316.  
  317. {  The explorer calls this member function when it finds a registered }
  318. { property sheet extension for a particular type of object. For each }
  319. { additional page, the extension creates a page object by calling }
  320. { CreatePropertySheetPage API and calls lpfnAddPage. }
  321.  
  322. {  Parameters: }
  323. {   lpfnAddPage -- Specifies the callback function. }
  324. {   lParam -- Specifies the opaque handle to be passed to the callback function. }
  325.  
  326.  
  327. { IShellPropSheetExt::ReplacePage }
  328.  
  329. {  The explorer never calls this member of property sheet extensions. The }
  330. { explorer calls this member of control panel extensions, so that they }
  331. { can replace some of default control panel pages (such as a page of }
  332. { mouse control panel). }
  333.  
  334. {  Parameters: }
  335. {   uPageID -- Specifies the page to be replaced. }
  336. {   lpfnReplace Specifies the callback function. }
  337. {   lParam -- Specifies the opaque handle to be passed to the callback function. }
  338.  
  339. {=========================================================================== }
  340.  
  341. type
  342.  IShellPropSheetExt = class(IUnknown)
  343.     function AddPages(lpfnAddPage: TFNADDPROPSHEETPAGE; lParam:LPARAM):HResult; virtual; stdcall; abstract;
  344.     function ReplacePage(uPageID:UINT;
  345.                          lpfnReplaceWith:TFNADDPROPSHEETPAGE;
  346.                           lParam:LPARAM):HResult; virtual; stdcall; abstract;
  347.     end;
  348.  
  349. {=========================================================================== }
  350.  
  351. { IExtractIcon interface }
  352.  
  353. {  This interface is used in two different places in the shell. }
  354.  
  355. { Case-1: Icons of sub-folders for the scope-pane of the explorer. }
  356.  
  357. {  It is used by the explorer to get the 'icon location' of }
  358. { sub-folders from each shell folders. When the user expands a folder }
  359. { in the scope pane of the explorer, the explorer does following: }
  360. {  (1) binds to the folder (gets IShellFolder), }
  361. {  (2) enumerates its sub-folders by calling its EnumObjects member, }
  362. {  (3) calls its GetUIObjectOf member to get IExtractIcon interface }
  363. {     for each sub-folders. }
  364. {  In this case, the explorer uses only IExtractIcon::GetIconLocation }
  365. { member to get the location of the appropriate icon. An icon location }
  366. { always consists of a file name (typically DLL or EXE) and either an icon }
  367. { resource or an icon index. }
  368.  
  369.  
  370. { Case-2: Extracting an icon image from a file }
  371.  
  372. {  It is used by the shell when it extracts an icon image }
  373. { from a file. When the shell is extracting an icon from a file, }
  374. { it does following: }
  375. {  (1) creates the icon extraction handler object (by getting its CLSID }
  376. {     under the beginProgIDend\shell\ExtractIconHanler key and calling }
  377. {     CoCreateInstance requesting for IExtractIcon interface). }
  378. {  (2) Calls IExtractIcon::GetIconLocation. }
  379. {  (3) Then, calls IExtractIcon::Extract with the location/index pair. }
  380. {  (4) If (3) returns NOERROR, it uses the returned icon. }
  381. {  (5) Otherwise, it recursively calls this logic with new location }
  382. {     assuming that the location string contains a fully qualified path name. }
  383.  
  384. {  From extension programmer's point of view, there are only two cases }
  385. { where they provide implementations of IExtractIcon: }
  386. {  Case-1) providing explorer extensions (i.e., IShellFolder). }
  387. {  Case-2) providing per-instance icons for some types of files. }
  388.  
  389. { Because Case-1 is described above, we'll explain only Case-2 here. }
  390.  
  391. { When the shell is about display an icon for a file, it does following: }
  392. {  (1) Finds its ProgID and ClassID. }
  393. {  (2) If the file has a ClassID, it gets the icon location string from the }
  394. {    'DefaultIcon' key under it. The string indicates either per-class }
  395. {    icon (e.g., 'FOOBAR.DLL,2') or per-instance icon (e.g., '%1,1'). }
  396. {  (3) If a per-instance icon is specified, the shell creates an icon }
  397. {    extraction handler object for it, and extracts the icon from it }
  398. {    (which is described above). }
  399.  
  400. {  It is important to note that the shell calls IExtractIcon::GetIconLocation }
  401. { first, then calls IExtractIcon::Extract. Most application programs }
  402. { that support per-instance icons will probably store an icon location }
  403. { (DLL/EXE name and index/id) rather than an icon image in each file. }
  404. { In those cases, a programmer needs to implement only the GetIconLocation }
  405. { member and it Extract member simply returns S_FALSE. They need to }
  406. { implement Extract member only if they decided to store the icon images }
  407. { within files themselved or some other database (which is very rare). }
  408.  
  409.  
  410.  
  411. { [Member functions] }
  412.  
  413.  
  414. { IExtractIcon::GetIconLocation }
  415.  
  416. {  This function returns an icon location. }
  417.  
  418. {  Parameters: }
  419. {   uFlags     [in]  -- Specifies if it is opened or not (GIL_OPENICON or 0) }
  420. {   szIconFile [out] -- Specifies the string buffer buffer for a location name. }
  421. {   cchMax     [in]  -- Specifies the size of szIconFile (almost always MAX_PATH) }
  422. {   piIndex    [out] -- Sepcifies the address of UINT for the index. }
  423. {   pwFlags    [out] -- Returns GIL_* flags }
  424. {  Returns: }
  425. {   NOERROR, if it returns a valid location; S_FALSE, if the shell use a }
  426. {   default icon. }
  427.  
  428. {  Notes: The location may or may not be a path to a file. The caller can }
  429. {   not assume anything unless the subsequent Extract member call returns }
  430. {   S_FALSE. }
  431.  
  432. {   if the returned location is not a path to a file, GIL_NOTFILENAME should }
  433. {   be set in the returned flags. }
  434.  
  435. { IExtractIcon::Extract }
  436.  
  437. {  This function extracts an icon image from a specified file. }
  438.  
  439. {  Parameters: }
  440. {   pszFile [in] -- Specifies the icon location (typically a path to a file). }
  441. {   nIconIndex [in] -- Specifies the icon index. }
  442. {   phiconLarge [out] -- Specifies the HICON variable for large icon. }
  443. {   phiconSmall [out] -- Specifies the HICON variable for small icon. }
  444. {   nIconSize [in] -- Specifies the size icon required (size of large icon) }
  445. {                     LOWORD is the requested large icon size }
  446. {                     HIWORD is the requested small icon size }
  447. {  Returns: }
  448. {   NOERROR, if it extracted the from the file. }
  449. {   S_FALSE, if the caller should extract from the file specified in the }
  450. {           location. }
  451.  
  452. {=========================================================================== }
  453.  
  454. { GetIconLocation() input flags }
  455. const
  456.   GIL_OPENICON     =$0001      { allows containers to specify an 'open' look };
  457.   GIL_FORSHELL     =$0002      { icon is to be displayed in a ShellFolder };
  458.  
  459.   { GetIconLocation() return flags }
  460.  
  461.   GIL_SIMULATEDOC  =$0001      { simulate this document icon for this };
  462.   GIL_PERINSTANCE  =$0002      { icons from this class are per instance (each file has its own) };
  463.   GIL_PERCLASS     =$0004      { icons from this class per class (shared for all files of this type) };
  464.   GIL_NOTFILENAME  =$0008      { location is not a filename, must call ::Extract };
  465.   GIL_DONTCACHE    =$0010      { this icon should not be cached };
  466.  
  467. type
  468.   IExtractIcon = class(IUnknown)      { exic }
  469.     function GetIconLocation(uFlags:UINT; szIconFile:LPSTR; cchMax:UINT;
  470.                            var piIndex:integer;
  471.                            var pwFlags:UINT):HResult; virtual; stdcall; abstract;
  472.  
  473.     function Extract(pszFile:LPCSTR; nIconIndex:UINT; var phiconLarge:HICON;
  474.                      var phiconSmall:HICON;
  475.                      nIconSize:UINT):HResult; virtual; stdcall; abstract;
  476.     end;
  477.  
  478.  
  479. {=========================================================================== }
  480.  
  481. { IShellLink Interface }
  482.  
  483. {=========================================================================== }
  484. const
  485.     { IShellLink::Resolve fFlags }
  486.     SLR_NO_UI           = $0001;
  487.     SLR_ANY_MATCH       = $0002;
  488.     SLR_UPDATE          = $0004;
  489.  
  490.     { IShellLink::GetPath fFlags }
  491.     SLGP_SHORTPATH      = $0001;
  492.     SLGP_UNCPRIORITY    = $0002;
  493.  
  494. type
  495.   IShellLink = class(IUnknown) { sl }
  496.     function GetPath(pszFile:LPSTR; cchMaxPath:integer;
  497.                      var pfd:TWin32FindData;
  498.                      fFlags:DWORD):HResult; virtual; stdcall; abstract;
  499.  
  500.     function GetIDList(var ppidl:PITEMIDLIST):HResult; virtual; stdcall; abstract;
  501.     function SetIDList(pidl:PITEMIDLIST):HResult; virtual; stdcall; abstract;
  502.  
  503.     function GetDescription(pszName:LPSTR; cchMaxName:integer):HResult; virtual; stdcall; abstract;
  504.     function SetDescription(pszName:LPSTR):HResult; virtual; stdcall; abstract;
  505.  
  506.     function GetWorkingDirectory(pszDir:LPSTR; cchMaxPath:integer):HResult; virtual; stdcall; abstract;
  507.     function SetWorkingDirectory(pszDir:LPSTR):HResult; virtual; stdcall; abstract;
  508.  
  509.     function GetArguments(pszArgs:LPSTR; cchMaxPath:integer):HResult; virtual; stdcall; abstract;
  510.     function SetArguments(pszArgs:LPSTR):HResult; virtual; stdcall; abstract;
  511.  
  512.     function GetHotkey(var pwHotkey:word):HResult; virtual; stdcall; abstract;
  513.     function SetHotkey(wHotkey:word):HResult; virtual; stdcall; abstract;
  514.  
  515.     function GetShowCmd(var piShowCmd:integer):HResult; virtual; stdcall; abstract;
  516.     function SetShowCmd(iShowCmd:integer):HResult; virtual; stdcall; abstract;
  517.  
  518.     function GetIconLocation(pszIconPath:LPSTR; cchIconPath:integer;
  519.                              var piIcon:integer):HResult; virtual; stdcall; abstract;
  520.     function SetIconLocation(pszIconPath:LPSTR; iIcon:integer):HResult; virtual; stdcall; abstract;
  521.  
  522.     function SetRelativePath(pszPathRel:LPSTR; dwReserved:DWORD):HResult; virtual; stdcall; abstract;
  523.  
  524.     function Resolve(Wnd:HWND; fFlags: DWORD):HResult; virtual; stdcall; abstract;
  525.  
  526.     function SetPath(pszFile:LPSTR):HResult; virtual; stdcall; abstract;
  527. end;
  528.  
  529. {=========================================================================== }
  530. { ICopyHook Interface }
  531. {  The copy hook is called whenever file system directories are }
  532. {  copy/moved/deleted/renamed via the shell.  It is also called by the shell }
  533. {  on changes of status of printers. }
  534. {  Clients register their id under STRREG_SHEX_COPYHOOK for file system hooks }
  535. {  and STRREG_SHEx_PRNCOPYHOOK for printer hooks. }
  536. {  the CopyCallback is called prior to the action, so the hook has the chance }
  537. {  to allow, deny or cancel the operation by returning the falues: }
  538. {     IDYES  -  means allow the operation }
  539. {     IDNO   -  means disallow the operation on this file, but continue with }
  540. {              any other operations (eg. batch copy) }
  541. {     IDCANCEL - means disallow the current operation and cancel any pending }
  542. {              operations }
  543. {   arguments to the CopyCallback }
  544. {      hwnd - window to use for any UI }
  545. {      wFunc - what operation is being done }
  546. {      wFlags - and flags (FOF_*) set in the initial call to the file operation }
  547. {      pszSrcFile - name of the source file }
  548. {      dwSrcAttribs - file attributes of the source file }
  549. {      pszDestFile - name of the destiation file (for move and renames) }
  550. {      dwDestAttribs - file attributes of the destination file }
  551. {=========================================================================== }
  552.  
  553. type
  554.   ICopyHook = class(IUnknown) { sl }
  555.     function CopyCallback(Wnd:HWND;wFunc:UINT; wFlags:UINT;
  556.                           pszSrcFile:LPSTR; dwSrcAttribs:DWORD;
  557.                           pszDestFile:LPSTR; dwDestAttribs:DWORD):UINT; virtual; stdcall; abstract;
  558.     end;
  559.  
  560. {=========================================================================== }
  561.  
  562. { IFileViewerSite Interface }
  563.  
  564. {=========================================================================== }
  565.  
  566. type
  567.   IFileViewerSite = class(IUnknown)
  568.     function SetPinnedWindow(Wnd:HWND):HResult; virtual; stdcall; abstract;
  569.     function GetPinnedWindow(var Wnd:HWND):HResult; virtual; stdcall; abstract;
  570.     end;
  571.  
  572. {=========================================================================== }
  573. { IFileViewer Interface }
  574. { Implemented in a FileViewer component object.  Used to tell a }
  575. { FileViewer to PrintTo or to view, the latter happening though }
  576. { ShowInitialize and Show.  The filename is always given to the }
  577. { viewer through IPersistFile. }
  578. {=========================================================================== }
  579.  
  580. type
  581.   PFVShowInfo = ^TFVShowInfo;
  582.   TFVShowInfo = record
  583.     { Stuff passed into viewer (in) }
  584.      cbSize:DWORD;           { Size of structure for future expansion... }
  585.      hwndOwner:HWND;         { who is the owner window. }
  586.      iShow:integer;              { The show command }
  587.     { Passed in and updated  (in/Out) }
  588.      dwFlags:DWORD;          { flags }
  589.      rect:TRECT;              { Where to create the window may have defaults }
  590.      punkRel:IUNKNOWN;       { Relese this interface when window is visible }
  591.     { Stuff that might be returned from viewer (out) }
  592.      strNewFile:array[0..MAX_PATH-1] of TOLECHAR;   { New File to view. }
  593.     end;
  594.  
  595.    { Define File View Show Info Flags. }
  596. const
  597.    FVSIF_RECT      =$00000001      { The rect variable has valid data. };
  598.    FVSIF_PINNED    =$00000002      { We should Initialize pinned };
  599.  
  600.    FVSIF_NEWFAILED =$08000000      { The new file passed back failed };
  601.                                            { to be viewed. }
  602.  
  603.    FVSIF_NEWFILE   =$80000000      { A new file to view has been returned };
  604.    FVSIF_CANVIEWIT =$40000000      { The viewer can view it. };
  605.  
  606. type
  607.   IFileViewer = class(IUnknown)
  608.     function ShowInitialize(fsi:IFILEVIEWERSITE):HResult; virtual; stdcall; abstract;
  609.     function Show(pvsi:PFVSHOWINFO):HResult; virtual; stdcall; abstract;
  610.     function PrintTo(pszDriver:LPSTR; fSuppressUI:BOOL):HResult; virtual; stdcall; abstract;
  611.     end;
  612.  
  613. {------------------------------------------------------------------------- }
  614. { struct STRRET }
  615. { structure for returning strings from IShellFolder member functions }
  616. {------------------------------------------------------------------------- }
  617. const
  618.   STRRET_WSTR     =$0000;
  619.   STRRET_OFFSET   =$0001;
  620.   STRRET_CSTR     =$0002;
  621.  
  622. type
  623.   PSTRRet = ^TStrRet;
  624.   TSTRRET = record
  625.      uType:UINT; { One of the STRRET_* values }
  626.      case integer of
  627.        0:(pOleStr:LPWSTR);        { OLESTR that will be freed }
  628.        1:(uOffset:UINT);        { Offset into SHITEMID (ANSI) }
  629.        2:(cStr: array[0..MAX_PATH-1] of char); { Buffer to fill in }
  630.     end;
  631.  
  632. {------------------------------------------------------------------------- }
  633. { SHGetPathFromIDList }
  634. {  This function assumes the size of the buffer (MAX_PATH). The pidl }
  635. { should point to a file system object. }
  636. {------------------------------------------------------------------------- }
  637.  
  638. type     TSHGetPathFromIDList = function(pidl:PITEMIDLIST; pszPath:LPSTR):BOOL; stdcall;
  639. var      SHGetPathFromIDList  : TSHGetPathFromIDList;
  640.  
  641. {------------------------------------------------------------------------- }
  642. { SHGetSpecialFolderLocation }
  643. {  Caller should call SHFree to free the returned pidl. }
  644. {------------------------------------------------------------------------- }
  645.  
  646. { registry entries for special paths are kept in : }
  647. const
  648.   REGSTR_PATH_SPECIAL_FOLDERS   = REGSTR_PATH_EXPLORER+'\Shell Folders';
  649.   CSIDL_DESKTOP            =$0000;
  650.   CSIDL_PROGRAMS           =$0002;
  651.   CSIDL_CONTROLS           =$0003;
  652.   CSIDL_PRINTERS           =$0004;
  653.   CSIDL_PERSONAL           =$0005;
  654.   CSIDL_FAVORITES          =$0006;
  655.   CSIDL_STARTUP            =$0007;
  656.   CSIDL_RECENT             =$0008;
  657.   CSIDL_SENDTO             =$0009;
  658.   CSIDL_BITBUCKET          =$000a;
  659.   CSIDL_STARTMENU          =$000b;
  660.   CSIDL_DESKTOPDIRECTORY   =$0010;
  661.   CSIDL_DRIVES             =$0011;
  662.   CSIDL_NETWORK            =$0012;
  663.   CSIDL_NETHOOD            =$0013;
  664.   CSIDL_FONTS              =$0014;
  665.   CSIDL_TEMPLATES          =$0015;
  666.  
  667. type TSHGetSpecialFolderLocation = function (hwndOwner:HWND; nFolder:integer; var ppidl:PITEMIDLIST):HResult; stdcall;
  668. var  SHGetSpecialFolderLocation  : TSHGetSpecialFolderLocation;
  669.  
  670. {------------------------------------------------------------------------- }
  671. { SHBrowseForFolder API }
  672. {------------------------------------------------------------------------- }
  673.  
  674. type
  675.   BFFCALLBACK = function(Wnd:HWND;uMsg:UINT;lParam,lpData:LPARAM):integer stdcall;
  676.   PBrowseInfo = ^TBrowseInfo;
  677.   TBrowseInfo = record
  678.      hwndOwner:HWND;
  679.      pidlRoot:PITEMIDLIST;
  680.      pszDisplayName:LPSTR;  { Return display name of item selected. }
  681.      lpszTitle:LPCSTR;      { text to go in the banner over the tree. }
  682.      ulFlags:UINT;          { Flags that control the return stuff }
  683.      lpfn:BFFCALLBACK;
  684.      lParam:LPARAM;         { extra info that's passed back in callbacks }
  685.      iImage:integer;        { output var: where to return the Image index. }
  686.      end;
  687.  
  688. const
  689. { Browsing for directory. }
  690.    BIF_RETURNONLYFSDIRS   =$0001  { For finding a folder to start document searching };
  691.    BIF_DONTGOBELOWDOMAIN  =$0002  { For starting the Find Computer };
  692.    BIF_STATUSTEXT         =$0004;
  693.    BIF_RETURNFSANCESTORS  =$0008;
  694.  
  695.    BIF_BROWSEFORCOMPUTER  =$1000  { Browsing for Computers. };
  696.    BIF_BROWSEFORPRINTER   =$2000  { Browsing for Printers };
  697.  
  698.    { message from browser }
  699.    BFFM_INITIALIZED       = 1;
  700.    BFFM_SELCHANGED        = 2;
  701.  
  702.    { messages to browser }
  703.    BFFM_SETSTATUSTEXT      =(WM_USER + 100);
  704.    BFFM_ENABLEOK           =(WM_USER + 101);
  705.    BFFM_SETSELECTION       =(WM_USER + 102);
  706.  
  707.  
  708. type TSHBrowseForFolder = function (lpbi:PBROWSEINFO):PItemIDList; stdcall;
  709. var  SHBrowseForFolder  : TSHBrowseForFolder;
  710. {------------------------------------------------------------------------- }
  711. { SHLoadInProc }
  712. {   When this function is called, the shell calls CoCreateInstance }
  713. {  (or equivalent) with CLSCTX_INPROC_SERVER and the specified CLSID }
  714. {  from within the shell's process and release it immediately. }
  715. {------------------------------------------------------------------------- }
  716.  
  717. type TSHLoadInProc = function (rclsid:TCLSID):HRESULT; stdcall;
  718. var  SHLoadInProc  : TSHLoadInProc;
  719.  
  720. {------------------------------------------------------------------------- }
  721. { IEnumIDList interface }
  722. {  IShellFolder::EnumObjects member returns an IEnumIDList object. }
  723. {------------------------------------------------------------------------- }
  724.  
  725. type
  726.   IEnumIDList = class(IUnknown)
  727.     function Next( celt:ULONG;
  728.                    var rgelt: PITEMIDLIST;
  729.                    var pceltFetched:ULONG):HResult; virtual; stdcall; abstract;
  730.     function Skip(celt:ULONG):HResult; virtual; stdcall; abstract;
  731.     function Reset:HResult; virtual; stdcall; abstract;
  732.     function Clone(var ppenum:IEnumIDList):HResult; virtual; stdcall; abstract;
  733.     end;
  734.  
  735. {------------------------------------------------------------------------- }
  736. { IShellFolder interface }
  737. { [Member functions] }
  738. { IShellFolder::BindToObject(pidl, pbc, riid, ppvOut) }
  739. {   This function returns an instance of a sub-folder which is specified }
  740. {   by the IDList (pidl). }
  741. { IShellFolder::BindToStorage(pidl, pbc, riid, ppvObj) }
  742. {   This function returns a storage instance of a sub-folder which is }
  743. {   specified by the IDList (pidl). The shell never calls this member }
  744. {   function in the first release of Win95. }
  745. { IShellFolder::CompareIDs(lParam, pidl1, pidl2) }
  746. {   This function compares two IDLists and returns the result. The shell }
  747. {   explorer always passes 0 as lParam, which indicates 'sort by name'. }
  748. {   It should return 0 (as CODE of the scode), if two id indicates the }
  749. {   same object; negative value if pidl1 should be placed before pidl2; }
  750. {   positive value if pidl2 should be placed before pidl1. }
  751. { IShellFolder::CreateViewObject(hwndOwner, riid, ppvOut) }
  752. {   This function creates a view object of the folder itself. The view }
  753. {   object is a difference instance from the shell folder object. }
  754. { IShellFolder::GetAttributesOf(cidl, apidl, prgfInOut) }
  755. {   This function returns the attributes of specified objects in that }
  756. {   folder. 'cidl' and 'apidl' specifies objects. 'apidl' contains only }
  757. {   simple IDLists. The explorer initializes *prgfInOut with a set of }
  758. {   flags to be evaluated. The shell folder may optimize the operation }
  759. {   by not returning unspecified flags. }
  760. { IShellFolder::GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, ppvOut) }
  761. {   This function creates a UI object to be used for specified objects. }
  762. {   The shell explorer passes either IID_IDataObject (for transfer operation) }
  763. {   or IID_IContextMenu (for context menu operation) as riid. }
  764. { IShellFolder::GetDisplayNameOf }
  765. {   This function returns the display name of the specified object. }
  766. {   If the ID contains the display name (in the locale character set), }
  767. {   it returns the offset to the name. Otherwise, it returns a pointer }
  768. {   to the display name string (UNICODE), which is allocated by the }
  769. {   task allocator, or fills in a buffer. }
  770. { IShellFolder::SetNameOf }
  771. {   This function sets the display name of the specified object. }
  772. {   If it changes the ID as well, it returns the new ID which is }
  773. {   alocated by the task allocator. }
  774. {------------------------------------------------------------------------- }
  775.  
  776. const
  777.   { IShellFolder::GetDisplayNameOf/SetNameOf uFlags }
  778.   SHGDN_NORMAL     = 0;        { default (display purpose) }
  779.   SHGDN_INFOLDER   = 1;        { displayed under a folder (relative) }
  780.   SHGDN_FORPARSING = $8000;    { for ParseDisplayName or path }
  781.  
  782.   { IShellFolder::EnumObjects }
  783.   SHCONTF_FOLDERS         = 32;       { for shell browser }
  784.   SHCONTF_NONFOLDERS      = 64;       { for default view }
  785.   SHCONTF_INCLUDEHIDDEN   = 128;      { for hidden/system objects }
  786.  
  787.   { IShellFolder::GetAttributesOf flags }
  788.   SFGAO_CANCOPY          = DROPEFFECT_COPY { Objects can be copied };
  789.   SFGAO_CANMOVE          = DROPEFFECT_MOVE { Objects can be moved };
  790.   SFGAO_CANLINK          = DROPEFFECT_LINK { Objects can be linked };
  791.   SFGAO_CANRENAME         =$00000010     { Objects can be renamed };
  792.   SFGAO_CANDELETE         =$00000020     { Objects can be deleted };
  793.   SFGAO_HASPROPSHEET      =$00000040     { Objects have property sheets };
  794.   SFGAO_DROPTARGET        =$00000100     { Objects are drop target };
  795.   SFGAO_CAPABILITYMASK    =$00000177;
  796.   SFGAO_LINK              =$00010000     { Shortcut (link) };
  797.   SFGAO_SHARE             =$00020000     { shared };
  798.   SFGAO_READONLY          =$00040000     { read-only };
  799.   SFGAO_GHOSTED           =$00080000     { ghosted icon };
  800.   SFGAO_DISPLAYATTRMASK   =$000F0000;
  801.   SFGAO_FILESYSANCESTOR   =$10000000     { It contains file system folder };
  802.   SFGAO_FOLDER            =$20000000     { It's a folder. };
  803.   SFGAO_FILESYSTEM        =$40000000     { is a file system thing (file/folder/root) };
  804.   SFGAO_HASSUBFOLDER      =$80000000     { Expandable in the map pane };
  805.   SFGAO_CONTENTSMASK      =$80000000;
  806.   SFGAO_VALIDATE          =$01000000     { invalidate cached information };
  807.   SFGAO_REMOVABLE         =$02000000     { is this removeable media? };
  808.  
  809. type
  810.    IShellFolder = class(IUnknown)
  811.     function ParseDisplayName(hwndOwner:HWND;
  812.              pbcReserved:{LPBC}pointer; lpszDisplayName:POLESTR;
  813.              var pchEaten:ULONG; var ppidl:PITEMIDLIST;
  814.              var dwAttributes:ULONG):HResult; virtual; stdcall; abstract;
  815.     function EnumObjects(hwndOwner:HWND; grfFlags:DWORD;
  816.                          var EnumIDList: IENUMIDLIST):HResult; virtual; stdcall; abstract;
  817.     function BindToObject(pidl:PITEMIDLIST; pbcReserved:{LPBC}pointer;
  818.                           riid:TIID; var ppvOut:pointer):HResult; virtual; stdcall; abstract;
  819.     function BindToStorage(pidl:PITEMIDLIST; pbcReserved:{LPBC}pointer;
  820.                            riid:TIID; var ppvObj:pointer):HResult; virtual; stdcall; abstract;
  821.     function CompareIDs(lParam:LPARAM;
  822.                         pidl1,pidl2: PITEMIDLIST):HResult; virtual; stdcall; abstract;
  823.     function CreateViewObject(hwndOwner:HWND; riid:TIID;
  824.                               var ppvOut: pointer):HResult; virtual; stdcall; abstract;
  825.     function GetAttributesOf(cidl:UINT; var apidl: PITEMIDLIST;
  826.                              var rgfInOut:UINT):HResult; virtual; stdcall; abstract;
  827.     function GetUIObjectOf(hwndOwner:HWND; cidl:UINT; var apidl: PITEMIDLIST;
  828.                            riid:TIID; var  prgfInOut:UINT; var ppvOut:pointer):HResult; virtual; stdcall; abstract;
  829.     function GetDisplayNameOf(pidl: PITEMIDLIST; uFlags:DWORD;
  830.                               lpName: PSTRRET):HResult; virtual; stdcall; abstract;
  831.     function SetNameOf(hwndOwner:HWND; pidl: PITEMIDLIST;
  832.                        lpszName:POLEStr; uFlags: DWORD;
  833.                        var ppidlOut: PITEMIDLIST):HResult; virtual; stdcall; abstract;
  834.     end;
  835.  
  836. {  Helper function which returns a IShellFolder interface to the desktop }
  837. { folder. This is equivalent to call CoCreateInstance with CLSID_ShellDesktop. }
  838.  
  839. {  CoCreateInstance(CLSID_Desktop, NULL, }
  840. {                   CLSCTX_INPROC, IID_IShellFolder, &pshf); }
  841.  
  842. type TSHGetDesktopFolder = function (var ppshf: ISHELLFOLDER):HResult; stdcall;
  843. var  SHGetDesktopFolder  : TSHGetDesktopFolder;
  844.  
  845. {========================================================================== }
  846. { Clipboard format which may be supported by IDataObject from system }
  847. { defined shell folders (such as directories, network, ...). }
  848. {========================================================================== }
  849. const
  850.   CFSTR_SHELLIDLIST       ='Shell IDList Array'    { CF_IDLIST };
  851.   CFSTR_SHELLIDLISTOFFSET ='Shell Object Offsets'  { CF_OBJECTPOSITIONS };
  852.   CFSTR_NETRESOURCES      ='Net Resource'          { CF_NETRESOURCE };
  853.   CFSTR_FILEDESCRIPTOR    ='FileGroupDescriptor'   { CF_FILEGROUPDESCRIPTOR };
  854.   CFSTR_FILECONTENTS      ='FileContents'          { CF_FILECONTENTS };
  855.   CFSTR_FILENAME          ='FileName'              { CF_FILENAME };
  856.   CFSTR_PRINTERGROUP      ='PrinterFriendlyName'   { CF_PRINTERS };
  857.   CFSTR_FILENAMEMAP       ='FileNameMap'           { CF_FILENAMEMAP };
  858.  
  859.   { CF_OBJECTPOSITIONS }
  860.  
  861.   DVASPECT_SHORTNAME     = 2 { use for CF_HDROP to get short name version };
  862.  
  863. { format of CF_NETRESOURCE }
  864.  
  865. type
  866.   PNRESARRAY = ^TNRESARRAY;
  867.   TNRESARRAY = record { anr }
  868.      cItems:UINT;
  869.      nr: array[0..0] of TNETRESOURCE;
  870.      end;
  871.  
  872.  
  873. { format of CF_IDLIST }
  874.   PIDA = ^TIDA;
  875.   TIDA = record
  876.      cidl:UINT;          { number of relative IDList }
  877.      aoffset: array[0..0] of UINT;    { [0]: folder IDList, [1]-[cidl]: item IDList }
  878.      end;
  879.  
  880.  
  881. { FILEDESCRIPTOR.dwFlags field indicate which fields are to be used }
  882. const
  883.     FD_CLSID            = $0001;
  884.     FD_SIZEPOINT        = $0002;
  885.     FD_ATTRIBUTES       = $0004;
  886.     FD_CREATETIME       = $0008;
  887.     FD_ACCESSTIME       = $0010;
  888.     FD_WRITESTIME       = $0020;
  889.     FD_FILESIZE         = $0040;
  890.     FD_LINKUI           = $8000;       { 'link' UI is prefered }
  891.  
  892. type
  893.   PFILEDESCRIPTOR = ^TFILEDESCRIPTOR;
  894.   TFILEDESCRIPTOR = record { fod }
  895.      dwFlags:DWORD;
  896.      clsid:TCLSID;
  897.      sizel:TSIZE;
  898.      pointl:TPOINT;
  899.      dwFileAttributes:DWORD;
  900.      ftCreationTime:TFILETIME;
  901.      ftLastAccessTime:TFILETIME;
  902.      ftLastWriteTime:TFILETIME;
  903.      nFileSizeHigh:DWORD;
  904.      nFileSizeLow:DWORD;
  905.      cFileName: array[0..MAX_PATH-1] of CHAR;
  906.      end;
  907.  
  908.  
  909. { format of CF_FILEGROUPDESCRIPTOR }
  910.   PFILEGROUPDESCRIPTOR = ^TFILEGROUPDESCRIPTOR;
  911.   TFILEGROUPDESCRIPTOR = record { fgd }
  912.       cItems:UINT;
  913.       fgd: array[0..0] of TFILEDESCRIPTOR;
  914.       end;
  915.  
  916.  
  917. { format of CF_HDROP and CF_PRINTERS, in the HDROP case the data that follows }
  918. { is a double null terinated list of file names, for printers they are printer }
  919. { friendly names }
  920.   PDROPFILES = ^TDROPFILES;
  921.   TDROPFILES = record
  922.     pFiles:DWORD;                       { offset of file list }
  923.     pt:TPOINT;                          { drop point (client coords) }
  924.     fNC:BOOL;                           { is it on NonClient area }
  925.                                         { and pt is in screen coords }
  926.     fWide:BOOL;                         { WIDE character switch }
  927.     end;
  928.  
  929. {====== File System Notification APIs =============================== }
  930. const
  931.    {  File System Notification flags }
  932.    SHCNE_RENAMEITEM          =$00000001;
  933.    SHCNE_CREATE              =$00000002;
  934.    SHCNE_DELETE              =$00000004;
  935.    SHCNE_MKDIR               =$00000008;
  936.    SHCNE_RMDIR               =$00000010;
  937.    SHCNE_MEDIAINSERTED       =$00000020;
  938.    SHCNE_MEDIAREMOVED        =$00000040;
  939.    SHCNE_DRIVEREMOVED        =$00000080;
  940.    SHCNE_DRIVEADD            =$00000100;
  941.    SHCNE_NETSHARE            =$00000200;
  942.    SHCNE_NETUNSHARE          =$00000400;
  943.    SHCNE_ATTRIBUTES          =$00000800;
  944.    SHCNE_UPDATEDIR           =$00001000;
  945.    SHCNE_UPDATEITEM          =$00002000;
  946.    SHCNE_SERVERDISCONNECT    =$00004000;
  947.    SHCNE_UPDATEIMAGE         =$00008000;
  948.    SHCNE_DRIVEADDGUI         =$00010000;
  949.    SHCNE_RENAMEFOLDER        =$00020000;
  950.    SHCNE_FREESPACE           =$00040000;
  951.  
  952.    SHCNE_ASSOCCHANGED        =$08000000;
  953.  
  954.    SHCNE_DISKEVENTS          =$0002381F;
  955.    SHCNE_GLOBALEVENTS        =$0C0581E0 { Events that dont match pidls first };
  956.    SHCNE_ALLEVENTS           =$7FFFFFFF;
  957.    SHCNE_INTERRUPT           =$80000000 { The presence of this flag indicates };
  958.                                         { that the event was generated by an }
  959.                                         { interrupt.  It is stripped out before }
  960.                                         { the clients of SHCNNotify_ see it. }
  961.  
  962.    { Flags }
  963.    { uFlags & SHCNF_TYPE is an ID which indicates what dwItem1 and dwItem2 mean }
  964.    SHCNF_IDLIST      =$0000        { LPITEMIDLIST };
  965.    SHCNF_PATH        =$0001        { path name };
  966.    SHCNF_PRINTER     =$0002        { printer friendly name };
  967.    SHCNF_DWORD       =$0003        { DWORD };
  968.    SHCNF_TYPE        =$00FF;
  969.    SHCNF_FLUSH       =$1000;
  970.    SHCNF_FLUSHNOWAIT =$2000;
  971.  
  972. {  APIs }
  973.  
  974. type TSHChangeNotify = procedure (wEventId:longint; uFlags:UINT; dwItem1,dwItem2:pointer); stdcall;
  975. var  SHChangeNotify  : TSHChangeNotify;
  976.  
  977. type TSHAddToRecentDocs = procedure (uFlags:UINT; pv:pointer); stdcall;
  978. var  SHAddToRecentDocs  : TSHAddToRecentDocs;
  979.  
  980. type TSHGetInstanceExplorer = function (var Unk:IUnknown):HResult; stdcall;
  981. var  SHGetInstanceExplorer  : TSHGetInstanceExplorer;
  982.  
  983. { SHAddToRecentDocs }
  984. const
  985.   SHARD_PIDL      =$00000001;
  986.   SHARD_PATH      =$00000002;
  987.  
  988. procedure LoadLibs;
  989. procedure FreeLibs;
  990.  
  991. implementation
  992.  
  993. const Shell32DLL = 'shell32.dll';
  994.  
  995. var  hnLib: HMODULE;
  996.  
  997. procedure LoadLibs;
  998. begin
  999.   hnLib:=LoadLibrary(PChar(Shell32DLL));
  1000.   if hnLib=0 then
  1001.     raise Exception.Create('ShellOBJ - initialization: couldn''t open SHELL32.DLL')
  1002.   else begin
  1003.     SHGetPathFromIDList:=GetProcAddress(hnLib, 'SHGetPathFromIDList');
  1004.     SHGetSpecialFolderLocation:=GetProcAddress(hnLib, 'SHGetSpecialFolderLocation');
  1005.     SHBrowseForFolder:=GetProcAddress(hnLib, 'SHBrowseForFolder');
  1006.     SHLoadInProc:=GetProcAddress(hnLib, 'SHLoadInProc');
  1007.     SHGetDesktopFolder:=GetProcAddress(hnLib, 'SHGetDesktopFolder');
  1008.     SHChangeNotify:=GetProcAddress(hnLib, 'SHChangeNotify');
  1009.     SHAddToRecentDocs:=GetProcAddress(hnLib, 'SHAddToRecentDocs');
  1010.     SHGetInstanceExplorer:=GetProcAddress(hnLib, 'SHGetInstanceExplorer');
  1011.     if not Assigned(SHGetInstanceExplorer) or not Assigned(SHAddToRecentDocs) or not Assigned(SHChangeNotify) or
  1012.        not Assigned(SHGetDesktopFolder) or not Assigned(SHLoadInProc) or not Assigned(SHBrowseForFolder) or
  1013.        not Assigned(SHGetSpecialFolderLocation) or not Assigned(SHGetPathFromIDList) then
  1014.        raise Exception.Create('ShellOBJ - initialization: at least one function couldn''t be loaded!');
  1015.   end;
  1016. end;
  1017.  
  1018. procedure FreeLibs;
  1019. begin
  1020.   if hnLib<>0 then
  1021.     FreeLibrary(hnLib);
  1022. end;
  1023.  
  1024. function SHGetMalloc(var ppMalloc: IMALLOC):HResult;
  1025. begin
  1026.   Result := CoGetMalloc(MEMCTX_TASK,ppMalloc);
  1027. end;
  1028.  
  1029. //function SHGetPathFromIDList; external Shell32DLL name 'SHGetPathFromIDList';
  1030. //function SHGetSpecialFolderLocation; external Shell32DLL name 'SHGetSpecialFolderLocation';
  1031. //function SHBrowseForFolder; external Shell32DLL name 'SHBrowseForFolder';
  1032. //function SHLoadInProc; external Shell32DLL name 'SHLoadInProc';
  1033. //function SHGetDesktopFolder       ; external Shell32DLL name 'SHGetDesktopFolder';
  1034. //procedure SHChangeNotify;    external Shell32DLL name 'SHChangeNotify';
  1035. //procedure SHAddToRecentDocs; external Shell32DLL name 'SHAddToRecentDocs';
  1036. //function SHGetInstanceExplorer;  external Shell32DLL name 'SHGetInstanceExplorer';
  1037.  
  1038. end.
  1039.