Recent

Author Topic: [solved] How to wirte a drag into app within a frame?  (Read 1081 times)

Nicole

  • Hero Member
  • *****
  • Posts: 1069
[solved] How to wirte a drag into app within a frame?
« on: March 21, 2025, 03:41:24 pm »
In the demos of Lazarus there is a very easy way to perform a drag a file into an app. I could not bring this to work within a frame. Is this possible at all?
The form shall interact with windows, the frame won't.
Or is is possible with a frame but complex or laggy?
« Last Edit: April 08, 2025, 11:12:33 am by Nicole »

wp

  • Hero Member
  • *****
  • Posts: 12761
Re: How to wirte a drag into app within a frame?
« Reply #1 on: March 21, 2025, 06:06:42 pm »
I think this is not possible. But why not use a TForm in place of a TFrame? When you turn off the border (BorderStyle = bsNone) there's nothing to distinguish it from a frame. You'll have to insert the form into the parent form by code, though - but this is the recommended way to do it for a frame as well.

The attached demo shows that this seems to work: Files from the Explorer can be dropped only on the inserted form (the "pseudo-frame"), but not on the main form itself.

Nicole

  • Hero Member
  • *****
  • Posts: 1069
Re: How to wirte a drag into app within a frame?
« Reply #2 on: March 21, 2025, 09:01:41 pm »
Thank you for your answer. This is the demo from within Lazarus. This is what was my basis from which I tried to do my Drop-Frame and failed.  :'(

I tried to put the "sensitive area" directly on my form. This led to the strange fact, that every Tabsheet of my TPageControl had the drop area on top of itsself. So anything put on the Form will disturb every single frame. Do you think, "invisible" would work? So if I want to drop, I make something invisible or "sendToBack" or so? I am not sure, if the ideas are good, because if I have to mess around to drag and drop and seek and hide, I would be quicker to work with a open-file-dialog.

What do you think? I loved the demo that much, that I said to myself: This function I want ! :P
It is elegant and easy.

Nicole

  • Hero Member
  • *****
  • Posts: 1069
Re: How to wirte a drag into app within a frame?
« Reply #3 on: March 21, 2025, 09:13:50 pm »
Do you think the answer from ChatGPT makes sense?
I do not want to try it for one or two hours, if a pro may see at first glance, this never will work.

Code: Text  [Select][+][-]
  1. Ja, es ist möglich, Dateien per Drag-and-Drop auf ein `TFrame` in Lazarus zu ziehen. Der Prozess ist sehr ähnlich wie bei einem `TForm`, aber es gibt einige Details zu beachten, da `TFrame` ein untergeordnetes Steuerelement ist und keine eigenständige Fensterinstanz wie ein `TForm` hat.
  2.  
  3. Hier sind die Schritte, wie du Drag-and-Drop auf ein `TFrame` einrichtest:
  4.  
  5. 1. **Stelle sicher, dass das `TFrame` den Drag-and-Drop-Vorgang unterstützt**:
  6.    Standardmäßig unterstützt ein `TFrame` den Drag-and-Drop nicht automatisch. Du musst dafür sorgen, dass das `TFrame` die Drag-and-Drop-Events verarbeitet.
  7.  
  8. 2. **Verwende die `OnDragOver` und `OnDragDrop`-Ereignisse**:
  9.    Wie bei einem `TForm` kannst du die Ereignisse `OnDragOver` und `OnDragDrop` verwenden, um zu überprüfen, ob eine Datei über dem `TFrame` gezogen wird und wie sie abgelegt wird.
  10.  
  11. Hier ein einfaches Beispiel, wie du es einrichten kannst:
  12.  
  13. ### Beispielcode:
  14. ```pascal
  15. procedure TMyFrame.DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
  16. begin
  17.   // Überprüfen, ob die Quelle eine Datei ist
  18.   Accept := (Source is TControl); // Oder prüfe hier speziell nach einer Datei
  19. end;
  20.  
  21. procedure TMyFrame.DragDrop(Sender, Source: TObject; X, Y: Integer);
  22. var
  23.   FileName: string;
  24. begin
  25.   if Source is TControl then
  26.   begin
  27.     // Die Datei, die über das Frame gezogen und abgelegt wurde
  28.     if DragQueryFile(Source.Handle, 0, FileName, Length(FileName)) > 0 then
  29.     begin
  30.       // Hier kannst du die Datei weiterverarbeiten
  31.       ShowMessage('Datei abgelegt: ' + FileName);
  32.     end;
  33.   end;
  34. end;
  35.  
  36. procedure TMyFrame.FormCreate(Sender: TObject);
  37. begin
  38.   // Drag-and-Drop für das TFrame aktivieren
  39.   Self.DragMode := dmAutomatic;
  40.   Self.OnDragOver := DragOver;
  41.   Self.OnDragDrop := DragDrop;
  42. end;
  43. ```
  44.  
  45. ### Schritte zur Implementierung:
  46. 1. **`OnDragOver`**:
  47.    - Dieses Ereignis wird ausgelöst, wenn die Datei über das `TFrame` gezogen wird. Hier kannst du steuern, ob das Ablegen der Datei akzeptiert werden soll (in diesem Fall wird geprüft, ob es sich um ein Steuerlement handelt, das die Datei liefert).
  48.  
  49. 2. **`OnDragDrop`**:
  50.    - Dieses Ereignis wird ausgelöst, wenn die Datei auf das `TFrame` abgelegt wird. Hier kannst du den Dateinamen extrahieren und weiterverarbeiten.
  51.  
  52. 3. **`Self.DragMode := dmAutomatic`**:
  53.    - Dies aktiviert den Drag-and-Drop-Modus für das `TFrame`.
  54.  
  55. Mit dieser Methode sollte es dir möglich sein, eine Datei auf ein `TFrame` zu ziehen und darauf zu reagieren.
  56.  
  57. Wenn du spezifischere Anforderungen hast oder auf Probleme stößt, lass es mich wissen!

