DragDrop.pas 77 KB

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