DragDrop.pas 77 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054
  1. unit DragDrop;
  2. {
  3. Description
  4. ===========
  5. TDragDrop is a component for OLE drag-and-drop operations. The component
  6. is able to make successor components of TWinControl to the source AND
  7. target of drag-and-drop operations.
  8. Disclaimer
  9. ==========
  10. The author disclaims all warranties, expressed or implied, including,
  11. without limitation, the warranties of merchantability and of fitness
  12. for any purpose. The author assumes no liability for damages, direct or
  13. consequential, which may result from the use of this component/unit.
  14. Restrictions on Using the Unit / Component
  15. ==========================================
  16. This unit/component is copyright 1998 by Dieter Steinwedel. ALL RIGHTS
  17. ARE RESERVED BY DIETER STEINWEDEL. You are allowed to use it freely
  18. subject to the following restrictions:
  19. • You are not allowed delete or alter the author's name and
  20. copyright in any manner
  21. • You are not allowed to publish a copy, modified version or
  22. compilation neither for payment in any kind nor freely
  23. • You are allowed to create a link to the download in the WWW
  24. • These restrictions and terms apply to you as long as until
  25. I alter them. Changes can found on my homepage
  26. Contact
  27. =======
  28. homepage: http://godard.oec.uni-osnabrueck.de/student_home/dsteinwe/delphi/DietersDelphiSite.htm
  29. }
  30. {$ALIGN ON}
  31. {$ASSERTIONS OFF}
  32. {$BOOLEVAL OFF}
  33. {$DENYPACKAGEUNIT OFF}
  34. {$EXTENDEDSYNTAX ON}
  35. {$HINTS ON}
  36. {$IMPORTEDDATA ON}
  37. {$LONGSTRINGS ON}
  38. {$OPTIMIZATION ON}
  39. {$TYPEDADDRESS OFF}
  40. {$TYPEINFO OFF}
  41. {$WARNINGS ON}
  42. {$WARN SYMBOL_DEPRECATED OFF}
  43. interface
  44. uses
  45. SysUtils, Windows, Classes, Controls, Forms, ShellApi,
  46. Menus, Messages, Graphics, ActiveX, ExtCtrls, Grids;
  47. {MP}(*$HPPEMIT '#include <oleidl.h>'*)
  48. // Available drop effects by the system:
  49. // (redefined, so need not to type "ActiveX" in the uses clause of your units )
  50. const DROPEFFECT_None=ActiveX.DROPEFFECT_None;
  51. DROPEFFECT_Copy=ActiveX.DROPEFFECT_Copy;
  52. DROPEFFECT_Move=ActiveX.DROPEFFECT_Move;
  53. DROPEFFECT_Link=ActiveX.DROPEFFECT_Link;
  54. DROPEFFECT_Scroll=ActiveX.DROPEFFECT_Scroll;
  55. TYMED_HGLOBAL=ActiveX.TYMED_HGLOBAL;
  56. TYMED_FILE=ActiveX.TYMED_FILE;
  57. TYMED_ISTREAM=ActiveX.TYMED_ISTREAM;
  58. TYMED_ISTORAGE=ActiveX.TYMED_ISTORAGE;
  59. TYMED_GDI=ActiveX.TYMED_GDI;
  60. TYMED_MFPICT=ActiveX.TYMED_MFPICT;
  61. TYMED_ENHMF=ActiveX.TYMED_ENHMF;
  62. TYMED_NULL=ActiveX.TYMED_NULL;
  63. DefaultCursor=0;
  64. type
  65. IEnumFormatEtc = ActiveX.IEnumFormatEtc;
  66. IDataObject = ActiveX.IDataObject;
  67. TFormatEtc = ActiveX.TFormatEtc;
  68. TStgMedium = ActiveX.TStgMedium;
  69. TDropEffect=(deCopy, deMove, deLink);
  70. TDragResult=(drInvalid, drCancelled, drCopy, drMove, drLink);
  71. TDropEffectSet = set of TDropEffect;
  72. TDragDetectStatus = (ddsNone, ddsLeft, ddsRight, ddsCancelled, ddsDrag);
  73. TRenderDataOn = (rdoEnter, rdoEnterAndDropSync, rdoEnterAndDropAsync, rdoDropSync, rdoDropAsync, rdoNever);
  74. TSrcCompatibilityCheck = (CheckLindex, CheckdwAspect);
  75. TSrcCompatibilityCheckSet = set of TSrcCompatibilityCheck;
  76. TScrollInterval=1..10000;
  77. TScrollDirection=(sdUp, sdDown, sdLeft, sdRight);
  78. // event handlers ...
  79. TOnDragEnter = procedure(DataObj: IDataObject; grfKeyState: Longint; pt: TPoint;
  80. var dwEffect: longint; var Accept:boolean) of object;
  81. TOnDragLeave = procedure of object;
  82. TOnDragOver = procedure(grfKeyState: Longint; pt: TPoint;
  83. var dwEffect: longint) of object;
  84. TOnDrop = procedure(DataObj: IDataObject; grfKeyState: Longint; pt: TPoint;
  85. var dwEffect: longint) of object;
  86. TOnQueryContinueDrag = procedure(fEscapePressed: BOOL; grfKeyState: Longint; var Result: HResult) of object;
  87. TOnGiveFeedback = procedure(dwEffect: Longint; var Result: HResult) of object;
  88. TOnDragDetect = procedure(grfKeyState: Longint; DetectStart, pt: TPoint; DragDetectStatus:TDragDetectStatus) of object;
  89. TOnProcessDropped = procedure(Sender: TObject; grfKeyState: Longint; pt: TPoint; dwEffect: Longint) of object;
  90. TOnBeforeScrolling = procedure(Sender: TObject; pt: TPoint; var Interval: TScrollInterval;
  91. ScrollDirection: TScrollDirection; var ScrollPage:boolean) of object;
  92. TOnMenuPopup = procedure(Sender: TObject; AMenu: HMenu; DataObj:IDataObject;
  93. AMinCustCmd:integer; grfKeyState: Longint; pt: TPoint) of object;
  94. TOnMenuExecCmd = procedure(Sender: TObject; AMenu: HMenu; DataObj:IDataObject;
  95. Command:integer; var dwEffect: longint; var Succeeded:boolean) of object;
  96. TOnMenuDestroy = procedure(Sender: TObject; AMenu: HMenu) of object;
  97. TFormatEtcArray = array of TFormatEtc;
  98. TDetectRec = record
  99. end;
  100. // list classes ...
  101. TFormatEtcList = class
  102. private
  103. FCount:integer;
  104. FList:TFormatEtcArray;
  105. function Get(Index: Integer): TFormatEtc;
  106. procedure Put(Index: Integer; Item: TFormatEtc);
  107. public
  108. constructor Create;
  109. destructor Destroy; override;
  110. function Add(Item: TFormatEtc):integer;
  111. procedure Clear;
  112. procedure Delete(Index: Integer);
  113. function Clone:TFormatEtcList;
  114. property Count:integer read FCount;
  115. property Items[Index:integer]:TFormatEtc read get write put;
  116. end;
  117. // inherited classes ...
  118. TDDInterfacedObject = class(TInterfacedObject)
  119. public
  120. function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
  121. function _AddRef: Integer; stdcall;
  122. function _Release: Integer; stdcall;
  123. end;
  124. TEnumFormatEtc = class(TDDInterfacedObject, IEnumFormatEtc)
  125. protected
  126. FFormatEtcList:TFormatEtcList;
  127. FIndex: integer;
  128. public
  129. constructor Create(FormatEtcList:TFormatEtcList);
  130. destructor Destroy; override;
  131. function Next(celt: Longint; out elt;
  132. pceltFetched: PLongint): HResult; stdcall;
  133. function Skip(celt: Longint): HResult; stdcall;
  134. function Reset: HResult; stdcall;
  135. function Clone(out Enum: IEnumFormatEtc): HResult; stdcall;
  136. end;
  137. TDataObject = class(TDDInterfacedObject, IDataObject)
  138. protected
  139. FFormatEtcList:TFormatEtcList;
  140. FCheckLindex:boolean;
  141. FCheckdwAspect:boolean;
  142. public
  143. constructor Create;
  144. destructor Destroy; override;
  145. function GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium):
  146. HResult; stdcall;
  147. function GetDataHere(const formatetc: TFormatEtc; out medium: TStgMedium):
  148. HResult; stdcall;
  149. function QueryGetData(const formatetc: TFormatEtc): HResult;
  150. stdcall;
  151. function GetCanonicalFormatEtc(const formatetc: TFormatEtc;
  152. out formatetcOut: TFormatEtc): HResult; stdcall;
  153. function SetData(const formatetc: TFormatEtc; var medium: TStgMedium;
  154. fRelease: BOOL): HResult; stdcall;
  155. function EnumFormatEtc(dwDirection: Longint; out enumFormatEtc:
  156. IEnumFormatEtc): HResult; stdcall;
  157. function DAdvise(const formatetc: TFormatEtc; advf: Longint;
  158. const advSink: IAdviseSink; out dwConnection: Longint): HResult; stdcall;
  159. function DUnadvise(dwConnection: Longint): HResult; stdcall;
  160. function EnumDAdvise(out enumAdvise: IEnumStatData): HResult;
  161. stdcall;
  162. function RenderData(FormatEtc:TFormatEtc;
  163. var StgMedium: TStgMedium): HResult; virtual; abstract;
  164. protected
  165. function AllowData(FormatEtc: TFormatEtc): Boolean; virtual;
  166. end;
  167. // forward declaration, because TDropSource and TDropTarget uses this class ...
  168. TDragDrop = class;
  169. TDropSource = class(TDDInterfacedObject, IDropSource)
  170. private
  171. FOwner: TDragDrop;
  172. public
  173. constructor Create(AOwner: TDragDrop);
  174. destructor Destroy; override;
  175. function QueryContinueDrag(fEscapePressed: BOOL;
  176. grfKeyState: Longint): HResult; stdcall;
  177. function GiveFeedback(dwEffect: Longint): HResult; stdcall;
  178. end;
  179. TDropTarget = class(TDDInterfacedObject, IDropTarget)
  180. private
  181. FAccept:boolean;
  182. HorzStartTimer:TTimer;
  183. HorzScrollTimer:TTimer;
  184. VertStartTimer:TTimer;
  185. VertScrollTimer:TTimer;
  186. FVScrollCode:integer;
  187. FHScrollCode:integer;
  188. procedure InitScroll(VerticalScroll:boolean; ScrollCode:integer);
  189. procedure TermScroll(VerticalScroll:boolean);
  190. procedure DetermineScrollDir(VertScrolling:boolean; var ScrollCode:integer);
  191. procedure OnStartTimer(Sender: TObject);
  192. procedure OnScrollTimer(Sender: TObject);
  193. protected
  194. FOwner: TDragDrop;
  195. procedure SuggestDropEffect(grfKeyState: Longint; var dwEffect: longint); virtual;
  196. procedure AcceptDataObject(DataObj: IDataObject; var Accept:boolean); virtual;
  197. procedure RenderDropped(DataObj: IDataObject; grfKeyState: Longint; pt: TPoint;
  198. var dwEffect: longint); virtual;
  199. public
  200. constructor Create(AOwner: TDragDrop);
  201. destructor Destroy; override;
  202. function DragEnter(const dataObj: IDataObject; grfKeyState: Longint;
  203. pt: TPoint; var dwEffect: Longint): HResult; stdcall;
  204. function DragOver(grfKeyState: Longint; pt: TPoint;
  205. var dwEffect: Longint): HResult; stdcall;
  206. function DragLeave: HResult; stdcall;
  207. function Drop(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint;
  208. var dwEffect: Longint): HResult; stdcall;
  209. end;
  210. // custom properties
  211. TScrollDetectArea = class(TPersistent)
  212. private
  213. FControl: TPersistent;
  214. FMargin: word;
  215. FRange: word;
  216. FOnChange: TNotifyEvent;
  217. procedure SetValue(Index: Integer; Value: word);
  218. protected
  219. procedure Change; dynamic;
  220. procedure AssignTo(Dest: TPersistent); override;
  221. property Control: TPersistent read FControl;
  222. public
  223. constructor Create(Control: TPersistent);
  224. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  225. published
  226. property Margin: word index 0 read FMargin write SetValue default 0;
  227. property Range: word index 1 read FRange write SetValue default 10;
  228. end;
  229. TScrollDetectOptions = class(TPersistent)
  230. private
  231. FControl: TDragDrop;
  232. FScrollDelay: TScrollInterval;
  233. FStartDelay: TScrollInterval;
  234. FLeft: TScrollDetectArea;
  235. FTop: TScrollDetectArea;
  236. FRight: TScrollDetectArea;
  237. FBottom: TScrollDetectArea;
  238. FOnChange: TNotifyEvent;
  239. FHorzScrolling:boolean;
  240. FVertScrolling:boolean;
  241. FHorzPageScroll:boolean;
  242. FVertPageScroll:boolean;
  243. procedure SetValue(index:integer; Value: TScrollInterval);
  244. protected
  245. procedure Change; dynamic;
  246. procedure AssignTo(Dest: TPersistent); override;
  247. property Control: TDragDrop read FControl;
  248. public
  249. constructor Create(Control: TDragDrop);
  250. destructor Destroy; override;
  251. property OnChange: TNotifyEvent read FOnChange write FOnChange;
  252. published
  253. property ScrollDelay: TScrollInterval index 0 read FScrollDelay write SetValue default 100;
  254. property StartDelay: TScrollInterval index 1 read FStartDelay write SetValue default 750;
  255. property AreaLeft: TScrollDetectArea read FLeft write FLeft;
  256. property AreaTop: TScrollDetectArea read FTop write FTop;
  257. property AreaRight: TScrollDetectArea read FRight write FRight;
  258. property AreaBottom: TScrollDetectArea read FBottom write FBottom;
  259. property HorzScrolling:boolean read FHorzScrolling write FHorzScrolling default false;
  260. property VertScrolling:boolean read FVertScrolling write FVertScrolling default false;
  261. property HorzPageScroll:boolean read FHorzPageScroll write FHorzPageScroll default false;
  262. property VertPageScroll:boolean read FVertPageScroll write FVertPageScroll default false;
  263. end;
  264. // *THE* pseudo-visual Component
  265. TDragDrop = class(TComponent)
  266. private
  267. FAutoDetectDnD:boolean;
  268. FDragDetectDelta:byte;
  269. FAcceptOwnDnD:boolean;
  270. FBTF:Boolean;
  271. FContextMenu: boolean;
  272. FDragDropControl: TWinControl;
  273. FRegistered: Boolean;
  274. FOwnerIsSource:boolean;
  275. FShowPopUpMenu: boolean;
  276. FTargetEffectsSet: TDropEffectSet;
  277. FTargetEffects: longint;
  278. FOnQueryContinueDrag: TOnQueryContinueDrag;
  279. FOnGiveFeedback: TOnGiveFeedback;
  280. FOnDragEnter: TOnDragEnter;
  281. FOnDragLeave: TOnDragLeave;
  282. FOnDragOver: TOnDragOver;
  283. FOnDrop: TOnDrop;
  284. FSourceEffectsSet: TDropEffectSet;
  285. FSourceEffects: longint;
  286. FOnProcessDropped: TOnProcessDropped;
  287. OldWndProc:Pointer;
  288. WndProcPtr:Pointer;
  289. FOnDragDetect:TOnDragDetect;
  290. FDragDetectStatus:TDragDetectStatus;
  291. FDragDetectStart:TPoint;
  292. FRenderDataOn: TRenderDataOn;
  293. FDataObj:IDataObject;
  294. FgrfKeyState: Longint;
  295. Fpt: TPoint;
  296. FdwEffect: Longint;
  297. FCHCopy: HCursor;
  298. FCHMove: HCursor;
  299. FCHLink: HCursor;
  300. FCHScrollCopy: HCursor;
  301. FCHScrollMove: HCursor;
  302. FCHScrollLink: HCursor;
  303. FMessageHooked:boolean;
  304. FAvailableDropEffects:Longint;
  305. FTargetScrolling:integer;
  306. FSrcCompatibilityCheck:TSrcCompatibilityCheckSet;
  307. FScrollDetectOptions: TScrollDetectOptions;
  308. FOnBeforeScrolling: TOnBeforeScrolling;
  309. FOnAfterScrolling: TNotifyEvent;
  310. FPressedButton:integer;
  311. FInternalSource:TDragDrop;
  312. FOnMenuPopup:TOnMenuPopup;
  313. FOnMenuExecCmd:TOnMenuExecCmd;
  314. FOnMenuDestroy:TOnMenuDestroy;
  315. FOnMenuSucceeded:TOnProcessDropped;
  316. FOnDropHandlerSucceeded:TOnProcessDropped;
  317. procedure WndMethod(var Msg: TMessage);
  318. procedure SetDragDropControl(WinControl: TWinControl);
  319. procedure SetSourceEffects(Values:TDropEffectSet);
  320. procedure SetTargetEffects(Values:TDropEffectSet);
  321. protected
  322. FDropTarget: TDropTarget;
  323. procedure Loaded; override;
  324. procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  325. function CreateDataObject:TDataObject; virtual; abstract;
  326. procedure DoMenuPopup(Sender: TObject; AMenu: HMenu; DataObj: IDataObject;
  327. AMinCustCmd:integer; grfKeyState: Longint; pt: TPoint); virtual;
  328. function DoMenuExecCmd(Sender: TObject; AMenu: HMenu; DataObj:IDataObject;
  329. Command:integer; var dwEffect: longint):boolean; virtual;
  330. procedure DoMenuDestroy(Sender:TObject; AMenu: HMenu); virtual;
  331. function DropHandler(const dataObj: IDataObject; grfKeyState: Longint;
  332. pt: TPoint; var dwEffect: Longint): boolean; virtual;
  333. property OnDropHandlerSucceeded:TOnProcessDropped read FOnDropHandlerSucceeded
  334. write FOnDropHandlerSucceeded;
  335. public
  336. constructor Create(AOwner: TComponent); override;
  337. destructor Destroy; override;
  338. function RegisterTarget: Boolean;
  339. function UnRegisterTarget: Boolean;
  340. procedure HookMessageHandler;
  341. procedure UnhookMessageHandler(ForceUnhook:boolean);
  342. function ExecuteOperation(DataObject:TDataObject): TDragResult;
  343. function Execute: TDragResult;
  344. function CopyToClipboard:boolean; virtual;
  345. function GetFromClipboard:boolean; virtual;
  346. procedure StartDnDDetection(Button: TMouseButton); virtual;
  347. property OwnerIsSource:boolean read FOwnerIsSource;
  348. property Registered: Boolean read FRegistered default False;
  349. property CHCopy: HCursor read FCHCopy write FCHCopy default DefaultCursor;
  350. property CHMove: HCursor read FCHMove write FCHMove default DefaultCursor;
  351. property CHLink: HCursor read FCHLink write FCHLink default DefaultCursor;
  352. property CHScrollCopy: HCursor read FCHScrollCopy write FCHScrollCopy default DefaultCursor;
  353. property CHScrollMove: HCursor read FCHScrollMove write FCHScrollMove default DefaultCursor;
  354. property CHScrollLink: HCursor read FCHScrollLink write FCHScrollLink default DefaultCursor;
  355. property DragDetectStatus: TDragDetectStatus read FDragDetectStatus;
  356. property AvailableDropEffects: Longint read FAvailableDropEffects;
  357. property InternalSource:TDragDrop read FInternalSource;
  358. published
  359. property AcceptOwnDnD:boolean read FAcceptOwnDnD write FAcceptOwnDnD;
  360. property AutoDetectDnD:boolean read FAutoDetectDnD write FAutoDetectDnD;
  361. property BringToFront:Boolean read FBTF write FBTF;
  362. property DragDetectDelta:byte read FDragDetectDelta write FDragDetectDelta default 10;
  363. property DragDropControl: TWinControl read FDragDropControl write SetDragDropControl;
  364. property RenderDataOn: TRenderDataOn read FRenderDataOn write FRenderDataOn default rdoDropSync;
  365. property ScrollDetectOptions: TScrollDetectOptions read FScrollDetectOptions
  366. write FScrollDetectOptions;
  367. property SourceCompatibility:TSrcCompatibilityCheckSet read FSrcCompatibilityCheck
  368. write FSrcCompatibilityCheck;
  369. property SourceEffects: TDropEffectSet read FSourceEffectsSet write SetSourceEffects;
  370. property TargetPopupMenu: boolean read FShowPopUpMenu write FShowPopUpMenu;
  371. property TargetEffects: TDropEffectSet read FTargetEffectsSet write SetTargetEffects;
  372. property OnAfterScrolling: TNotifyEvent read FOnAfterScrolling write FOnAfterScrolling;
  373. property OnBeforeScrolling: TOnBeforeScrolling read FOnBeforeScrolling write FOnBeforeScrolling;
  374. property OnDragDetect: TOnDragDetect read FOnDragDetect write FOnDragDetect;
  375. property OnDragEnter: TOnDragEnter read FOnDragEnter write FOnDragEnter;
  376. property OnDragLeave: TOnDragLeave read FOnDragLeave write FOnDragLeave;
  377. property OnDragOver: TOnDragOver read FOnDragOver write FOnDragOver;
  378. property OnDrop: TOnDrop read FOnDrop write FOnDrop;
  379. property OnQueryContinueDrag: TOnQueryContinueDrag read FOnQueryContinueDrag
  380. write FOnQueryContinueDrag;
  381. property OnGiveFeedback: TOnGiveFeedback read FOnGiveFeedback
  382. write FOnGiveFeedback;
  383. property OnProcessDropped: TOnProcessDropped read FOnProcessDropped write FOnProcessDropped;
  384. property OnMenuPopup:TOnMenuPopup read FOnMenuPopup write FOnMenuPopup;
  385. property OnMenuExecCmd:TOnMenuExecCmd read FOnMenuExecCmd write FOnMenuExecCmd;
  386. property OnMenuDestroy:TOnMenuDestroy read FOnMenuDestroy write FOnMenuDestroy;
  387. property OnMenuSucceeded:TOnProcessDropped read FOnMenuSucceeded write FOnMenuSucceeded;
  388. end;
  389. procedure Register;
  390. resourcestring
  391. MICopyStr = '&Copy Here';
  392. MIMoveStr = '&Move Here';
  393. MILinkStr = '&Shortcut(s) Create Here';
  394. MIAbortStr = '&Abort';
  395. implementation
  396. const CmdAbort = 0;
  397. CmdMove = 1;
  398. CmdCopy = 2;
  399. CmdLink = 3;
  400. CmdSeparator = 4;
  401. MinCustCmd = 10;
  402. var DDM_ProcessDropped:DWord; // Never change its value
  403. MouseHookHandle:HHook;
  404. MouseHookDragDrop:TDragDrop;
  405. GInternalSource:TDragDrop;
  406. function MouseHookProc(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT; stdcall;
  407. var MouseHookStruct:TMouseHookStruct;
  408. grfKeyState:Longint;
  409. begin
  410. Result:=CallNextHookEx(MouseHookHandle,Code,wParam,lParam);
  411. if assigned(MouseHookDragDrop)=false then
  412. begin
  413. UnHookWindowsHookEx(MouseHookHandle);
  414. MouseHookHandle:=0;
  415. exit;
  416. end;
  417. with MouseHookDragDrop do
  418. begin
  419. MouseHookStruct:=TMouseHookStruct(pointer(lparam)^);
  420. if ((FDragDetectStatus=ddsRight) and (wParam=WM_LBUTTONDOWN)) or
  421. ((FDragDetectStatus=ddsLeft) and (wParam=WM_RBUTTONDOWN)) then
  422. begin
  423. FPressedButton:=2;
  424. FDragDetectStatus:=ddsCancelled;
  425. if assigned(FOnDragDetect) then
  426. begin
  427. if HiWord(DWord(GetKeyState(VK_SHIFT)))<>0 then
  428. grfKeyState:=MK_SHIFT
  429. else grfKeyState:=0;
  430. if HiWord(DWord(GetKeyState(VK_CONTROL)))<>0 then
  431. grfKeyState:=grfKeyState or MK_CONTROL;
  432. FOnDragDetect(grfKeyState,
  433. FDragDropControl.ScreenToClient(FDragDetectStart),
  434. FDragDropControl.ScreenToClient(MouseHookStruct.pt),
  435. FDragDetectStatus);
  436. end;
  437. exit;
  438. end;
  439. if ((wParam=WM_LBUTTONDOWN) or (wParam=WM_RBUTTONDOWN)) and
  440. (FDragDetectStatus=ddsCancelled) then
  441. begin
  442. FPressedButton:=2;
  443. exit;
  444. end;
  445. if (FDragDetectStatus=ddsCancelled) and
  446. ((wParam=WM_LBUTTONUP) or (wParam=WM_RBUTTONUP)) then
  447. begin
  448. dec(FPressedButton);
  449. if FPressedButton<=0 then
  450. begin
  451. UnHookWindowsHookEx(MouseHookHandle);
  452. MouseHookHandle:=0;
  453. FDragDetectStatus:=ddsNone;
  454. if assigned(FOnDragDetect) then
  455. begin
  456. if HiWord(DWord(GetKeyState(VK_SHIFT)))<>0 then
  457. grfKeyState:=MK_SHIFT
  458. else grfKeyState:=0;
  459. if HiWord(DWord(GetKeyState(VK_CONTROL)))<>0 then
  460. grfKeyState:=grfKeyState or MK_CONTROL;
  461. FOnDragDetect(grfKeyState,
  462. FDragDropControl.ScreenToClient(FDragDetectStart),
  463. FDragDropControl.ScreenToClient(MouseHookStruct.pt),
  464. FDragDetectStatus);
  465. end;
  466. end;
  467. exit;
  468. end;
  469. if ((FDragDetectStatus=ddsRight) and (wParam=WM_RBUTTONUP)) or
  470. ((FDragDetectStatus=ddsLeft) and (wParam=WM_LBUTTONUP)) then
  471. begin
  472. UnHookWindowsHookEx(MouseHookHandle);
  473. MouseHookHandle:=0;
  474. FDragDetectStatus:=ddsNone;
  475. if assigned(FOnDragDetect) then
  476. begin
  477. if HiWord(DWord(GetKeyState(VK_SHIFT)))<>0 then
  478. grfKeyState:=MK_SHIFT
  479. else grfKeyState:=0;
  480. if HiWord(DWord(GetKeyState(VK_CONTROL)))<>0 then
  481. grfKeyState:=grfKeyState or MK_CONTROL;
  482. FOnDragDetect(grfKeyState,
  483. FDragDropControl.ScreenToClient(FDragDetectStart),
  484. FDragDropControl.ScreenToClient(MouseHookStruct.pt),
  485. FDragDetectStatus);
  486. end;
  487. exit;
  488. end;
  489. if ((abs(FDragDetectStart.X-MouseHookStruct.pt.x)>DragDetectDelta) or
  490. (abs(FDragDetectStart.Y-MouseHookStruct.pt.y)>DragDetectDelta)) and
  491. ((FDragDetectStatus=ddsRight) or (FDragDetectStatus=ddsLeft)) then
  492. begin
  493. FDragDetectStatus:=ddsDrag;
  494. UnHookWindowsHookEx(MouseHookHandle);
  495. MouseHookHandle:=0;
  496. if assigned(FOnDragDetect) then
  497. begin
  498. if HiWord(DWord(GetKeyState(VK_SHIFT)))<>0 then
  499. grfKeyState:=MK_SHIFT
  500. else grfKeyState:=0;
  501. if HiWord(DWord(GetKeyState(VK_CONTROL)))<>0 then
  502. grfKeyState:=grfKeyState or MK_CONTROL;
  503. FOnDragDetect(grfKeyState,
  504. FDragDropControl.ScreenToClient(FDragDetectStart),
  505. FDragDropControl.ScreenToClient(MouseHookStruct.pt),
  506. FDragDetectStatus);
  507. end;
  508. if (FDragDetectStatus<>ddsNone) then
  509. begin
  510. FDragDetectStatus:=ddsNone;
  511. if assigned(FOnDragDetect) then
  512. begin
  513. if HiWord(DWord(GetKeyState(VK_SHIFT)))<>0 then
  514. grfKeyState:=MK_SHIFT
  515. else grfKeyState:=0;
  516. if HiWord(DWord(GetKeyState(VK_CONTROL)))<>0 then
  517. grfKeyState:=grfKeyState or MK_CONTROL;
  518. FOnDragDetect(grfKeyState,
  519. FDragDropControl.ScreenToClient(FDragDetectStart),
  520. FDragDropControl.ScreenToClient(MouseHookStruct.pt),
  521. FDragDetectStatus);
  522. end;
  523. end;
  524. end;
  525. end;
  526. end;
  527. // TFormatEtcList --------------------------------------------------------------
  528. constructor TFormatEtcList.Create;
  529. begin
  530. inherited Create;
  531. FCount:=0;
  532. SetLength(FList, 0);
  533. end;
  534. destructor TFormatEtcList.Destroy;
  535. begin
  536. if (FCount>0) and (FList<>nil) then SetLength(FList, 0);
  537. inherited Destroy;
  538. end;
  539. function TFormatEtcList.Get(Index: Integer): TFormatEtc;
  540. begin
  541. if (Index>=FCount) or (FList=nil) then
  542. raise EListError.Create('Invalid item index')
  543. else Result:=FList[Index];
  544. end;
  545. procedure TFormatEtcList.Put(Index: Integer; Item: TFormatEtc);
  546. begin
  547. if (Index>=FCount) or (FList=nil) then
  548. raise EListError.Create('Invalid item index')
  549. else FList[Index]:=Item;
  550. end;
  551. function TFormatEtcList.Add(Item: TFormatEtc):integer;
  552. begin
  553. SetLength(FList, Succ(FCount));
  554. FList[FCount]:=Item;
  555. Result:=FCount;
  556. inc(FCount);
  557. end;
  558. procedure TFormatEtcList.Clear;
  559. begin
  560. SetLength(Flist, 0);
  561. FCount:=0;
  562. end;
  563. function TFormatEtcList.Clone:TFormatEtcList;
  564. var FEL:TFormatEtcList;
  565. begin
  566. FEL:=TFormatEtcList.Create;
  567. if FList<>nil then
  568. begin
  569. SetLength(FEL.FList, FCount);
  570. CopyMemory(FEL.FList,FList,FCount*SizeOf(TFormatEtc));
  571. FEL.FCount:=FCount;
  572. end;
  573. Result:=FEL;
  574. end;
  575. procedure TFormatEtcList.Delete(Index: Integer);
  576. var movecount:integer;
  577. begin
  578. if (Index>=FCount) or (FList=nil) then
  579. raise EListError.Create('Invalid item index')
  580. else
  581. begin
  582. movecount:=FCount-Index-1;
  583. System.move(FList[Index+1],FList[Index],movecount*sizeof(TFormatEtc));
  584. dec(FCount);
  585. SetLength(FList, FCount);
  586. end;
  587. end;
  588. // TDDInterfacedObject ---------------------------------------------------------
  589. function TDDInterfacedObject.QueryInterface(const IID: TGUID; out Obj): HResult;
  590. begin
  591. Result:=inherited QueryInterface(IID,Obj);
  592. end;
  593. function TDDInterfacedObject._AddRef: Integer;
  594. begin
  595. Result:=inherited _AddRef;
  596. end;
  597. function TDDInterfacedObject._Release: Integer;
  598. begin
  599. Result:=inherited _Release;
  600. end;
  601. // TEnumFormatEtc --------------------------------------------------------------
  602. constructor TEnumFormatEtc.Create(FormatEtcList:TFormatEtcList);
  603. begin
  604. inherited Create;
  605. _AddRef;
  606. FFormatEtcList:=FormatEtcList;
  607. end;
  608. destructor TEnumFormatEtc.Destroy;
  609. begin
  610. if Assigned(FFormatEtcList) then FFormatEtcList.Free;
  611. inherited Destroy;
  612. end;
  613. function TEnumFormatEtc.Next(celt: Longint; out elt;
  614. pceltFetched: PLongint): HResult;
  615. var copycount:integer;
  616. begin
  617. Result:=S_False;
  618. if pceltFetched<>nil then pceltFetched^:=0;
  619. if (celt<=0) or (FFormatEtcList.Count=0) or (FIndex>=FFormatEtcList.Count) or
  620. ((pceltFetched=nil) and (celt<>1)) then exit;
  621. copycount:=FFormatEtcList.Count-FIndex;
  622. if celt<copycount then copycount:=celt;
  623. if pceltFetched<>nil then pceltFetched^:=copycount;
  624. CopyMemory(@TFormatEtc(elt),@TFormatEtc(FFormatEtcList.FList[FIndex]),
  625. copycount*sizeof(TFormatEtc));
  626. inc(FIndex,copycount);
  627. Result:=S_OK;
  628. end;
  629. function TEnumFormatEtc.Skip(celt: Longint): HResult;
  630. begin
  631. if (FIndex+celt<=FFormatEtcList.Count) then
  632. begin
  633. inc(FIndex,celt);
  634. Result:=S_Ok;
  635. end
  636. else Result:=S_False;
  637. end;
  638. function TEnumFormatEtc.Reset: HResult;
  639. begin
  640. FIndex:=0;
  641. Result:=S_OK;
  642. end;
  643. function TEnumFormatEtc.Clone(out Enum: IEnumFormatEtc): HResult;
  644. begin
  645. Result:=S_OK;
  646. try
  647. Enum:=TEnumFormatEtc.Create(FFormatEtcList);
  648. TEnumFormatEtc(Enum).FIndex := FIndex;
  649. except
  650. Result:=E_Fail;
  651. end;
  652. end;
  653. // TDataObject -----------------------------------------------------------------
  654. constructor TDataObject.Create;
  655. begin
  656. inherited Create;
  657. _AddRef;
  658. FFormatEtcList:=TFormatEtcList.Create;
  659. end;
  660. destructor TDataObject.Destroy;
  661. begin
  662. FFormatEtcList.Free;
  663. inherited Destroy;
  664. end;
  665. function TDataObject.GetData(const formatetcIn: TFormatEtc; out medium: TStgMedium):
  666. HResult;
  667. var i:integer;
  668. Cursor:TCursor;
  669. begin
  670. try
  671. if FFormatEtcList.Count>0 then
  672. for i:=0 to FFormatEtcList.Count-1 do
  673. if (formatetcIn.tymed and FFormatEtcList.Items[i].tymed<>0) and
  674. ((FCheckLindex=false) or (FCheckLindex and
  675. (formatetcIn.lindex=FFormatEtcList.Items[i].lindex))) and
  676. ((FCheckdwAspect=false) or (FCheckdwAspect and
  677. (formatetcIn.dwAspect=FFormatEtcList.Items[i].dwAspect))) and
  678. (formatetcIn.cfFormat=FFormatEtcList.Items[i].cfFormat) then
  679. begin
  680. Cursor:=Screen.Cursor;
  681. try
  682. Screen.Cursor:=crHourglass;
  683. Result:=RenderData(formatetcIn,medium);
  684. finally
  685. Screen.Cursor:=Cursor;
  686. end;
  687. exit;
  688. end;
  689. Result:=DV_E_FormatEtc;
  690. except
  691. medium.HGlobal:=0;
  692. Result:=E_Fail;
  693. end;
  694. end;
  695. function TDataObject.GetDataHere(const formatetc: TFormatEtc; out medium: TStgMedium):
  696. HResult;
  697. begin
  698. Result:=E_NOTIMPL;
  699. end;
  700. function TDataObject.GetCanonicalFormatEtc(const formatetc: TFormatEtc;
  701. out formatetcOut: TFormatEtc): HResult;
  702. begin
  703. Result:=E_NOTIMPL;
  704. end;
  705. function TDataObject.QueryGetData(const formatetc: TFormatEtc): HResult;
  706. const DVError:array[0..3] of HResult=(DV_E_FORMATETC,DV_E_TYMED,DV_E_DVASPECT,DV_E_LINDEX);
  707. var i,j:integer;
  708. begin
  709. j:=0;
  710. if (FFormatEtcList.Count>0) and AllowData(FormatEtc) then
  711. for i:=0 to FFormatEtcList.Count-1 do
  712. if FormatEtc.cfFormat=FFormatEtcList.Items[i].cfFormat then
  713. begin
  714. if FormatEtc.tymed and FFormatEtcList.Items[i].tymed<>0 then
  715. begin
  716. if FormatEtc.dwAspect=FFormatEtcList.Items[i].dwAspect then
  717. begin
  718. if FormatEtc.lindex=FFormatEtcList.Items[i].lindex then
  719. begin
  720. Result:=S_OK;
  721. exit;
  722. end
  723. else if j<3 then j:=3;
  724. end
  725. else if j<2 then j:=2;
  726. end
  727. else if j<1 then j:=1;
  728. end;
  729. Result:=DVError[j];
  730. end;
  731. function TDataObject.AllowData(FormatEtc: TFormatEtc): Boolean;
  732. begin
  733. Result := True;
  734. end;
  735. function TDataObject.EnumFormatEtc(dwDirection: Longint; out enumFormatEtc:
  736. IEnumFormatEtc): HResult;
  737. begin
  738. Result:=E_Fail;
  739. if dwDirection=DATADIR_GET then
  740. begin
  741. EnumFormatEtc:=TEnumFormatEtc.Create(FFormatEtcList.Clone);
  742. Result:=S_OK;
  743. end
  744. else EnumFormatEtc:=nil;
  745. if EnumFormatEtc=nil then Result:=OLE_S_USEREG;
  746. end;
  747. function TDataObject.SetData(const formatetc: TFormatEtc; var medium: TStgMedium;
  748. fRelease: BOOL): HResult;
  749. var i:integer;
  750. AddData:boolean;
  751. begin
  752. Result:=E_Fail;
  753. if FRelease then exit;
  754. AddData:=true;
  755. if FFormatEtcList.Count>0 then
  756. for i:=0 to FFormatEtcList.Count-1 do
  757. if FFormatEtcList.Items[i].cfFormat=FormatEtc.cfFormat then
  758. begin
  759. AddData:=false;
  760. FFormatEtcList.Items[i]:=FormatEtc;
  761. end;
  762. if AddData then
  763. FFormatEtcList.Add(FormatEtc);
  764. end;
  765. function TDataObject.DAdvise(const formatetc: TFormatEtc; advf: Longint;
  766. const advSink: IAdviseSink; out dwConnection: Longint): HResult;
  767. begin
  768. Result:=E_NOTIMPL;
  769. end;
  770. function TDataObject.DUnadvise(dwConnection: longint): HResult; stdcall;
  771. begin
  772. Result:=E_NOTIMPL;
  773. end;
  774. function TDataObject.EnumDAdvise(out enumAdvise: IEnumStatData): HResult;
  775. begin
  776. Result:=OLE_E_AdviseNotSupported;
  777. end;
  778. // TDropSource methods ---------------------------------------------------------
  779. constructor TDropSource.Create(AOwner: TDragDrop);
  780. begin
  781. inherited Create;
  782. _AddRef;
  783. FOwner:=AOwner;
  784. end;
  785. destructor TDropSource.Destroy;
  786. begin
  787. inherited Destroy;
  788. end;
  789. function TDropSource.QueryContinueDrag(fEscapePressed: BOOL;
  790. grfKeyState: Longint): HResult; stdcall;
  791. // Determines whether a drag-and-drop operation should be continued, cancelled,
  792. // or completed. You do not call this method directly. The OLE DoDragDrop function
  793. // calls this method during a drag-and-drop operation.
  794. begin
  795. // Abort drag-and-drop?
  796. if (((grfKeyState and MK_LBUTTON)<>0) and
  797. ((grfKeyState and MK_RBUTTON)<>0)) or fEscapePressed then
  798. begin
  799. Result:=DRAGDROP_S_CANCEL;
  800. FOwner.FOwnerIsSource:=false;
  801. end
  802. // Finish drag-and-drop?
  803. else if (((grfKeyState and MK_LBUTTON)=0) and
  804. ((grfKeyState and MK_RBUTTON)=0)) then Result:=DRAGDROP_S_DROP
  805. else Result:=S_OK;
  806. if assigned(FOwner.FOnQueryContinueDrag) then
  807. FOwner.FOnQueryContinueDrag(fEscapePressed,grfKeyState,Result);
  808. end;
  809. function TDropSource.GiveFeedback(dwEffect: Longint): HResult; stdcall;
  810. // Enables a source application to give visual feedback to its end user
  811. // during a drag-and-drop operation by providing the DoDragDrop function
  812. // with an enumeration value specifying the visual effect.
  813. var HC: HCursor;
  814. begin
  815. if Assigned(FOwner.FOnGiveFeedback) then FOwner.FOnGiveFeedback(dwEffect,Result);
  816. if dwEffect and DROPEFFECT_SCROLL<>0 then
  817. begin
  818. if dwEffect and DROPEFFECT_LINK<>0 then HC:=FOwner.FCHScrollLink
  819. else if dwEffect and DROPEFFECT_Move<>0 then HC:=FOwner.FCHScrollMove
  820. else if dwEffect and DROPEFFECT_COPY<>0 then HC:=FOwner.FCHScrollCopy
  821. else HC:=DefaultCursor;
  822. end
  823. else if dwEffect and DROPEFFECT_LINK<>0 then HC:=FOwner.FCHLink
  824. else if dwEffect and DROPEFFECT_Move<>0 then HC:=FOwner.FCHMove
  825. else if dwEffect and DROPEFFECT_COPY<>0 then HC:=FOwner.FCHCopy
  826. else HC:=DefaultCursor;
  827. if HC=DefaultCursor then
  828. begin
  829. Result:=DRAGDROP_S_USEDEFAULTCURSORS
  830. end
  831. else
  832. begin
  833. Result:=S_Ok;
  834. Windows.SetCursor(HC);
  835. end;
  836. end;
  837. // TDropTarget interface -------------------------------------------------------
  838. constructor TDropTarget.Create(AOwner: TDragDrop);
  839. begin
  840. inherited Create;
  841. FOwner:=AOwner;
  842. _AddRef;
  843. HorzStartTimer:=TTimer.Create(FOwner);
  844. HorzStartTimer.Enabled:=false;
  845. HorzStartTimer.OnTimer:=OnStartTimer;
  846. HorzScrollTimer:=TTimer.Create(FOwner);
  847. HorzScrollTimer.Enabled:=false;
  848. HorzScrollTimer.OnTimer:=OnScrollTimer;
  849. VertStartTimer:=TTimer.Create(FOwner);
  850. VertStartTimer.Enabled:=false;
  851. VertStartTimer.OnTimer:=OnStartTimer;
  852. VertScrollTimer:=TTimer.Create(FOwner);
  853. VertScrollTimer.Enabled:=false;
  854. VertScrollTimer.OnTimer:=OnScrollTimer;
  855. FVScrollCode:=0;
  856. FHScrollCode:=0;
  857. end;
  858. destructor TDropTarget.Destroy;
  859. begin
  860. HorzStartTimer.Free;
  861. HorzScrollTimer.Free;
  862. VertStartTimer.Free;
  863. VertScrollTimer.Free;
  864. inherited Destroy;
  865. end;
  866. procedure TDropTarget.InitScroll(VerticalScroll:boolean; ScrollCode:integer);
  867. begin
  868. TermScroll(VerticalScroll);
  869. if VerticalScroll then
  870. begin
  871. VertStartTimer.Interval:=FOwner.FScrollDetectOptions.FStartDelay;
  872. VertStartTimer.Enabled:=true;
  873. FVScrollCode:=ScrollCode;
  874. end
  875. else
  876. begin
  877. HorzStartTimer.Interval:=FOwner.FScrollDetectOptions.FStartDelay;
  878. HorzStartTimer.Enabled:=true;
  879. FHScrollCode:=ScrollCode;
  880. end;
  881. end;
  882. procedure TDropTarget.TermScroll(VerticalScroll:boolean);
  883. begin
  884. if VerticalScroll then
  885. begin
  886. VertStartTimer.Enabled:=false;
  887. if VertScrollTimer.Enabled then
  888. sendmessage(FOwner.DragDropControl.handle,WM_VScroll,SB_ENDSCROLL,0);
  889. VertScrollTimer.Enabled:=false;
  890. FVScrollCode:=0;
  891. end
  892. else
  893. begin
  894. HorzStartTimer.Enabled:=false;
  895. if HorzScrollTimer.Enabled then
  896. sendmessage(FOwner.DragDropControl.handle,WM_HScroll,SB_ENDSCROLL,0);
  897. HorzScrollTimer.Enabled:=false;
  898. FHScrollCode:=0;
  899. end;
  900. end;
  901. procedure TDropTarget.DetermineScrollDir(VertScrolling:boolean;
  902. var ScrollCode:integer);
  903. var p1m,p1r,p2m,p2r:integer;
  904. ptmc:TPoint;
  905. SCROLLINFO:TSCROLLINFO;
  906. begin
  907. GetCursorPos(ptmc);
  908. ptmc:=FOwner.DragDropControl.ScreenToClient(ptmc);
  909. if VertScrolling then
  910. begin
  911. // Checking vertical scroll areas ...
  912. // If the vertical scroll areas intersect, we don't allow scrolling
  913. p1m:=FOwner.FScrollDetectOptions.AreaTop.Margin;
  914. p1r:=p1m+FOwner.ScrollDetectOptions.AreaTop.Range;
  915. p2m:=FOwner.DragDropControl.ClientHeight-1-
  916. FOwner.ScrollDetectOptions.AreaBottom.Margin;
  917. p2r:=p2m-FOwner.ScrollDetectOptions.AreaBottom.Range;
  918. if (p1r<p2r) then
  919. begin
  920. if (p1m<=ptmc.y) and (p1r>=ptmc.y) then ScrollCode:=1
  921. else if (p2m>=ptmc.y) and (p2r<=ptmc.y) then ScrollCode:=2
  922. else ScrollCode:=0;
  923. if ScrollCode>0 then
  924. begin
  925. ScrollInfo.cbSize := Sizeof(ScrollInfo);
  926. ScrollInfo.FMask:=SIF_PAGE or SIF_POS or SIF_RANGE;
  927. if GetScrollInfo(FOwner.DragDropControl.Handle,SB_VERT,
  928. ScrollInfo) then
  929. begin
  930. if ScrollInfo.nPage>0 then dec(ScrollInfo.nPage);
  931. if ((ScrollCode=1) and (ScrollInfo.nPos<=ScrollInfo.nMin)) or
  932. ((ScrollCode=2) and
  933. (ScrollInfo.nPos>=ScrollInfo.nMax-integer(ScrollInfo.nPage))) then
  934. ScrollCode:=0;
  935. end
  936. else ScrollCode:=0;
  937. end;
  938. end
  939. else ScrollCode:=0;
  940. end
  941. else
  942. begin
  943. // Checking horizontal scroll areas ...
  944. // If the horizontal scroll areas intersect, we don't allow scrolling
  945. p1m:=FOwner.FScrollDetectOptions.AreaLeft.Margin;
  946. p1r:=p1m+FOwner.ScrollDetectOptions.AreaLeft.Range;
  947. p2m:=FOwner.DragDropControl.ClientWidth-1-
  948. FOwner.ScrollDetectOptions.AreaRight.Margin;
  949. p2r:=p2m-FOwner.ScrollDetectOptions.AreaRight.Range;
  950. if (p1r<p2r) then
  951. begin
  952. if (p1m<=ptmc.x) and (p1r>=ptmc.x) then ScrollCode:=1
  953. else if (p2m>=ptmc.x) and (p2r<=ptmc.x) then ScrollCode:=2
  954. else ScrollCode:=0;
  955. if ScrollCode>0 then
  956. begin
  957. ScrollInfo.cbSize := Sizeof(ScrollInfo);
  958. ScrollInfo.FMask:=SIF_PAGE or SIF_POS or SIF_RANGE;
  959. if GetScrollInfo(FOwner.DragDropControl.Handle,SB_Horz,
  960. ScrollInfo) then
  961. begin
  962. if ScrollInfo.nPage>0 then dec(ScrollInfo.nPage);
  963. if ((ScrollCode=1) and (ScrollInfo.nPos<=ScrollInfo.nMin)) or
  964. ((ScrollCode=2) and
  965. (ScrollInfo.nPos>=ScrollInfo.nMax-integer(ScrollInfo.nPage))) then
  966. ScrollCode:=0;
  967. end
  968. else ScrollCode:=0;
  969. end;
  970. end
  971. else ScrollCode:=0;
  972. end;
  973. end;
  974. procedure TDropTarget.OnStartTimer(Sender: TObject);
  975. begin
  976. if Sender=HorzStartTimer then
  977. begin
  978. HorzStartTimer.Enabled:=false;
  979. HorzScrollTimer.Interval:=FOwner.FScrollDetectOptions.FScrollDelay;
  980. OnScrollTimer(HorzScrollTimer);
  981. HorzScrollTimer.Enabled:=true;
  982. end
  983. else
  984. begin
  985. VertStartTimer.Enabled:=false;
  986. VertScrollTimer.Interval:=FOwner.FScrollDetectOptions.FScrollDelay;
  987. OnScrollTimer(VertScrollTimer);
  988. VertScrollTimer.Enabled:=true;
  989. end;
  990. end;
  991. procedure TDropTarget.OnScrollTimer(Sender: TObject);
  992. var ScrollPage:boolean;
  993. pt:TPoint;
  994. Interval:TScrollInterval;
  995. ScrollCode,SCWParam:integer;
  996. begin
  997. Interval:=FOwner.FScrollDetectOptions.FScrollDelay;
  998. if Sender=VertScrollTimer then
  999. begin
  1000. if FOwner.FScrollDetectOptions.FVertScrolling then
  1001. begin
  1002. DetermineScrollDir(true,ScrollCode);
  1003. if ScrollCode>0 then
  1004. begin
  1005. if ((VertStartTimer.Enabled=false) and (VertScrollTimer.Enabled=false)) or
  1006. (FVScrollCode<>ScrollCode) then InitScroll(true,ScrollCode)
  1007. else
  1008. begin
  1009. ScrollPage:=FOwner.FScrollDetectOptions.FVertPageScroll;
  1010. if assigned(FOwner.FOnBeforeScrolling) then
  1011. begin
  1012. GetCursorPos(pt);
  1013. pt:=FOwner.DragDropControl.ScreenToClient(pt);
  1014. if FVScrollCode=1 then FOwner.FOnBeforeScrolling(FOwner, pt,
  1015. Interval, sdUp, ScrollPage)
  1016. else FOwner.FOnBeforeScrolling(FOwner, pt, Interval, sdDown,
  1017. ScrollPage);
  1018. end;
  1019. if ScrollPage then
  1020. begin
  1021. if FVScrollCode=1 then SCWParam:=SB_PAGEUP
  1022. else SCWParam:=SB_PAGEDOWN;
  1023. end
  1024. else
  1025. begin
  1026. if FVScrollCode=1 then SCWParam:=SB_LINEUP
  1027. else SCWParam:=SB_LINEDOWN;
  1028. end;
  1029. sendmessage(FOwner.DragDropControl.handle,WM_VScroll,SCWParam,0);
  1030. if assigned(FOwner.FOnAfterScrolling) then
  1031. FOwner.FOnAfterScrolling(FOwner);
  1032. VertScrollTimer.Interval:=Interval;
  1033. end;
  1034. end
  1035. else if FVScrollCode<>0 then TermScroll(true);
  1036. end
  1037. else if FVScrollCode<>0 then TermScroll(true);
  1038. end
  1039. else
  1040. begin
  1041. if FOwner.FScrollDetectOptions.FHorzScrolling then
  1042. begin
  1043. DetermineScrollDir(false,ScrollCode);
  1044. if ScrollCode>0 then
  1045. begin
  1046. if ((HorzStartTimer.Enabled=false) and (HorzScrollTimer.Enabled=false)) or
  1047. (FHScrollCode<>ScrollCode) then InitScroll(false,ScrollCode)
  1048. else
  1049. begin
  1050. ScrollPage:=FOwner.FScrollDetectOptions.FHorzPageScroll;
  1051. if assigned(FOwner.FOnBeforeScrolling) then
  1052. begin
  1053. GetCursorPos(pt);
  1054. pt:=FOwner.DragDropControl.ScreenToClient(pt);
  1055. if FHScrollCode=1 then FOwner.FOnBeforeScrolling(FOwner, pt,
  1056. Interval, sdLeft, ScrollPage)
  1057. else FOwner.FOnBeforeScrolling(FOwner, pt, Interval, sdRight,
  1058. ScrollPage);
  1059. end;
  1060. if ScrollPage then
  1061. begin
  1062. if FHScrollCode=1 then SCWParam:=SB_PAGELEFT
  1063. else SCWParam:=SB_PAGERIGHT;
  1064. end
  1065. else
  1066. begin
  1067. if FHScrollCode=1 then SCWParam:=SB_LINELEFT
  1068. else SCWParam:=SB_LINERIGHT;
  1069. end;
  1070. sendmessage(FOwner.DragDropControl.handle,WM_HScroll,SCWParam,0);
  1071. HorzScrollTimer.Interval:=Interval;
  1072. end;
  1073. end
  1074. else if FHScrollCode<>0 then TermScroll(false);
  1075. end
  1076. else if FHScrollCode<>0 then TermScroll(false);
  1077. end;
  1078. end;
  1079. procedure TDropTarget.SuggestDropEffect(grfKeyState: Longint; var dwEffect: longint);
  1080. begin
  1081. if (FOwner.FAcceptOwnDnD=false) and
  1082. (FOwner.FOwnerIsSource) then dwEffect:=DropEffect_None
  1083. else if (grfKeyState and MK_CONTROL=0) and (grfKeyState and MK_SHIFT<>0) and
  1084. (FOwner.FTargetEffects and DropEffect_Move<>0) then
  1085. dwEffect:=DropEffect_Move
  1086. else if (grfKeyState and MK_CONTROL<>0) and
  1087. (grfKeyState and MK_SHIFT<>0) and
  1088. (FOwner.FTargetEffects and DropEffect_Link<>0) then
  1089. dwEffect:=DropEffect_Link
  1090. else if (deCopy in FOwner.FTargetEffectsSet) and
  1091. (dwEffect and DropEffect_Copy<>0) then
  1092. dwEffect:=DropEffect_Copy
  1093. else if (deMove in FOwner.FTargetEffectsSet) and
  1094. (dwEffect and DropEffect_Move<>0) then
  1095. dwEffect:=DropEffect_Move
  1096. else if (deLink in FOwner.FTargetEffectsSet) and
  1097. (dwEffect and DropEffect_Link<>0) then
  1098. dwEffect:=DropEffect_Link
  1099. else dwEffect:=DropEffect_None;
  1100. if FOwner.FTargetScrolling<>0 then dwEffect:=dwEffect or integer(DropEffect_Scroll);
  1101. end;
  1102. procedure TDropTarget.AcceptDataObject(DataObj: IDataObject; var Accept:boolean);
  1103. begin
  1104. Accept:=true;
  1105. end;
  1106. function TDropTarget.DragEnter(const dataObj: IDataObject; grfKeyState: Longint;
  1107. pt: TPoint; var dwEffect: Longint): HResult;
  1108. // Is called if the d&d-mouse cursor moves ON (one call only) the TargeTWinControl. Here,
  1109. // you influence if a drop can be accepted and the drop's effect if accepted.
  1110. begin
  1111. TDragDrop(FOwner).FInternalSource:=GInternalSource;
  1112. FOwner.FAvailableDropEffects:=dwEffect;
  1113. FOwner.FContextMenu:=grfKeyState and mk_rbutton<>0;
  1114. if (FOwner.RenderDataOn=rdoEnter) or (FOwner.RenderDataOn=rdoEnterAndDropSync) or
  1115. (FOwner.RenderDataOn=rdoEnterAndDropAsync) then
  1116. RenderDropped(DataObj, grfKeyState, pt, dwEffect);
  1117. SuggestDropEffect(grfKeyState,dwEffect);
  1118. AcceptDataObject(DataObj, FAccept);
  1119. if Assigned(FOwner.OnDragEnter) then
  1120. FOwner.OnDragEnter(DataObj, grfKeyState,
  1121. FOwner.FDragDropControl.ScreenToClient(pt), dwEffect, FAccept);
  1122. if ((FOwner.FAcceptOwnDnD=false) and (FOwner.FOwnerIsSource)) or
  1123. (FAccept=false) then dwEffect:=DropEffect_None;
  1124. Result:= NOERROR;
  1125. end;
  1126. function TDropTarget.DragOver(grfKeyState: Longint; pt: TPoint;
  1127. var dwEffect: Longint): HResult;
  1128. // Is called if the mouse cursor moves OVER (called on every mouse move) the
  1129. // TargeTWinControl. Even here may you influence if a drop can be accepted and the
  1130. // drop's effect if accepted. Because this function is very often called YOUR
  1131. // function should be very efficient programmed.
  1132. var ScrollCode:integer;
  1133. begin
  1134. if FOwner.FScrollDetectOptions.FVertScrolling then
  1135. begin
  1136. DetermineScrollDir(true,ScrollCode);
  1137. if ScrollCode>0 then
  1138. begin
  1139. if ((VertStartTimer.Enabled=false) and (VertScrollTimer.Enabled=false)) or
  1140. (FVScrollCode<>ScrollCode) then InitScroll(true,ScrollCode);
  1141. end
  1142. else if FVScrollCode<>0 then TermScroll(true);
  1143. end
  1144. else if FVScrollCode<>0 then TermScroll(true);
  1145. if FOwner.FScrollDetectOptions.FHorzScrolling then
  1146. begin
  1147. DetermineScrollDir(false,ScrollCode);
  1148. if ScrollCode>0 then
  1149. begin
  1150. if ((HorzStartTimer.Enabled=false) and (HorzScrollTimer.Enabled=false)) or
  1151. (FHScrollCode<>ScrollCode) then InitScroll(false,ScrollCode);
  1152. end
  1153. else if FHScrollCode<>0 then TermScroll(false);
  1154. end
  1155. else if FHScrollCode<>0 then TermScroll(false);
  1156. if FAccept=false then dwEffect:=DropEffect_None;
  1157. SuggestDropEffect(grfKeyState,dwEffect);
  1158. if Assigned(FOwner.OnDragOver) then
  1159. FOwner.OnDragOver(grfKeyState, FOwner.FDragDropControl.ScreenToClient(pt),
  1160. dwEffect);
  1161. if ((FOwner.FAcceptOwnDnD=false) and (FOwner.FOwnerIsSource)) or
  1162. (FAccept=false) then dwEffect:=DropEffect_None;
  1163. Result:=NOERROR;
  1164. end;
  1165. function TDropTarget.DragLeave: HResult;
  1166. // Removes target feedback and releases the data object.
  1167. begin
  1168. TDragDrop(FOwner).FInternalSource:=nil;
  1169. if Assigned(FOwner.OnDragLeave) then FOwner.OnDragLeave;
  1170. FOwner.FAvailableDropEffects:=0;
  1171. Result:=NOERROR;
  1172. TermScroll(true);
  1173. TermScroll(false);
  1174. end;
  1175. function TDropTarget.Drop(const DataObj: IDataObject; grfKeyState: Longint; pt: TPoint;
  1176. var dwEffect: Longint): HResult;
  1177. // Instructs drop target to handle the datas which are dropped on it.
  1178. var Menu:HMenu;
  1179. Cmd:Cardinal;
  1180. mcursor:TCursor;
  1181. KeyState:integer;
  1182. function BuildMenuItemInfo(ACaption:string; ShowDefault:boolean;
  1183. ACommand:UInt; ASeparator:boolean):TMenuItemInfo;
  1184. begin
  1185. with Result do
  1186. begin
  1187. // cbSize:=SizeOf(MenuItemInfo);
  1188. cbSize:=44; //Required for Windows95
  1189. fMask:=MIIM_ID or MIIM_STATE or MIIM_TYPE;
  1190. if ASeparator then fType:=MFT_SEPARATOR
  1191. else fType:=MFT_STRING;
  1192. if ShowDefault then fState:=MFS_ENABLED or MFS_Default
  1193. else fState:=MFS_ENABLED;
  1194. wID:=ACommand;
  1195. hSubMenu:=0;
  1196. hbmpChecked:=0;
  1197. hbmpUnchecked:=0;
  1198. dwTypeData:=PChar(ACaption);
  1199. end;
  1200. end;
  1201. begin
  1202. Result:=E_Fail;
  1203. if FOwner.FContextMenu then KeyState:=grfKeyState or MK_RButton
  1204. else KeyState:=grfKeyState or MK_LButton;
  1205. if FAccept then SuggestDropEffect(KeyState,dwEffect)
  1206. else dwEffect:=DropEffect_None;
  1207. if assigned(FOwner.OnDragOver) then
  1208. FOwner.OnDragOver(KeyState, FOwner.FDragDropControl.ScreenToClient(pt),
  1209. dwEffect);
  1210. if ((FOwner.FAcceptOwnDnD=false) and (FOwner.FOwnerIsSource)) or
  1211. (FAccept=false) then dwEffect:=DropEffect_None;
  1212. TermScroll(true);
  1213. TermScroll(false);
  1214. if (FOwner.DropHandler(DataObj, KeyState, pt, dwEffect)=false) then
  1215. begin
  1216. // Show popup menu?
  1217. if FOwner.FContextMenu and FOwner.FShowPopupMenu and (dwEffect<>DropEffect_None) then
  1218. begin
  1219. Menu:=CreatePopupMenu;
  1220. if (deMove in FOwner.FTargetEffectsSet) and
  1221. (FOwner.FAvailableDropEffects and DropEffect_Move<>0) then
  1222. InsertMenuItem(Menu, DWORD(-1), true,
  1223. BuildMenuItemInfo(MIMoveStr, dwEffect and DropEffect_Move<>0,
  1224. CmdMove, false));
  1225. if (deCopy in FOwner.FTargetEffectsSet) and
  1226. (FOwner.FAvailableDropEffects and DropEffect_Copy<>0) then
  1227. InsertMenuItem(Menu, DWORD(-1), true,
  1228. BuildMenuItemInfo(MICopyStr, dwEffect and DropEffect_Copy<>0,
  1229. CmdCopy, false));
  1230. if (deLink in FOwner.FTargetEffectsSet) and
  1231. (FOwner.FAvailableDropEffects and DropEffect_Link<>0) then
  1232. InsertMenuItem(Menu, DWORD(-1), true,
  1233. BuildMenuItemInfo(MILinkStr, dwEffect and DropEffect_Link<>0,
  1234. CmdLink, false));
  1235. InsertMenuItem(Menu, DWORD(-1), true,
  1236. BuildMenuItemInfo('-', false, CmdSeparator, true));
  1237. InsertMenuItem(Menu, DWORD(-1), true,
  1238. BuildMenuItemInfo(MIAbortStr, false, CmdAbort, false));
  1239. // Add custom-menuitems ...
  1240. FOwner.DoMenuPopup(self, Menu, DataObj, MinCustCmd, KeyState, pt);
  1241. try
  1242. dwEffect:=DROPEFFECT_None;
  1243. Cmd:=Cardinal(TrackPopupMenuEx(Menu, TPM_LEFTALIGN or TPM_RIGHTBUTTON or TPM_RETURNCMD,
  1244. pt.x, pt.y, FOwner.DragDropControl.Handle, nil));
  1245. case Cmd of
  1246. CmdMove: dwEffect:=DROPEFFECT_Move;
  1247. CmdCopy: dwEffect:=DROPEFFECT_Copy;
  1248. CmdLink: dwEffect:=DROPEFFECT_Link;
  1249. CmdSeparator, CmdAbort:
  1250. dwEffect:=DROPEFFECT_None;
  1251. else // custom-menuitem was selected ...
  1252. begin
  1253. dwEffect:=DROPEFFECT_None;
  1254. if FOwner.DoMenuExecCmd(self, Menu, DataObj, Cmd, dwEffect) and
  1255. assigned(FOwner.FOnMenuSucceeded) then
  1256. FOwner.FOnMenuSucceeded(self, KeyState,
  1257. FOwner.FDragDropControl.ScreenToClient(pt), dwEffect);
  1258. end;
  1259. end;
  1260. finally
  1261. FOwner.DoMenuDestroy(Self, Menu);
  1262. DestroyMenu(Menu);
  1263. end;
  1264. end;
  1265. if assigned(FOwner.OnDrop) then
  1266. FOwner.OnDrop(DataObj, KeyState,
  1267. FOwner.FDragDropControl.ScreenToClient(pt), dwEffect);
  1268. if dwEffect<>DROPEFFECT_None then
  1269. begin
  1270. if FOwner.FBTF Then
  1271. SetForegroundWindow((FOwner.Owner As TWinControl).Handle);
  1272. TDragDrop(FOwner).FdwEffect:=dwEffect;
  1273. TDragDrop(FOwner).FgrfKeyState:=KeyState;
  1274. TDragDrop(FOwner).Fpt:=pt;
  1275. if (FOwner.RenderDataOn=rdoDropAsync) or
  1276. (FOwner.RenderDataOn=rdoEnterAndDropAsync) then
  1277. begin
  1278. TDragDrop(FOwner).FDataObj:=DataObj;
  1279. DataObj._AddRef;
  1280. end
  1281. else if (FOwner.RenderDataOn=rdoDropSync) or
  1282. (FOwner.RenderDataOn=rdoEnterAndDropSync) then
  1283. begin
  1284. // Set hourglass-cursor
  1285. mcursor:=Screen.Cursor;
  1286. Screen.Cursor:=crHourGlass;
  1287. try
  1288. RenderDropped(DataObj, KeyState, pt, dwEffect);
  1289. finally
  1290. // Set old cursor
  1291. Screen.Cursor:=mcursor;
  1292. end;
  1293. end;
  1294. PostMessage(FOwner.DragDropControl.Handle,DDM_ProcessDropped,0,0);
  1295. Result:=NOERROR;
  1296. end
  1297. else TDragDrop(FOwner).FInternalSource:=nil;
  1298. end
  1299. else
  1300. begin
  1301. TDragDrop(FOwner).FInternalSource:=nil;
  1302. if assigned(FOwner.FOnDropHandlerSucceeded) then
  1303. FOwner.FOnDropHandlerSucceeded(self, KeyState,
  1304. FOwner.FDragDropControl.ScreenToClient(pt), dwEffect);
  1305. end;
  1306. end;
  1307. procedure TDropTarget.RenderDropped(DataObj: IDataObject; grfKeyState: Longint;
  1308. pt: TPoint; var dwEffect: longint);
  1309. begin
  1310. // override, if you need ...
  1311. end;
  1312. // TScrollDetectArea methods ---------------------------------------------------
  1313. constructor TScrollDetectArea.Create(Control: TPersistent);
  1314. begin
  1315. inherited Create;
  1316. FControl:=Control;
  1317. end;
  1318. procedure TScrollDetectArea.AssignTo(Dest: TPersistent);
  1319. begin
  1320. if Dest is TScrollDetectArea then
  1321. with TScrollDetectArea(Dest) do
  1322. begin
  1323. FMargin:=Self.FMargin;
  1324. FRange:=Self.FRange;
  1325. Change;
  1326. end
  1327. else inherited AssignTo(Dest);
  1328. end;
  1329. procedure TScrollDetectArea.SetValue(Index: Integer;
  1330. Value: word);
  1331. begin
  1332. case Index of
  1333. 0: if Value<>FMargin then
  1334. begin
  1335. FMargin:=Value;
  1336. Change;
  1337. end;
  1338. 1: if Value<>FRange then
  1339. begin
  1340. FRange:=Value;
  1341. Change;
  1342. end;
  1343. end;
  1344. end;
  1345. procedure TScrollDetectArea.Change;
  1346. begin
  1347. if Assigned(FOnChange) then FOnChange(Self);
  1348. end;
  1349. // TScrollDetectOptions methods -------------------------------------------------
  1350. constructor TScrollDetectOptions.Create(Control: TDragDrop);
  1351. begin
  1352. inherited Create;
  1353. FControl:=Control;
  1354. FScrollDelay:=100;
  1355. FStartDelay:=750;
  1356. FLeft:=TScrollDetectArea.Create(self);
  1357. FLeft.Margin:=0;
  1358. FLeft.Range:=10;
  1359. FLeft.OnChange:=FOnChange;
  1360. FTop:=TScrollDetectArea.Create(self);
  1361. FTop.Margin:=0;
  1362. FTop.Range:=10;
  1363. FTop.OnChange:=FOnChange;
  1364. FRight:=TScrollDetectArea.Create(self);
  1365. FRight.Margin:=0;
  1366. FRight.Range:=10;
  1367. FRight.OnChange:=FOnChange;
  1368. FBottom:=TScrollDetectArea.Create(self);
  1369. FBottom.Margin:=0;
  1370. FBottom.Range:=10;
  1371. FBottom.OnChange:=FOnChange;
  1372. FHorzScrolling:=false;
  1373. FVertScrolling:=false;
  1374. FHorzPageScroll:=false;
  1375. FVertPageScroll:=false;
  1376. end;
  1377. destructor TScrollDetectOptions.Destroy;
  1378. begin
  1379. FLeft.Free;
  1380. FTop.Free;
  1381. FRight.Free;
  1382. FBottom.Free;
  1383. inherited Destroy;
  1384. end;
  1385. procedure TScrollDetectOptions.AssignTo(Dest: TPersistent);
  1386. begin
  1387. if Dest is TScrollDetectOptions then
  1388. with TScrollDetectOptions(Dest) do
  1389. begin
  1390. FScrollDelay:=Self.FScrollDelay;
  1391. FStartDelay:=Self.FStartDelay;
  1392. FLeft.AssignTo(Self.FLeft);
  1393. FTop.AssignTo(Self.FTop);
  1394. FRight.AssignTo(Self.FRight);
  1395. FBottom.AssignTo(Self.FBottom);
  1396. Change;
  1397. end
  1398. else inherited AssignTo(Dest);
  1399. end;
  1400. procedure TScrollDetectOptions.SetValue(index:integer; Value: TScrollInterval);
  1401. begin
  1402. if (Index=0) and (Value<>FScrollDelay) then
  1403. begin
  1404. FScrollDelay:=Value;
  1405. Change;
  1406. end;
  1407. if (Index=1) and (Value<>FStartDelay) then
  1408. begin
  1409. FStartDelay:=Value;
  1410. Change;
  1411. end;
  1412. end;
  1413. procedure TScrollDetectOptions.Change;
  1414. begin
  1415. if Assigned(FOnChange) then FOnChange(Self);
  1416. end;
  1417. // TDragDrop control ------------------------------------------------------
  1418. constructor TDragDrop.Create(AOwner: TComponent);
  1419. begin
  1420. inherited Create(AOwner);
  1421. FDropTarget:=TDropTarget.Create(Self);
  1422. FRegistered:=False;
  1423. FDragDropControl:=nil;
  1424. FBTF:=False;
  1425. FAcceptOwnDnD:=false;
  1426. FShowPopupMenu:=true;
  1427. FDragDetectDelta:=10;
  1428. FDragDetectStatus:=ddsNone;
  1429. FRenderDataOn:=rdoDropSync;
  1430. FCHCopy:=DefaultCursor;
  1431. FCHMove:=DefaultCursor;
  1432. FCHLink:=DefaultCursor;
  1433. FCHScrollCopy:=DefaultCursor;
  1434. FCHScrollMove:=DefaultCursor;
  1435. FCHScrollLink:=DefaultCursor;
  1436. FMessageHooked:=false;
  1437. FAvailableDropEffects:=0;
  1438. FTargetScrolling:=0;
  1439. FSrcCompatibilityCheck:=[CheckLindex, CheckdwAspect];
  1440. FScrollDetectOptions:=TScrollDetectOptions.Create(Self);
  1441. FInternalSource:=nil;
  1442. end;
  1443. destructor TDragDrop.Destroy;
  1444. begin
  1445. UnregisterTarget;
  1446. UnhookMessageHandler(true);
  1447. FDropTarget._Release;
  1448. FDropTarget:=nil;
  1449. FDragDropControl:=nil;
  1450. FScrollDetectOptions.Free;
  1451. inherited Destroy;
  1452. end;
  1453. procedure TDragDrop.WndMethod(var Msg: TMessage); // message-hook to receive DDM_ProcessDropped
  1454. var mcursor:TCursor;
  1455. begin
  1456. with Msg do
  1457. begin
  1458. Result:=CallWindowProc(OldWndProc, DragDropControl.Handle, Msg, wParam, LParam);
  1459. if (Msg=DDM_ProcessDropped) then
  1460. begin
  1461. if (RenderDataOn=rdoDropAsync) or (RenderDataOn=rdoEnterAndDropAsync) then
  1462. begin
  1463. // Set hourglass-cursor
  1464. mcursor:=Screen.Cursor;
  1465. Screen.Cursor:=crHourGlass;
  1466. try
  1467. FDropTarget.RenderDropped(FDataObj, FgrfKeyState, Fpt, FdwEffect);
  1468. FDataObj._Release;
  1469. finally
  1470. // Set old cursor
  1471. Screen.Cursor:=mcursor;
  1472. end;
  1473. end;
  1474. if assigned(FOnProcessDropped) then
  1475. FOnProcessDropped(self, FgrfKeyState,
  1476. FDragDropControl.ScreenToClient(Fpt), FdwEffect);
  1477. FAvailableDropEffects:=0;
  1478. FInternalSource:=nil;
  1479. end;
  1480. case Msg of
  1481. WM_Destroy:
  1482. begin
  1483. if FRegistered then
  1484. begin
  1485. CoLockObjectExternal(FDropTarget, false, false);
  1486. if (FDragDropControl.HandleAllocated=false) or
  1487. (FDragDropControl.HandleAllocated and
  1488. (RevokeDragDrop(FDragDropControl.Handle)=S_OK)) then
  1489. FRegistered:=false;
  1490. end;
  1491. FMessageHooked:=false;
  1492. end;
  1493. WM_LBUTTONDOWN, WM_RBUTTONDOWN:
  1494. begin
  1495. if FAutoDetectDnD and (FDragDetectStatus=ddsNone) and
  1496. (FSourceEffects<>0) then
  1497. begin
  1498. if Msg=WM_LBUTTONDOWN then FDragDetectStatus:=ddsLeft
  1499. else FDragDetectStatus:=ddsRight;
  1500. GetCursorPos(FDragDetectStart);
  1501. if assigned(FOnDragDetect) then
  1502. FOnDragDetect(wparam,
  1503. FDragDropControl.ScreenToClient(FDragDetectStart),
  1504. FDragDropControl.ScreenToClient(FDragDetectStart),
  1505. FDragDetectStatus);
  1506. if (MouseHookHandle<>0) then
  1507. begin // MouseHookProc is used by another component ...
  1508. UnHookWindowsHookEx(MouseHookHandle);
  1509. MouseHookHandle:=0;
  1510. if assigned(MouseHookDragDrop) then
  1511. begin
  1512. MouseHookDragDrop.FDragDetectStatus:=ddsNone;
  1513. if assigned(MouseHookDragDrop.FOnDragDetect) then
  1514. MouseHookDragDrop.FOnDragDetect(wparam,
  1515. MouseHookDragDrop.FDragDropControl.ScreenToClient(
  1516. MouseHookDragDrop.FDragDetectStart),
  1517. MouseHookDragDrop.FDragDropControl.ScreenToClient(
  1518. FDragDetectStart),
  1519. MouseHookDragDrop.FDragDetectStatus);
  1520. end;
  1521. end;
  1522. MouseHookDragDrop:=self;
  1523. MouseHookHandle:=SetWindowsHookEx(WH_MOUSE,MouseHookProc,LongWord(HInstance),0);
  1524. end;
  1525. end;
  1526. WM_HSCROLL:
  1527. if LOWORD(wParam)<>SB_ENDSCROLL then FTargetScrolling:=FTargetScrolling or 1
  1528. else FTargetScrolling:=FTargetScrolling and not 1;
  1529. WM_VSCROLL:
  1530. if LOWORD(wParam)<>SB_ENDSCROLL then FTargetScrolling:=FTargetScrolling or 2
  1531. else FTargetScrolling:=FTargetScrolling and not 2;
  1532. WM_MOUSEMOVE:
  1533. if (MouseHookHandle<>0) and (wParam and (MK_LBUTTON or MK_RBUTTON)=0) then
  1534. begin
  1535. UnHookWindowsHookEx(MouseHookHandle);
  1536. MouseHookHandle:=0;
  1537. if assigned(MouseHookDragDrop) then
  1538. begin
  1539. MouseHookDragDrop.FDragDetectStatus:=ddsNone;
  1540. if assigned(MouseHookDragDrop.FOnDragDetect) then
  1541. MouseHookDragDrop.FOnDragDetect(wparam,
  1542. MouseHookDragDrop.FDragDropControl.ScreenToClient(
  1543. MouseHookDragDrop.FDragDetectStart),
  1544. MouseHookDragDrop.FDragDropControl.ScreenToClient(
  1545. FDragDetectStart),
  1546. MouseHookDragDrop.FDragDetectStatus);
  1547. end;
  1548. MouseHookDragDrop:=nil;
  1549. end;
  1550. end;
  1551. end;
  1552. end;
  1553. procedure TDragDrop.StartDnDDetection(Button: TMouseButton);
  1554. var grfKeyState: Longint;
  1555. begin
  1556. if Button=mbLeft then FDragDetectStatus:=ddsLeft
  1557. else if Button=mbRight then FDragDetectStatus:=ddsRight
  1558. else
  1559. begin
  1560. FDragDetectStatus:=ddsNone;
  1561. exit;
  1562. end;
  1563. GetCursorPos(FDragDetectStart);
  1564. if HiWord(DWord(GetKeyState(VK_SHIFT)))<>0 then grfKeyState:=MK_SHIFT
  1565. else grfKeyState:=0;
  1566. if HiWord(DWord(GetKeyState(VK_CONTROL)))<>0 then
  1567. grfKeyState:=grfKeyState or MK_CONTROL;
  1568. if (MouseHookHandle<>0) then
  1569. begin // MouseHookProc is used by another component ...
  1570. UnHookWindowsHookEx(MouseHookHandle);
  1571. MouseHookHandle:=0;
  1572. if assigned(MouseHookDragDrop) then
  1573. begin
  1574. MouseHookDragDrop.FDragDetectStatus:=ddsNone;
  1575. if assigned(MouseHookDragDrop.FOnDragDetect) then
  1576. MouseHookDragDrop.FOnDragDetect(grfKeyState,
  1577. MouseHookDragDrop.FDragDropControl.ScreenToClient(
  1578. MouseHookDragDrop.FDragDetectStart),
  1579. MouseHookDragDrop.FDragDropControl.ScreenToClient(FDragDetectStart),
  1580. MouseHookDragDrop.FDragDetectStatus);
  1581. end;
  1582. end;
  1583. MouseHookDragDrop:=self;
  1584. MouseHookHandle:=SetWindowsHookEx(WH_MOUSE,MouseHookProc,LongWord(HInstance),0);
  1585. if assigned(FOnDragDetect) then
  1586. FOnDragDetect(grfKeyState,
  1587. FDragDropControl.ScreenToClient(FDragDetectStart),
  1588. FDragDropControl.ScreenToClient(FDragDetectStart),
  1589. FDragDetectStatus);
  1590. end;
  1591. procedure TDragDrop.Loaded;
  1592. // Methode which is called if all components are created - now, we can register
  1593. // the target control for drag-and-drop operations
  1594. begin
  1595. inherited Loaded;
  1596. if (FDragDropControl<>nil) and (csDesigning in ComponentState=false) then RegisterTarget;
  1597. end;
  1598. procedure TDragDrop.Notification(AComponent: TComponent; Operation: TOperation);
  1599. begin
  1600. inherited Notification(AComponent,Operation);
  1601. if (AComponent=FDragDropControl) and (Operation=opRemove) then
  1602. begin
  1603. UnregisterTarget;
  1604. UnhookMessageHandler(true);
  1605. FDragDropControl:=nil;
  1606. end;
  1607. end;
  1608. function TDragDrop.RegisterTarget: Boolean;
  1609. // Methode for registering the DragDropControl for drag-and-drop oprations
  1610. begin
  1611. Result:=false;
  1612. try
  1613. HookMessageHandler;
  1614. finally
  1615. // nothing to do
  1616. end;
  1617. if FRegistered or (FTargetEffects=0) or (FDragDropControl=nil) then exit;
  1618. try
  1619. // CoLockObjectExternal crashes debugging intermittently in C++ Builder 2010
  1620. {$IFNDEF IDE}
  1621. // Ensure that drag-and-drop interface stays in memory
  1622. CoLockObjectExternal(FDropTarget, True, False);
  1623. {$ENDIF}
  1624. if RegisterDragDrop(FDragDropControl.Handle, IDropTarget(FDropTarget))=S_OK then
  1625. begin
  1626. Result:=True;
  1627. FRegistered:=True;
  1628. end;
  1629. except
  1630. Result:=false;
  1631. FRegistered:=false;
  1632. end;
  1633. end;
  1634. function TDragDrop.UnRegisterTarget: Boolean;
  1635. begin
  1636. Result:=false;
  1637. if (FRegistered=false) or (FDragDropControl=nil) then exit;
  1638. try
  1639. UnHookMessageHandler(false);
  1640. CoLockObjectExternal(FDropTarget, false, False);
  1641. if (FDragDropControl.HandleAllocated=false) or
  1642. (FDragDropControl.HandleAllocated and
  1643. (RevokeDragDrop(FDragDropControl.Handle)=S_OK)) then
  1644. begin
  1645. FRegistered:=false;
  1646. Result:=true;
  1647. end;
  1648. except
  1649. end;
  1650. end;
  1651. procedure TDragDrop.HookMessageHandler;
  1652. begin
  1653. if (FDragDropControl=nil) or (FDragDropControl.Handle=0) then exit;
  1654. if (FMessageHooked=false) and ((FSourceEffects<>0) or (FTargetEffects<>0)) then
  1655. begin
  1656. WndProcPtr:=MakeObjectInstance(WndMethod);
  1657. OldWndProc:=Pointer(SetWindowLong(FDragDropControl.Handle, GWL_WNDPROC,
  1658. longint(WndProcPtr)));
  1659. FMessageHooked:=true;
  1660. end;
  1661. end;
  1662. procedure TDragDrop.UnhookMessageHandler(ForceUnhook:boolean);
  1663. begin
  1664. if FMessageHooked and (ForceUnhook or ((FSourceEffects=0) and (FTargetEffects=0))) then
  1665. begin
  1666. begin
  1667. SetWindowLong(FDragDropControl.Handle, GWL_WNDPROC, longint(OldWndProc));
  1668. FreeObjectInstance(WndProcPtr);
  1669. WndProcPtr:=nil;
  1670. OldWndProc:=nil;
  1671. end;
  1672. FMessageHooked:=false;
  1673. end;
  1674. end;
  1675. procedure TDragDrop.DoMenuPopup(Sender: TObject; AMenu: HMenu; DataObj: IDataObject; AMinCustCmd:integer;
  1676. grfKeyState: Longint; pt: TPoint);
  1677. begin
  1678. if assigned(FOnMenuPopup) then
  1679. FOnMenuPopup(Sender, AMenu, DataObj, AMinCustCmd, grfKeyState,
  1680. FDragDropControl.ScreenToClient(pt));
  1681. end;
  1682. function TDragDrop.DoMenuExecCmd(Sender: TObject; AMenu: HMenu; DataObj:IDataObject;
  1683. Command:integer; var dwEffect: longint):boolean;
  1684. begin
  1685. Result:=false;
  1686. if assigned(FOnMenuExecCmd) then
  1687. FOnMenuExecCmd(Sender, AMenu, DataObj, Command, dwEffect, Result);
  1688. end;
  1689. procedure TDragDrop.DoMenuDestroy(Sender:TObject; AMenu: HMenu);
  1690. begin
  1691. if assigned(FOnMenuDestroy) then FOnMenuDestroy(Sender, AMenu);
  1692. end;
  1693. procedure TDragDrop.SetDragDropControl(WinControl: TWinControl);
  1694. begin
  1695. if WinControl<>FDragDropControl then
  1696. begin
  1697. if FRegistered and (csDesigning in ComponentState=false) then
  1698. begin
  1699. UnhookMessageHandler(true);
  1700. UnregisterTarget;
  1701. end;
  1702. FDragDropControl:=WinControl;
  1703. if (csDesigning in ComponentState=false) then RegisterTarget;
  1704. end;
  1705. end;
  1706. function TDragDrop.ExecuteOperation(DataObject:TDataObject): TDragResult;
  1707. var dwEffect: Longint;
  1708. DropSource: TDropSource;
  1709. pt: tpoint;
  1710. grfKeyState:longint;
  1711. begin
  1712. Result:=drInvalid;
  1713. if (DataObject=nil) or (GInternalSource<>nil) then exit;
  1714. GInternalSource:=self;
  1715. if (FSourceEffects<>0) then
  1716. begin
  1717. if MouseHookHandle<>0 then
  1718. begin
  1719. UnHookWindowsHookEx(MouseHookHandle);
  1720. MouseHookHandle:=0;
  1721. end;
  1722. FDragDetectStatus:=ddsDrag;
  1723. DataObject.FCheckLindex:=CheckLindex in FSrcCompatibilityCheck;
  1724. DataObject.FCheckdwAspect:=CheckdwAspect in FSrcCompatibilityCheck;
  1725. try
  1726. FOwnerIsSource:=true;
  1727. try
  1728. DropSource:=TDropSource.Create(self);
  1729. try
  1730. if (DataObject<>nil) and (DragDropControl<>nil) and
  1731. (DoDragDrop(IDataObject(DataObject), DropSource,
  1732. FSourceEffects, dwEffect)=DRAGDROP_S_DROP) then
  1733. begin
  1734. case dwEffect and ((DropEffect_Copy or
  1735. DropEffect_Move or DropEffect_Link)) of
  1736. DropEffect_Copy: Result:=drCopy;
  1737. DropEffect_Move: Result:=drMove;
  1738. DropEffect_Link: Result:=drLink;
  1739. else
  1740. begin
  1741. {MP dropped on no-drop location or }
  1742. {cancelled by ddext after drop with move-effect}
  1743. Result:=drInvalid;
  1744. end;
  1745. end;
  1746. end
  1747. else
  1748. begin
  1749. {MP cancelled by user }
  1750. Result:=drCancelled;
  1751. end;
  1752. finally
  1753. DropSource._Release;
  1754. end;
  1755. except
  1756. Result:=drInvalid;
  1757. raise;
  1758. end;
  1759. finally
  1760. FOwnerIsSource:=false;
  1761. DataObject._Release;
  1762. end;
  1763. FDragDetectStatus:=ddsNone;
  1764. if assigned(FOnDragDetect) then
  1765. begin
  1766. GetCursorPos(pt);
  1767. if HiWord(DWord(GetKeyState(VK_SHIFT)))<>0 then grfKeyState:=MK_SHIFT
  1768. else grfKeyState:=0;
  1769. if HiWord(DWord(GetKeyState(VK_CONTROL)))<>0 then
  1770. grfKeyState:=grfKeyState or MK_CONTROL;
  1771. FOnDragDetect(grfKeyState,
  1772. FDragDropControl.ScreenToClient(FDragDetectStart),
  1773. FDragDropControl.ScreenToClient(pt), FDragDetectStatus);
  1774. end;
  1775. end
  1776. else
  1777. begin
  1778. FDragDetectStatus:=ddsNone;
  1779. Result:=drCancelled;
  1780. end;
  1781. GInternalSource:=nil;
  1782. end;
  1783. function TDragDrop.Execute: TDragResult;
  1784. begin
  1785. Result:=ExecuteOperation(CreateDataObject);
  1786. end;
  1787. procedure TDragDrop.SetSourceEffects(Values:TDropEffectSet);
  1788. begin
  1789. FSourceEffectsSet:=Values;
  1790. FSourceEffects:=0;
  1791. if deCopy in Values then inc(FSourceEffects,DROPEFFECT_COPY);
  1792. if deMove in Values then inc(FSourceEffects,DROPEFFECT_MOVE);
  1793. if deLink in Values then inc(FSourceEffects,DROPEFFECT_LINK);
  1794. if (csDesigning in ComponentState=false) and (csLoading in ComponentState=false) then
  1795. begin
  1796. if (csDesigning in ComponentState=false) and (FMessageHooked=false) and
  1797. (FSourceEffects<>0) then HookMessageHandler;
  1798. if (csDesigning in ComponentState=false) and (FMessageHooked=true) and
  1799. (FSourceEffects=0) then UnhookMessageHandler(false);
  1800. end;
  1801. end;
  1802. procedure TDragDrop.SetTargetEffects(Values:TDropEffectSet);
  1803. begin
  1804. FTargetEffectsSet:=Values;
  1805. FTargetEffects:=0;
  1806. if deCopy in Values then inc(FTargetEffects,DROPEFFECT_COPY);
  1807. if deMove in Values then inc(FTargetEffects,DROPEFFECT_MOVE);
  1808. if deLink in Values then inc(FTargetEffects,DROPEFFECT_LINK);
  1809. if (csDesigning in ComponentState=false) and (FRegistered=false) and
  1810. (FTargetEffects<>0) then RegisterTarget;
  1811. if (FRegistered=true) and (FTargetEffects=0) then
  1812. UnRegisterTarget;
  1813. end;
  1814. procedure SetMenuItemsStrings;
  1815. begin
  1816. {MP}{ case SysLocale.PriLangID of
  1817. LANG_GERMAN:
  1818. begin
  1819. MICopyStr:='Hierher &kopieren';
  1820. MIMoveStr:='Hierher &verschieben';
  1821. MILinkStr:='Verknüpfung(en) hier &erstellen';
  1822. MIAbortStr:='&Abbrechen';
  1823. end;
  1824. LANG_FRENCH:
  1825. begin // French
  1826. MICopyStr:='&Copier ici';
  1827. MIMoveStr:='&Transférer ici';
  1828. MILinkStr:='&Créer un ou des raccourci(s) ici';
  1829. MIAbortStr:='&Arrêt';
  1830. end;
  1831. LANG_ITALIAN:
  1832. begin // Italian
  1833. MICopyStr:='&Copiare qui';
  1834. MIMoveStr:='&Muoversi qui';
  1835. MILinkStr:='&Scorciatoia(e) crea qui';
  1836. MIAbortStr:='&Terminazione';
  1837. end;
  1838. LANG_POLISH:
  1839. begin // Polish
  1840. MICopyStr:='&Kopiuj tutaj';
  1841. MIMoveStr:='&Przenieœ tutaj';
  1842. MILinkStr:='Utwórz &skrót(y) tutaj';
  1843. MIAbortStr:='&Anuluj';
  1844. end;
  1845. LANG_PORTUGUESE:
  1846. begin // Portuguese
  1847. MICopyStr:='&Copíe aqui';
  1848. MIMoveStr:='&Mova aqui';
  1849. MILinkStr:='&Atalho(s) cría aqui';
  1850. MIAbortStr:='&Aborto';
  1851. end;
  1852. LANG_SPANISH:
  1853. begin // Spanish
  1854. MICopyStr:='&Copie aquí';
  1855. MIMoveStr:='&Muévase aquí';
  1856. MILinkStr:='&Atajo(s) crea aquí ';
  1857. MIAbortStr:='&Aborto';
  1858. end;
  1859. else
  1860. begin // English
  1861. MICopyStr:=SCopyStr;'&Copy Here';
  1862. MIMoveStr:=SMoveStr;'&Move Here';
  1863. MILinkStr:=SLinkStr;'&Shortcut(s) Create Here';
  1864. MIAbortStr:=SAbortStr;'&Abort';
  1865. end;
  1866. end;}{/MP}
  1867. end;
  1868. function TDragDrop.CopyToClipboard:boolean;
  1869. var DataObject:IDataObject;
  1870. begin
  1871. Result:=false;
  1872. DataObject:=CreateDataObject;
  1873. if DataObject=nil then exit;
  1874. try
  1875. Result:=OLESetClipBoard(DataObject)=S_Ok;
  1876. finally
  1877. DataObject._Release;
  1878. end;
  1879. end;
  1880. function TDragDrop.GetFromClipboard:boolean;
  1881. var DataObject:IDataObject;
  1882. pt:TPoint;
  1883. dwEffect:longint;
  1884. begin
  1885. Result:=OLEGetClipBoard(DataObject)=S_Ok;
  1886. if Result then
  1887. begin
  1888. pt.x:=-1;
  1889. pt.y:=-1;
  1890. dwEffect:=DropEffect_Copy;
  1891. FDropTarget.RenderDropped(DataObject, 0, pt, dwEffect);
  1892. end;
  1893. end;
  1894. function TDragDrop.DropHandler(const dataObj: IDataObject; grfKeyState: Longint;
  1895. pt: TPoint; var dwEffect: Longint): boolean;
  1896. begin
  1897. Result:=false;
  1898. end;
  1899. // Register method -------------------------------------------------------------
  1900. procedure Register;
  1901. begin
  1902. {MP}RegisterComponents({'Shell32'}'DragDrop', [TDragDrop]);
  1903. end;
  1904. // initialize/de-initialize the ole libary -------------------------------------
  1905. initialization
  1906. begin
  1907. OleInitialize(nil);
  1908. MouseHookHandle:=0;
  1909. GInternalSource:=nil;
  1910. SetMenuItemsStrings;
  1911. // to avoid mix ups
  1912. DDM_ProcessDropped:=RegisterWindowMessage('DDM_ProcessDropped');
  1913. end;
  1914. finalization
  1915. begin
  1916. if MouseHookHandle<>0 then UnHookWindowsHookEx(MouseHookHandle);
  1917. OleUninitialize;
  1918. end;
  1919. end.