DragDropText.pas 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. unit DragDropText;
  2. {
  3. Description
  4. ===========
  5. TDragDropText is a component for simple OLE drag-and-drop operations
  6. with text. 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;
  43. type
  44. TDataObjectText = class(TDataObject)
  45. private
  46. TextStream:TMemoryStream;
  47. public
  48. constructor Create(StringList: TStringList);
  49. destructor Destroy; override;
  50. function RenderData(FormatEtc:TFormatEtc;
  51. var StgMedium: TStgMedium):HResult; override;
  52. end;
  53. TDropTargetText = class(TDropTarget)
  54. protected
  55. procedure AcceptDataObject(DataObj: IDataObject; var Accept:boolean); override;
  56. public
  57. constructor Create(AOwner: TDragDrop);
  58. destructor Destroy; override;
  59. procedure RenderDropped(DataObj: IDataObject; grfKeyState: Longint;
  60. pt: TPoint; var dwEffect: longint); override;
  61. end;
  62. TDragDropText = class(TDragDrop)
  63. private
  64. FLines:TStringList;
  65. protected
  66. function CreateDataObject:TDataObject; override;
  67. public
  68. constructor Create(AOwner: TComponent); override;
  69. destructor Destroy; override;
  70. property Lines: TStringList read FLines write FLines;
  71. end;
  72. procedure Register;
  73. implementation
  74. // some local functions --------------------------------------------------------
  75. procedure CopyAsText(Strs:TStrings; DataPtr: PChar; DataSize:longint);
  76. var lStrs:TStringList;
  77. s:string;
  78. i:longint;
  79. begin
  80. lStrs:=TStringList.Create;
  81. s:='';
  82. i:=0;
  83. while i<DataSize do
  84. begin
  85. if (DataPtr[i]=#13) and (DataPtr[i+1]=#10) and (i+1<DataSize) then
  86. begin
  87. lstrs.add(s);
  88. s:='';
  89. inc(i);
  90. end else s:=s+DataPtr[i];
  91. inc(i);
  92. end;
  93. if s<>'' then lstrs.add(s);
  94. Strs.assign(lStrs);
  95. lStrs.free;
  96. end;
  97. // TDataObjectText -------------------------------------------------------------
  98. constructor TDataObjectText.Create(StringList: TStringList);
  99. var i: integer;
  100. FE:TFormatEtc;
  101. SM:TStgMedium;
  102. pc:array[0..255] of char;
  103. begin
  104. inherited Create;
  105. with FE do
  106. begin
  107. cfFormat:=cf_Text;
  108. ptd:=nil;
  109. dwAspect:=DVAspect_Content;
  110. lindex:=-1;
  111. tymed:=tymed_HGlobal;
  112. end;
  113. SetData(FE,SM,false);
  114. TextStream:=TMemoryStream.Create;
  115. for i:=0 to StringList.count-1 do
  116. begin
  117. if i=StringList.count-1 then
  118. begin
  119. strPcopy(pc, StringList[i]+#0);
  120. TextStream.Write(pc,length(StringList[i])+1);
  121. end
  122. else
  123. begin
  124. strPcopy(pc, StringList[i]+#13#10);
  125. TextStream.Write(pc,length(StringList[i])+2);
  126. end;
  127. end;
  128. end;
  129. destructor TDataObjectText.Destroy;
  130. begin
  131. TextStream.free;
  132. inherited Destroy;
  133. end;
  134. function TDataObjectText.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 then
  141. begin
  142. h:=GlobalAlloc(GHND or GMEM_SHARE, TextStream.Size);
  143. if h=0 then
  144. begin
  145. Result:=E_OUTOFMEMORY;
  146. exit;
  147. end;
  148. p:=globallock(h);
  149. TextStream.Seek(0,0);
  150. TextStream.Read(p^,TextStream.Size);
  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. end;
  161. // TDropTargetText -------------------------------------------------------------
  162. constructor TDropTargetText.Create(AOwner: TDragDrop);
  163. begin
  164. inherited Create(AOwner);
  165. end;
  166. destructor TDropTargetText.Destroy;
  167. begin
  168. inherited Destroy;
  169. end;
  170. procedure TDropTargetText.AccepTDataObject(DataObj: IDataObject;
  171. var Accept:boolean);
  172. var FE:TFormatEtc;
  173. begin
  174. with FE do
  175. begin
  176. cfFormat:=cf_Text;
  177. ptd:=nil;
  178. dwAspect:=DVASPECT_CONTENT;
  179. lindex:=-1;
  180. tymed:=TYMED_HGLOBAL;
  181. end;
  182. Accept:=DataObj.QueryGetData(FE)=S_OK;
  183. end;
  184. procedure TDropTargetText.RenderDropped(DataObj: IDataObject; grfKeyState: Longint;
  185. pt: TPoint; var dwEffect: longint);
  186. var FE: TFormatEtc;
  187. SM: TStgMedium;
  188. DataSize: longint;
  189. DataPtr: pointer;
  190. begin
  191. with FE do
  192. begin
  193. cfFormat:=CF_Text;
  194. ptd:=nil;
  195. dwAspect:=DVASPECT_CONTENT;
  196. lindex:=-1;
  197. tymed:=TYMED_HGLOBAL;
  198. end;
  199. if DataObj.GetData(FE,SM)=S_Ok then
  200. begin
  201. DataSize:=GlobalSize(SM.HGlobal);
  202. try
  203. DataPtr:=GlobalLock(SM.HGlobal);
  204. CopyAsText(TDragDropText(FOwner).FLines, DataPtr,
  205. DataSize);
  206. finally
  207. GlobalUnLock(SM.HGlobal);
  208. ReleaseStgMedium(SM);
  209. end;
  210. end;
  211. end;
  212. // TDragDropText ---------------------------------------------------------------
  213. constructor TDragDropText.Create(AOwner: TComponent);
  214. begin
  215. inherited Create(AOwner);
  216. FLines:=TStringList.Create;
  217. FLines.sorted:=false;
  218. FLines.Duplicates:=dupAccept;
  219. FDropTarget._Release;
  220. FDropTarget:=TDropTargetText.Create(self);
  221. end;
  222. destructor TDragDropText.Destroy;
  223. begin
  224. FLines.Free;
  225. inherited destroy;
  226. end;
  227. function TDragDropText.CreateDataObject:TDataObject;
  228. begin
  229. if FLines.Count>0 then Result:=TDataObjectText.Create(FLines)
  230. else Result:=nil;
  231. end;
  232. // Register Component ----------------------------------------------------------
  233. procedure Register;
  234. begin
  235. {MP}RegisterComponents({'Shell32'}'DragDrop', [TDragDropText]);
  236. end;
  237. end.