DragDropURL.pas 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. unit DragDropURL;
  2. {
  3. Description
  4. ===========
  5. TDragDropURL is a component for simple OLE drag-and-drop operations
  6. with URLs. The component is a child-class from TDragDrop.
  7. Disclaimer
  8. ==========
  9. The author disclaims all warranties, expressed or implied, including,
  10. without limitation, the warranties of merchantability and of fitness
  11. for any purpose. The author assumes no liability for damages, direct or
  12. consequential, which may result from the use of this component/unit.
  13. Restrictions on Using the Unit / Component
  14. ==========================================
  15. This unit/component is copyright 1998 by Dieter Steinwedel. ALL RIGHTS
  16. ARE RESERVED BY DIETER STEINWEDEL. You are allowed to use it freely
  17. subject to the following restrictions:
  18. • You are not allowed delete or alter the author's name and
  19. copyright in any manner
  20. • You are not allowed to publish a copy, modified version or
  21. compilation neither for payment in any kind nor freely
  22. • You are allowed to create a link to the download in the WWW
  23. • These restrictions and terms apply to you as long as until
  24. I alter them. Changes can found on my homepage
  25. Contact
  26. =======
  27. homepage: http://godard.oec.uni-osnabrueck.de/student_home/dsteinwe/delphi/DietersDelphiSite.htm
  28. }
  29. {$ALIGN ON}
  30. {$ASSERTIONS OFF}
  31. {$BOOLEVAL OFF}
  32. {$DENYPACKAGEUNIT OFF}
  33. {$EXTENDEDSYNTAX ON}
  34. {$HINTS ON}
  35. {$IMPORTEDDATA ON}
  36. {$LONGSTRINGS ON}
  37. {$OPTIMIZATION ON}
  38. {$TYPEDADDRESS OFF}
  39. {$TYPEINFO OFF}
  40. {$WARNINGS ON}
  41. interface
  42. uses DragDrop, Windows, Classes, SysUtils, ActiveX, PIDL, ShlObj;
  43. type
  44. TDataObjectURL = class(TDataObject)
  45. private
  46. URLStream:TMemoryStream;
  47. FGDStream:TMemoryStream;
  48. public
  49. constructor Create(ScrapFileName, URL:string; Scrap:boolean);
  50. destructor Destroy; override;
  51. function RenderData(FormatEtc:TFormatEtc;
  52. var StgMedium: TStgMedium):HResult; override;
  53. end;
  54. TDropTargetURL = class(TDropTarget)
  55. protected
  56. procedure AcceptDataObject(DataObj: IDataObject; var Accept:boolean); override;
  57. public
  58. constructor Create(AOwner: TDragDrop);
  59. destructor Destroy; override;
  60. procedure RenderDropped(DataObj: IDataObject; grfKeyState: Longint;
  61. pt: TPoint; var dwEffect: longint); override;
  62. end;
  63. TDragDropURL = class(TDragDrop)
  64. private
  65. FURL:String;
  66. FScrapFileName:string;
  67. protected
  68. function CreateDataObject:TDataObject; override;
  69. public
  70. constructor Create(AOwner: TComponent); override;
  71. destructor Destroy; override;
  72. property URL: String read FURL write FURL;
  73. property ScrapFileName: string read FScrapFileName write FScrapFileName;
  74. end;
  75. procedure Register;
  76. implementation
  77. // TDataObjectURL -------------------------------------------------------------
  78. const HLineSize=24;
  79. constructor TDataObjectURL.Create(ScrapFileName, URL:string; Scrap:boolean);
  80. var FE:TFormatEtc;
  81. SM:TStgMedium;
  82. pc:array[0..255] of char;
  83. FDescriptor:TFILEGROUPDESCRIPTOR;
  84. begin
  85. inherited Create;
  86. with FE do
  87. begin
  88. cfFormat:=CF_SHELLURL;
  89. ptd:=nil;
  90. dwAspect:=DVAspect_Content;
  91. lindex:=-1;
  92. tymed:=tymed_HGlobal;
  93. end;
  94. SetData(FE,SM,false);
  95. FE.cfFormat:=cf_Text;
  96. SetData(FE,SM,false);
  97. if Scrap then
  98. begin
  99. FE.cfFormat:=CF_FILEDESCRIPTOR;
  100. SetData(FE,SM,false);
  101. FE.cfFormat:=CF_FILECONTENTS;
  102. FE.lindex:=0;
  103. SetData(FE,SM,false);
  104. end;
  105. URLStream:=TMemoryStream.Create;
  106. Fillchar(pc,sizeof(pc),#0);
  107. pc:='[InternetShortcut]'#13#10'URL=';
  108. URLStream.Write(pc,HLineSize);
  109. Fillchar(pc,sizeof(pc),#0);
  110. strPcopy(pc,URL+#0);
  111. URLStream.Write(pc,length(URL)+1);
  112. FGDStream:=TMemoryStream.Create;
  113. FDescriptor.cItems:=1;
  114. with FDescriptor.fgd[0] do
  115. begin
  116. dwFlags:=FD_LinkUI;
  117. FillChar(cFileName,sizeof(cFileName),#0);
  118. if ScrapFileName<>'' then
  119. begin
  120. if CompareText(ExtractFileExt(ScrapFileName),'.url')<>0 then
  121. ScrapFileName:=ScrapFileName+'.url';
  122. strPcopy(cFileName,ScrapFileName+#0);
  123. end
  124. else cFileName:='URL Link.url';
  125. end;
  126. FGDStream.Write(FDescriptor,SizeOf(FDescriptor));
  127. end;
  128. destructor TDataObjectURL.Destroy;
  129. begin
  130. URLStream.free;
  131. FGDStream.free;
  132. inherited Destroy;
  133. end;
  134. function TDataObjectURL.RenderData(FormatEtc:TFormatEtc;
  135. var StgMedium: TStgMedium):HResult;
  136. var h: HGlobal;
  137. p:pointer;
  138. begin
  139. Result:=E_Fail;
  140. if (FormatEtc.cfFormat=cf_Text) or (FormatEtc.cfFormat=CF_SHELLURL) then
  141. begin
  142. h:=GlobalAlloc(GHND or GMEM_SHARE, URLStream.Size-HLineSize);
  143. if h=0 then
  144. begin
  145. Result:=E_OUTOFMEMORY;
  146. exit;
  147. end;
  148. p:=globallock(h);
  149. URLStream.Seek(HLineSize,0);
  150. URLStream.Read(p^,URLStream.Size-HLineSize);
  151. globalunlock(h);
  152. with StgMedium do
  153. begin
  154. tymed:=TYMED_HGLOBAL;
  155. hGlobal := h;
  156. unkForRelease := nil;
  157. end;
  158. Result:=S_OK;
  159. end;
  160. if (FormatEtc.cfFormat=CF_FILECONTENTS) then
  161. begin
  162. h:=GlobalAlloc(GHND or GMEM_SHARE, URLStream.Size);
  163. if h=0 then
  164. begin
  165. Result:=E_OUTOFMEMORY;
  166. exit;
  167. end;
  168. p:=globallock(h);
  169. URLStream.Seek(0,0);
  170. URLStream.Read(p^,URLStream.Size);
  171. globalunlock(h);
  172. with StgMedium do
  173. begin
  174. tymed:=TYMED_HGLOBAL;
  175. hGlobal := h;
  176. unkForRelease := nil;
  177. end;
  178. Result:=S_OK;
  179. end;
  180. if (FormatEtc.cfFormat=CF_FILEDESCRIPTOR) then
  181. begin
  182. h:=GlobalAlloc(GHND or GMEM_SHARE, FGDStream.Size);
  183. if h=0 then
  184. begin
  185. Result:=E_OUTOFMEMORY;
  186. exit;
  187. end;
  188. p:=globallock(h);
  189. FGDStream.Seek(0,0);
  190. FGDStream.Read(p^,FGDStream.Size);
  191. globalunlock(h);
  192. with StgMedium do
  193. begin
  194. tymed:=TYMED_HGLOBAL;
  195. hGlobal := h;
  196. unkForRelease := nil;
  197. end;
  198. Result:=S_OK;
  199. end;
  200. end;
  201. // TDropTargetURL -------------------------------------------------------------
  202. constructor TDropTargetURL.Create(AOwner: TDragDrop);
  203. begin
  204. inherited Create(AOwner);
  205. end;
  206. destructor TDropTargetURL.Destroy;
  207. begin
  208. inherited Destroy;
  209. end;
  210. procedure TDropTargetURL.AccepTDataObject(DataObj: IDataObject;
  211. var Accept:boolean);
  212. var FE:TFormatEtc;
  213. begin
  214. with FE do
  215. begin
  216. cfFormat:=CF_SHELLURL;
  217. ptd:=nil;
  218. dwAspect:=DVASPECT_CONTENT;
  219. lindex:=-1;
  220. tymed:=TYMED_HGLOBAL;
  221. end;
  222. Accept:=DataObj.QueryGetData(FE)=S_OK;
  223. end;
  224. procedure TDropTargetURL.RenderDropped(DataObj: IDataObject; grfKeyState: Longint;
  225. pt: TPoint; var dwEffect: longint);
  226. var FE: TFormatEtc;
  227. SM: TStgMedium;
  228. DataPtr: pchar;
  229. begin
  230. with FE do
  231. begin
  232. cfFormat:=CF_SHELLURL;
  233. ptd:=nil;
  234. dwAspect:=DVASPECT_CONTENT;
  235. lindex:=-1;
  236. tymed:=TYMED_HGLOBAL;
  237. end;
  238. if DataObj.GetData(FE,SM)=S_Ok then
  239. begin
  240. try
  241. DataPtr:=GlobalLock(SM.HGlobal);
  242. TDragDropURL(FOwner).FURL:=StrPas(DataPtr);
  243. finally
  244. GlobalUnLock(SM.HGlobal);
  245. ReleaseStgMedium(SM);
  246. end;
  247. end;
  248. end;
  249. // TDragDropURL ---------------------------------------------------------------
  250. constructor TDragDropURL.Create(AOwner: TComponent);
  251. begin
  252. inherited Create(AOwner);
  253. FURL:='';
  254. FScrapFileName:='';
  255. FDropTarget._Release;
  256. FDropTarget:=TDropTargetURL.Create(self);
  257. end;
  258. destructor TDragDropURL.Destroy;
  259. begin
  260. inherited destroy;
  261. end;
  262. function TDragDropURL.CreateDataObject:TDataObject;
  263. begin
  264. if FURL<>'' then Result:=TDataObjectURL.Create(FScrapFileName,FURL,true)
  265. else Result:=nil;
  266. end;
  267. // Register Component ----------------------------------------------------------
  268. procedure Register;
  269. begin
  270. {MP}RegisterComponents({'Shell32'}'DragDrop', [TDragDropURL]);
  271. end;
  272. end.