wp

  • Hero Member
  • *****
  • Posts: 12761
Re: How to wirte a drag into app within a frame?
« Reply #4 on: March 21, 2025, 11:58:47 pm »
A typical answer of ChatGPT: Nice to read - but does not work. (It refers to internal, but not to external drag and drop).

I do not understand your requirement. You have a pagecontrol, each page containing a frame, and each frame should correspond to drag&drop from the Explorer in its own way? As I showed you, replace the frames by borderless forms. And to avoid all of them responding to the OnDropFiles event for sure, turn off their AllowDropFiles property and in the pagecontrol's OnChange turn on only the one of the form residing on the active page.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1501
    • Lebeau Software
Re: How to wirte a drag into app within a frame?
« Reply #5 on: March 22, 2025, 12:06:16 am »
In the demos of Lazarus there is a very easy way to perform a drag a file into an app. I could not bring this to work within a frame. Is this possible at all?

Sure. Any HWND can be the target of a file drag, but that HWND must be registered with the OS to express interest in such actions.  A TForm's window is registered by the LCL, but a TFrame's window is not.  So just register it yourself, using either DragAcceptFiles() or RegisterDragDrop(), and then implement the necessary handler accordingly (WM_DROPFILES or IDropTarget, respectively).
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Boleeman

  • Hero Member
  • *****
  • Posts: 886
Re: How to wirte a drag into app within a frame?
« Reply #6 on: March 22, 2025, 08:50:10 am »
Came across this:

Lazarus drag drop component using platform native drag drop mechanism

https://github.com/cutec-chris/NativeDragDrop

The drag source component will listen to OnMouseDown and OnMouseMove events of the control to which it is connected and detect the drag operation and start it when you click left and move 5 pixels. The above mouse events will still work for your control and can be used like normal, only when the drag gesture is detected the drag-drop will take modal mouse control until the drag/drop operation ends.

Also attached is a Lazarus w32 program source of a drag drop example that converts an svg into a png

It uses a TShape instead of a frame as the drop target. Enjoy.

« Last Edit: March 22, 2025, 09:02:34 am by Boleeman »

Nicole

  • Hero Member
  • *****
  • Posts: 1069
Re: How to wirte a drag into app within a frame?
« Reply #7 on: March 22, 2025, 11:46:07 am »
Thank you for all suggestions. I saved all of them and started trying the first one of WP.

Sounds great, runs, - but not any more after I try to modify it.
It works like this: It creates a form2 on the Tabsheets. So it can use the foms things.

