Why can't I use ToolButtons after assigning them an Action? - delphi

I am learning Delphi and building a simple NotePad. However, as soon as I add an Action to some ToolButtons (note the align left, center, and right buttons and Bold), they are disabled in the running app, although the Enabled property is set to true in the Object Inspector. They become enabled in the running app if I remove the Action from them in the Object Inspector, but then they are just useless clickable buttons. I have added some pictures below.
I have Googled and tried myself almost to insanity and I really can't figure it out myself.

A normal TAction needs an OnExecute event to become enabled. You can control this with the property DisableIfNoHandler, which defaults to True.

Related

How to make TdxBarButton always visible in TdxBarManager.Bars[i], even when user is removed this button (made invisible) previous time?

I am using DevExpress TdxBarManager for Delphi, which is very complex component. It contains set of TdxBarButton's (or its descendants) - commands. And it also contains set of TdxBars - panels in which those commands are placed.
During the design time the developer creates TdxBarButton instance, assings properties to it in the object inspector and then drags-and-drops it on the TdxBar instance.
During the runtime the user can call 'Add or Remove Buttons' and this opens the dialog, in which the user can opt to make some buttons from this bar invisible. The visible/invisible button selection is preserved in the user registry.
My question is - how can I press the TdxBarButton to be always visible? Even when the user has opted to make it invisible. I know that dxBarButton has Visible property whose possible values include ivAlways, but this value ir preserved and resetting it does not make the invisible button visible again.
I am currently developing using Delphi 6, but I guess the same applies to TdxBarManager in the more recent Delphi as well like Delphi 2009 or Delphi Sydney.

Fix for Enabled changing button "Down" status

I have some TSpeedButtons on a form that has multiple uses. In one mode I don't want one button to be clicked so I just set "Enabled:=False;"
But, if it was Down and I force it to Enabled:=False it goes to the Up-State. How can I prevent "Enabled" affecting the current Up/Down State as I still need it to visually show the current State.
In short, you cannot do what you are asking for with a standard TSpeedButton. This is just the way it is coded to work.
When you set Enabled to false on a TSpeedButton, the button gets drawn in a disabled state regardless of its Down property. The TSpeedButton.Paint() method forces the State property to bsDisabled, wiping out any current Up/Down state. In Delphi 5, this causes the button to be drawn with an Up appearance. In more modern versions of Delphi, if visual styles are enabled, the button gets drawn with a flat appearance that is neither Up nor Down.
The only way to change this behavior is to either:
derive a new class from TSpeedButton and override the virtual Paint() method so you can custom-draw the button yourself however you want. You will have to draw the entire button, though.
make a copy of the VCL's Buttons.pas source file (Vcl.Buttons.pas in XE2 and later), add the copied file to your project (make sure Runtime Packages are disabled), and then you can modify the implementation of TSpeedButton.Paint() itself however you want. Just know that this will affect every TSpeedButton in your project.

Is it possible to open a menu when a button is clicked in Rad Studio

It is possible to do in most other environments, but i'm unable to find a way to do this with Embarcadero.
The closest thing that was found is setting the DropDownMenu property on a button with bsSplitButton property... however this has a problem that it only works with Vista (so in fact i cannot even test if it works at all).
Alternatively it is currently possible to add a regular right button drop down.
Is there a way to connect button's left button click event to a specific drop down menu?
Your button's OnClick event handler can call the Popup() method of a TPopupMenu component. You do not have to assign the PopupMenu to the button unless you want it to handle right-clicking.

TToolbar Button with dropdown menu greyed out

I'm having issues getting a TToolbar Button to appear "enable"
The button has an Action assigned to it - which is fire by the OnClick event
It is also setup with a Drop Down Menu, which has 2 options on it, both of which are enabled, and both of which fire off when clicked.
Despite all this the TToolbar Button steadfastly remains greyed out, but accepts the clicks.
Any suggestions?
You're doing things wrong. :-)
When using actions, you don't use the button's OnClick event - you put the code in the action's OnExecute event instead (because that's what's executing - the action - and not the button). When an action is assigned to the control, the control cannot be enabled until there's a handler for the TAction.OnExecute.
The reason for using actions is so you can put the code in a single place (events related to the action), and then every single control attached to that action uses that common code to perform the same functionality. Editing the code in that single location means all controls attached to that action see the same changes.
If there's nothing attached to the TAction.OnExecute event, the control has nothing to do if it was selected (clicked), and so there's no reason to enable it in the first place.
In case someone else comes across this, I just had this problem (using Delphi 10.2 Tokyo).
For some reason, the "EnableDropdown" property on the TToolButton caused the button to to be greyed out when set to true. Setting this property to false seems to have resolved the problem for me (the dropdown menu remains functional anyway).

Delphi - Duplicate tpanel and tbuttons on second form

On my main form I have a TPanel containing buttons that act as a toolbar. I want to clone/copy this toolbar and the buttons and their functionality to a second form.
Cloning the menu was simple using newmenu.merge(mainmenu). That was an excellent shortcut to duplicating a Tmainmenu.
But I am at a loss on how to easily duplicate my toolbar without having to manually assign the events and keep a timer to compare and track which buttons are enabled and disabled in comparison to the real mainmenu on the main form. Depending on what the application is doing the main toolbar buttons will be enabled and disabled at various times.
Any ideas here? Thanks for any suggestions or tips to make this easier.
Duplicating the controls
In the Form Designer, select the panel and press Ctrl+C to copy it and all its children to the clipboard. Go to the second form and press Ctrl+V to paste.
If you're still working on the design and want to keep it consistent between both forms, then create a TFrame and design your toolbar layout there. Then put an instance of that frame on both your forms. Changes to the frame design will be reflected in the forms.
See Working with frames in the help.
Making sure both sets of buttons are enabled consistently
Create a data module. Put a TActionList on it. Add an action to it for each button on your main form. Assign event handlers to the actions' OnUpdate events. In them, set the actions' Enabled properties. Finally, assign each button's Action property to refer to the corresponding action object. The buttons will automatically get enabled and disabled with the actions. No timer required.
Furthermore, you can handle the actions' OnExecute events, too. Clear each button's OnClick property, and then move the button's OnClick code into the corresponding action's OnExecute handler. It will automatically get called when you click the button, even though the OnClick property is empty.
When you assign the Caption or Hint property of a TAction, the corresponding properties of any associated controls also change. Likewise for images, if the control supports them. Actions can be assigned to menu items, too.
See Using action lists in the help.
Acting like a toolbar
Just use TToolbar. That's what it's for.
Or, once you're used to actions, put a TActionManager in your project and use it with TActionToolbar and TActionMainMenuBar. See Organizing actions for toolbars and menus in the help.
Are the buttons attached to actions? If so, you can use the OnUpdate event of the TActionList to specify what should and should not be enabled. If not, it isn't too much work to convert to using actions.
If you go this route to convert to using a ActionList, consider putting the ActionList in a datamodule where different units and forms could reference it.
You can Use ClipBoard Object For Copy Your Panel.
Clipboard.SetComponent(Panel1);
Clipboard.GetComponent(Form2,GroupBox1);

Resources