Forum > LCL

[Resolved] Drag'n'Drop from TVirtualStringTree to SpeedButton

(1/2) > >>

ArminLinder:
Today my problem of the day is, that TSpeedButton does not seem to support handlers for DragOver and DragDrop.
Is there a way to get drag'n'drop  functionality attached to a SpeedButton? In case it helps: for this project a Windows only solution is acceptable.

Long story:

I have Drag''n'Drop enabled controls (VirtualStringTree and ListBox) controls on a form and implemented Drag'n'Drop in between them by implementing DragOver and DragDrop event handlers --> works great.

On the same form, I have a Speedbutton which deletes the currently selected nodes when clicked. Works too.

I thought it would be nice if mouse-addicted users can drag nodes from a tree or list and drop them on the Speedbutton to get them deleted. Unfortunately SpeedButtons, unlike ordinary Buttons or BitButtons, do not seem to support DragOver and DragDrop events.

I already tried clumsy workarounds, like putting a DnD enabled Panel underneath the Button or enabling Drag'n'Drop for the underlying form, but this won't work, sinde the drop is disabled as soon as the mouse cursor enters the rectangle of the Speedbutton. Furthermore I wonder why SpeedButtons won't publish those event handlers, I always though all VCL/LCL controls support them and was baffled to find out that Speedbuttons are an exception - there may be rasons?

Thnx,

Armin.

howardpc:
The reason for TSpeedButton's lack of support for  drag and drop is that it is designed to be a lightweight control, descending from TGraphicControl, and so not able to receive focus, for instance.
Drag and drop functionality is introduced in the LCL at the level of TWinControl, and is available for all TWinControl descendants (which have a window handle).

wp:
Use a TBitBtn instead of the TSpeedButton.

ArminLinder:
The reason why I moved from TButton to TSpeedButton was because I do not want the focus taken away from another control. AFAIK BitBtns take the focus as well.

Wp showed me a different approach, though it is a bit hacky I guess that for my specific issue it is the ideal solution;


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---type  TSpeedButtonHack = class(TSpeedButton);  // access protected properties hack ... procedure TForm1.FormCreate(Sender: TObject);begin  TSpeedButtonHack(SpeedButton1).OnDragOver := @SpeedButtonDragOver;  TSpeedButtonHack(SpeedButton1).OnDragDrop := @SpeedButtonDragDrop;end; 
I decided for this specific situation the hack is my best option.

Thnx for your help,

Armin.

lucamar:

--- Quote from: Nimral on May 13, 2021, 02:42:37 pm ---Wp showed me a different approach, though it is a bit hacky I guess that for my specific issue it is the ideal solution;

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{... some code ...}
--- End quote ---

For such "kluges" an even better approach is to use an interposed class:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Buttons; type  TSpeedButton = class(Buttons.TSpeedButton);  // access protected properties hack   TForm1 = class(TForm){... etc ...}
That way you can use your buttons normally, including access to protected methods/properties, without having to type-cast to a new class:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.FormCreate(Sender: TObject);begin  SpeedButton1.OnDragOver := @SpeedButtonDragOver;  SpeedButton1.OnDragDrop := @SpeedButtonDragDrop;end;

Navigation

[0] Message Index

[#] Next page

Go to full version