WPs code works in a way, that Form2 is created on EVERY Tabsheet.
This would mean, that my app gets about 20 forms more, which I do not need.
I tried - and this is perhaps my fault - to create Form 2 at only ONE tabsheet in various ways.
These led to access violations in every way.

and about ChatGPT: This is so true! The solutions look great, but often they do not work. For what I use it is, e.g. to ask what in the uses clauses is missing. Or I let it write tedious edit fields to a table with 20 fields. I just key in the DDL and ChatGPT writes them. One time, it tried to get lazy and said: The spare have to be written in the same time. And I answered: Do it, you are only a computer. And then it wrote all of them ;-)


Nicole

  • Hero Member
  • *****
  • Posts: 1069
Re: How to wirte a drag into app within a frame?
« Reply #8 on: March 22, 2025, 04:01:17 pm »
@ Boleeman:
thank you for the projekt. The disadvantage of it is, that it needs BGRABitmap.
This component troubled me a lot and I decided not to use it any more.

Nicole

  • Hero Member
  • *****
  • Posts: 1069
Re: How to wirte a drag into app within a frame?
« Reply #9 on: March 22, 2025, 04:08:55 pm »
@ Remy Lebeau
A most interesting idea, sound so easy and the complete links...
I am afraid, I am not able to use them.

Code: C  [Select][+][-]
  1. eg. I read
  2. void DragAcceptFiles(
  3.   HWND hWnd,
  4.   BOOL fAccept
  5. );
  6.  

This is C, I have no idea of. How to register it in Free Pascal?

One question in between: At the moment I am windows user. When I once may want to change my environment to Linux (I dream of it since Win 11 was released), - will this work still?

440bx

  • Hero Member
  • *****
  • Posts: 5164
Re: How to wirte a drag into app within a frame?
« Reply #10 on: March 22, 2025, 05:29:31 pm »
@Nicole,

Attached is an example of how to handle drag and drop the _original_ way (no nice dragndrop icons.)  It shows you how to use DragAcceptFiles, DragQueryFile, DragFinish and processing the WM_DROPFILES.

A word of "caution": this is pure Windows API, I have no clue whatsoever how to do it using OOP, LCL or whatever it is that should be used in Lazarus.  The example compiles in both, 32 and 64 bit.

Also, those APIs are Windows specific.  That code is not portable to other O/Ss.

Lastly, there is another set of Windows functions to do drag n drop which can provide very nice drag and drop icons but, that set of functions is a good bit more involved to use.  I suggest you start by understanding the code I attached.    For the more involved method, I know there is a package that simplifies the implementation but, I don't have an example of that since that's not how I do things.

HTH.

PS: the archive includes a 64 bit compiled version of the example.  You can delete it if you want and create your own.  I figured I'd include it for your convenience, just in case.



(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

BrunoK

  • Hero Member
  • *****
  • Posts: 696
  • Retired programmer
Re: How to wirte a drag into app within a frame?
« Reply #11 on: March 22, 2025, 06:41:16 pm »
Minimal project on WP's example.

wp

  • Hero Member
  • *****
  • Posts: 12761
Re: How to wirte a drag into app within a frame?
« Reply #12 on: March 22, 2025, 06:48:14 pm »
It's really a bad idea to open two threads about the same topic, and people are responding without context in each of them.

d2010

  • Full Member
  • ***
  • Posts: 143
Re: How to wirte a drag into app within a frame?
« Reply #13 on: March 22, 2025, 07:12:18 pm »
Came across this:

Lazarus drag drop component using platform native drag drop mechanism
The drag source component will listen to OnMouseDown and OnMouseMove events of the control to which it is connected and detect the drag operation and start it when you click left and move 5 pixels. The above mouse events will still work for your control and can be used like normal, only when the drag gesture is detected the drag-drop will take modal mouse control until the drag/drop operation ends.
Also attached is a Lazarus w32 program source of a drag drop example that converts an svg into a png
It uses a TShape instead of a frame as the drop target. Enjoy.

Maybe  you  execute too much X 1000 these lines
Code: [Select]
    bmp := TBGRABitmap.Create;
    svg := TBGRASVG.Create;
    writer := TFPWriterPNG.Create;
    writer.UseAlpha := true;
Do you forced too much the memory leaks?
 ::)

 

TinyPortal © 2005-2018