direktor05 2 Posted Friday at 12:28 PM Hello, I want to do drag drop from Windows Explorer to my app via OLE interface IDropTarget. Question is how do I detect if OLE communication is working well. For now RegisterDragDrop function is working fine. But I can't get a call to DragEnter function when dragging starts. How can I check that OLE is working fine and that dragging somehow starts? But why I can't get DragEnter function to run? Here is some nice theory: https://delphidabbler.com/articles/article-24 I can't get any of this functions to work or be called. What is wrong? And how do I check if OLE can detect drag-drop in the first place? function DragEnter(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; function DragOver(grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; function DragLeave: HResult; stdcall; function Drop(const dataObj: IDataObject; grfKeyState: Longint; pt: TPoint; var dwEffect: Longint): HResult; stdcall; Share this post Link to post
direktor05 2 Posted Friday at 01:03 PM https://learn.microsoft.com/en-us/windows/win32/shell/dragdrop I'm stopped at point 1 or 2. Share this post Link to post
direktor05 2 Posted Friday at 01:11 PM RegisterDragDrop(Handle, Handler); Handle: 722688 Handler: TFileDropTarget($23747B02490) as IDropTarget So I have a pointer to IDropTarget, but it does not call IDropTarget.DropEnter function when I start the drag operation. Why not? And how can I check this? Share this post Link to post
direktor05 2 Posted Friday at 01:28 PM RegisterDropTarget(TFileDropTarget.Create(FileDragEnter, FileDragOver, FileDragDrop, FileDragLeave)); Share this post Link to post
direktor05 2 Posted Friday at 01:42 PM https://www.swissdelphicenter.ch/en/showcode.php?id=1627 Share this post Link to post
direktor05 2 Posted Friday at 01:46 PM But there still is a question why my DragEnter code is not executed? And how can I find the answer? Share this post Link to post
direktor05 2 Posted Friday at 02:07 PM procedure TForm1.Create(Sender: TObject); begin RegisterDropTarget(TFileDropTarget.Create(FileDragEnter, FileDragOver, FileDragDrop, FileDragLeave)); end; procedure TForm1.RegisterDropTarget(Handler: IDropTarget); begin RegisterDragDrop(Handle, Handler); FDragDropHandle := Handle; end; procedure TForm1.FileDragEnter(Sender: TObject; FileList: TStrings; Point: TPoint; Shift: TShiftState; var Action: TFileDropAction); begin IT NEVER ENTERS HERE FDragFromWindows := True; Point := ScreenToClient(Point); UpdateFileDragAction(FileList, Point, Action); end; Share this post Link to post
direktor05 2 Posted Friday at 02:51 PM How can I check if OLE is called? CoInitialize works OK. RegisterDragDrop also OK. There is no error anywhere but the thing does not work. How can I test a call to OLE dll? Share this post Link to post
Anders Melander 1748 Posted Friday at 07:08 PM Is there are reason why don't just use one of these? https://github.com/landrix/The-Drag-and-Drop-Component-Suite-for-Delphi https://github.com/andersmelander/Drag-and-Drop-Component-Suite If you don't want to use a ready-made library then I suggest you at least use the DragTargetAnalyzer example application in the above library to diagnose your target. Share this post Link to post
Ian Branch 123 Posted Friday at 07:28 PM FWIW I can recommend the landrix suite, it is based on anders' suite. Share this post Link to post
Remy Lebeau 1349 Posted Friday at 10:06 PM (edited) 7 hours ago, direktor05 said: procedure TForm1.Create(Sender: TObject); begin RegisterDropTarget(TFileDropTarget.Create(FileDragEnter, FileDragOver, FileDragDrop, FileDragLeave)); end; The Form's OnCreate event is not the best place to register the drop target. If your Form's window is ever recreated at runtime, you will lose your registration. Instead, override the Form's virtual CreateWnd() method and do the registration there instead. Edited Friday at 10:06 PM by Remy Lebeau 1 Share this post Link to post
direktor05 2 Posted 15 hours ago Anders your component probably does diagnostic according to your component functions not in general. I need a solution how do you check if a procedure of function is executed/called inside OLE/ActiveX dll, better yet specifically inside shell drag drop dll? Any hero here? Share this post Link to post
Remy Lebeau 1349 Posted 15 hours ago (edited) 21 minutes ago, direktor05 said: how do you check if a procedure of function is executed/called inside OLE/ActiveX dll, better yet specifically inside shell drag drop dll? You don't. The drag code is running inside of the Windows Explorer process. If it is not invoking the IDropTarget object inside of your process, it means the call is being blocked outside of your process, most likely by UAC/UIPI if your app is running elevated. Per the comments on your StackOverflow question on this topic: Quote Note that Windows doesn't support drag and drop between programs running at different integrity levels since Wndows Vista. Programs running with Administrator prviledge will not be a drop target for stuff dragged from programs not running with Administrator priviledge. – Brian Quote It can work if you handle WM_DROPFILES (DragAcceptFiles()) instead of IDropTarget (RegisterDragDrop()), and then use ChangeWindowMessageFilter/Ex() to allow the WM_DROPFILES, WM_COPYDATA, and (undocumented) WM_COPYGLOBALDATA (0x0049) messages. ChangeWindowMessageFilter/Ex() doesn't work with IDropTarget, though. The alternative is to either 1) enable UIAccess=true for your app (this has very restrictive requirements, though), or 2) run a non-elevated process to accept the drag and then IPC the data into your elevated app. - Remy Lebeau Edited 15 hours ago by Remy Lebeau Share this post Link to post