landrix / The-Drag-and-Drop-Component-Suite-for-Delphi

MIT License
161 stars 57 forks source link

TDropFileTarget.MultiTarget fails in some cases #67

Open PeterPanino opened 1 year ago

PeterPanino commented 1 year ago

I use the TDropFileTarget 5.82 component in Delphi 11.3. I have activated the MultiTarget property and registered six different controls as Target in the form's OnCreate event handler. The Register action doesn't always work for all registered controls, as sometimes, randomly, one of the registered controls does not work as a drop target. Therefore, feedback should be given on whether the Register action fails on a control. The Register procedure should be a function and give back the Register result. Or a parameter that holds the registration success? Also, sometimes the OnDragOver event handler is not called on some registered controls.

landrix commented 1 year ago

What type are the controls? Do you have an example?

PeterPanino commented 1 year ago

These are the controls:

DropFileTargetMulti.Register(dxPDFViewerMain); // TdxPdfViewer DropFileTargetMulti.Register(PlainTextEditor); // TImageEnFolderMView DropFileTargetMulti.Register(ImageEnFolderMViewBrushImages); // TJamFileList DropFileTargetMulti.Register(JamFileListPDFAttachments); // TJamFileList DropFileTargetMulti.Register(ImageEnViewPixelEditor); // TImageEnView DropFileTargetMulti.Register(TextEditorSVG); // TTextEditor

PeterPanino commented 1 year ago

Also, I need to check the file in OnDragOver;

procedure TformMain.DropFileTargetMultiDragOver(Sender: TObject; ShiftState: TShiftState; APoint: TPoint; var Effect: Integer);
begin
  CodeSite.Send('Test', DropFileTargetMulti.Files[0]);
end;

But the OnDragOver event handler is not executed!

andersmelander commented 1 year ago

Therefore, feedback should be given on whether the Register action fails on a control.

An exception is raised in the registration fails:

OleCheck(RegisterDragDrop(Parent.Handle, TCustomDropTarget(Owner)));

What you're likely experiencing is that the control handle is being destroyed and recreated after you have registered the control as a drop target. For example, this happens if you change the FormStyle of a form.

The drop target component works around this via the AutoRegister property. What AutoRegister does is that it instructs the drop target component to create a hidden child control with your drop target as the parent. Now if the handle of the drop target is recreated the child control will be notified and it will automatically redo the drop target registration (the call to RegisterDragDrop). See TWinControlProxy So make sure AutoRegister=True. If your target is a RichEdit control (or if it's based on a RichEdit control) then you're out of luck with regard to AutoRegister because they don't play well together.

If AutoRegister is already True then something else is going on. It could be that the controls are doing their own drop target registration, or that they are messing with their child controls (and thus the TWinControlProxy).

But the OnDragOver event handler is not executed!

Try running the TargetAnalyzer. It will show you how your application is interacting with the drop source.