Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | daniel-mar | 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. |