Subversion Repositories decoder

Rev

Blame | Last modification | View Log | RSS feed

  1. unit DragDropHandler;
  2.  
  3. // -----------------------------------------------------------------------------
  4. // Project:         Drag and Drop Component Suite.
  5. // Module:          DragDropHandler
  6. // Description:     Implements Drop and Drop Context Menu Shell Extenxions
  7. //                  (a.k.a. drag-and-drop handlers).
  8. // Version:         4.0
  9. // Date:            18-MAY-2001
  10. // Target:          Win32, Delphi 5-6
  11. // Authors:         Anders Melander, anders@melander.dk, http://www.melander.dk
  12. // Copyright        © 1997-2001 Angus Johnson & Anders Melander
  13. // -----------------------------------------------------------------------------
  14. interface
  15.  
  16. uses
  17.   DragDrop,
  18.   DragDropComObj,
  19.   DragDropContext,
  20.   Menus,
  21.   ShlObj,
  22.   ActiveX,
  23.   Windows,
  24.   Classes;
  25.  
  26. {$include DragDrop.inc}
  27.  
  28. type
  29. ////////////////////////////////////////////////////////////////////////////////
  30. //
  31. //              TDragDropHandler
  32. //
  33. ////////////////////////////////////////////////////////////////////////////////
  34. // A typical drag-and-drop handler session goes like this:
  35. // 1. User right-drags (drags with the right mouse button) and drops one or more
  36. //    source files which has a registered drag-and-drop handler.
  37. // 2. The shell loads the drag-and-drop handler module.
  38. // 3. The shell instantiates the registered drag drop handler object as an
  39. //    in-process COM server.
  40. // 4. The IShellExtInit.Initialize method is called with the name of the target
  41. //    folder and a data object which contains the dragged data.
  42. //    The target folder name is stored in the TDragDropHandler.TargetFolder
  43. //    property as a string and in the TargetPIDL property as a PIDL.
  44. // 5. The IContextMenu.QueryContextMenu method is called to populate the popup
  45. //    menu.
  46. //    TDragDropHandler uses the PopupMenu property to populate the drag-and-drop
  47. //    context menu.
  48. // 6. If the user chooses one of the context menu items we have supplied, the
  49. //    IContextMenu.InvokeCommand method is called.
  50. //    TDragDropHandler locates the corresponding TMenuItem and fires the menu
  51. //    items OnClick event.
  52. // 7. The shell unloads the drag-and-drop handler module (usually after a few
  53. //    seconds).
  54. ////////////////////////////////////////////////////////////////////////////////
  55.   TDragDropHandler = class(TDropContextMenu, IShellExtInit, IContextMenu)
  56.   private
  57.     FFolderPIDL: pItemIDList;
  58.   protected
  59.     function GetFolder: string;
  60.     { IShellExtInit }
  61.     function Initialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
  62.       hKeyProgID: HKEY): HResult; stdcall;
  63.     { IContextMenu }
  64.     function QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast,
  65.       uFlags: UINT): HResult; stdcall;
  66.     function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;
  67.     function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
  68.       pszName: LPSTR; cchMax: UINT): HResult; stdcall;
  69.   public
  70.     destructor Destroy; override;
  71.     function GetFolderPIDL: pItemIDList; // Caller must free PIDL!
  72.     property Folder: string read GetFolder;
  73.   end;
  74.  
  75. ////////////////////////////////////////////////////////////////////////////////
  76. //
  77. //              TDragDropHandlerFactory
  78. //
  79. ////////////////////////////////////////////////////////////////////////////////
  80. // COM Class factory for TDragDropHandler.
  81. ////////////////////////////////////////////////////////////////////////////////
  82.   TDragDropHandlerFactory = class(TDropContextMenuFactory)
  83.   protected
  84.     function HandlerRegSubKey: string; override;
  85.   end;
  86.  
  87. ////////////////////////////////////////////////////////////////////////////////
  88. //
  89. //              Component registration
  90. //
  91. ////////////////////////////////////////////////////////////////////////////////
  92. procedure Register;
  93.  
  94.  
  95. ////////////////////////////////////////////////////////////////////////////////
  96. //
  97. //              Misc.
  98. //
  99. ////////////////////////////////////////////////////////////////////////////////
  100.  
  101.  
  102. ////////////////////////////////////////////////////////////////////////////////
  103. ////////////////////////////////////////////////////////////////////////////////
  104. //
  105. //                      IMPLEMENTATION
  106. //
  107. ////////////////////////////////////////////////////////////////////////////////
  108. ////////////////////////////////////////////////////////////////////////////////
  109. implementation
  110.  
  111. uses
  112.   DragDropFile,
  113.   DragDropPIDL,
  114.   Registry,
  115.   ComObj,
  116.   SysUtils;
  117.  
  118. ////////////////////////////////////////////////////////////////////////////////
  119. //
  120. //              Component registration
  121. //
  122. ////////////////////////////////////////////////////////////////////////////////
  123.  
  124. procedure Register;
  125. begin
  126.   RegisterComponents(DragDropComponentPalettePage, [TDragDropHandler]);
  127. end;
  128.  
  129.  
  130. ////////////////////////////////////////////////////////////////////////////////
  131. //
  132. //              Utilities
  133. //
  134. ////////////////////////////////////////////////////////////////////////////////
  135.  
  136.  
  137. ////////////////////////////////////////////////////////////////////////////////
  138. //
  139. //              TDragDropHandler
  140. //
  141. ////////////////////////////////////////////////////////////////////////////////
  142. destructor TDragDropHandler.Destroy;
  143. begin
  144.   if (FFolderPIDL <> nil) then
  145.     ShellMalloc.Free(FFolderPIDL);
  146.   inherited Destroy;
  147. end;
  148.  
  149. function TDragDropHandler.GetCommandString(idCmd, uType: UINT;
  150.   pwReserved: PUINT; pszName: LPSTR; cchMax: UINT): HResult;
  151. begin
  152.   Result := inherited GetCommandString(idCmd, uType, pwReserved, pszName, cchMax);
  153. end;
  154.  
  155. function TDragDropHandler.GetFolder: string;
  156. begin
  157.   Result := GetFullPathFromPIDL(FFolderPIDL);
  158. end;
  159.  
  160. function TDragDropHandler.GetFolderPIDL: pItemIDList;
  161. begin
  162.   Result := CopyPIDL(FFolderPIDL);
  163. end;
  164.  
  165. function TDragDropHandler.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
  166. begin
  167.   Result := E_FAIL;
  168.   try
  169.     Result := inherited InvokeCommand(lpici);
  170.   finally
  171.     if (Result <> E_FAIL) then
  172.     begin
  173.       ShellMalloc.Free(FFolderPIDL);
  174.       FFolderPIDL := nil;
  175.     end;
  176.   end;
  177. end;
  178.  
  179. function TDragDropHandler.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,
  180.   idCmdLast, uFlags: UINT): HResult;
  181. begin
  182.   Result := inherited QueryContextMenu(Menu, indexMenu, idCmdFirst,
  183.     idCmdLast, uFlags);
  184. end;
  185.  
  186. function TDragDropHandler.Initialize(pidlFolder: PItemIDList;
  187.   lpdobj: IDataObject; hKeyProgID: HKEY): HResult;
  188. begin
  189.   if (pidlFolder <> nil) then
  190.   begin
  191.     // Copy target folder PIDL.
  192.     FFolderPIDL := CopyPIDL(pidlFolder);
  193.     Result := inherited Initialize(pidlFolder, lpdobj, hKeyProgID);
  194.   end else
  195.     Result := E_INVALIDARG;
  196. end;
  197.  
  198. ////////////////////////////////////////////////////////////////////////////////
  199. //
  200. //              TDragDropHandlerFactory
  201. //
  202. ////////////////////////////////////////////////////////////////////////////////
  203. function TDragDropHandlerFactory.HandlerRegSubKey: string;
  204. begin
  205.   Result := 'DragDropHandlers';
  206. end;
  207.  
  208. end.
  209.