How do I prevent menu and toolbar clicks stealing focus from a floating form? - delphi

I want to achieve the same effect as in Visual Studio 2010+, where if you float an editor on top of the main form, clicking on a main form menu or toolbar button doesn't cause the main form to steal focus; instead the floating window retains focus.
Without this it becomes impossible to invoke any main menu command that operates on a focused control when the focused control is in a floating window - because the control you wanted to operate on loses focus just as the command is invoked.
(Ironically, if you look closely at this image you'll see that the selection in the editor is muted, indicating that the editor control doesn't have focus. Visual Studio seems to be doing something slightly devious to achieve the illusion that the floating window is still focused.)

The solution is very easy if you are using TActionMainMenuBar and TActionToolBar.
First the menu bar: TActionMainMenuBar has a property AutoFocus, which is True by default. Set this to False and then clicking on the menu won't automatically give focus to the form containing the menu. Instead, the form that previously had focus will retain it.
Now the tool bar: TActionToolBar doesn't have an AutoFocus property. Instead you need to handle its OnMouseActivate event and return maNoActivate.
Note that returning maNoActivate from an OnMouseActivate handler doesn't work for all controls. Some controls such as TButton will give themselves the focus when clicked regardless of the return result from the OnMouseActivate handler. But in the case of TActionToolBar we do get the effect we are after.
It took me a while to find this though, and even searching Google for a page containing both 'AutoFocus' and 'OnMouseActivate' elicits no useful results (other than, presumably, this page once it gets indexed). So I hope this answer will help someone else.

Related

how to respond to a key press when focused on a radiogroup in delphi

In delphi:
How can you respond to a key press when the current focus is on a radiogroup which does not have an onkeypress event. I was hoping to use the forms onkeypress event but it doesnt see to fire.
You can make this possible by setting the form's KeyPreview property to True.
However, I'm not sure you are actually doing things right, since this is a fairly uncommon problem.
You didn't write what keyboard shortcut you want to respond to. But please remember that
Letters are used to navigate the GUI. For instance, pressing A might select the &All radio button or click the &Add push button. Similarly, Alt+A does the same if the current control allows character input, allows you to open the &Add-ons menu item, etc.
If you want to add a proper shortcut like Ctrl+O, it is much better to use a TActionList with an action having this shortcut. This action can be mapped to menu items, buttons, etc., or simply exist in the background not being attached to any visual control. In very simple applications, you might want to use a stand-alone menu item with such a shortcut instead.

Default Button with VCL Styles

I am puzzled by the styling of TButtons that have Default:=True. The issue is that at least with some styles (Luna, for example), the most recently focused button is highlighted orange, which is the same styling used for a default button. As a result, I am concerned that users might be confused as to which button is the default or will at least think it odd that two buttons are highlighted. This behavior can be seen in XE7 (and according to a comment, also in XE8).
Questions:
Is this considered a modern way (relatively to unstyled VCL) to present default buttons?
If this is not considered standard behavior I can work around it in my own dialogs by strategically enabling/disabling the default button, but I was wondering whether I missed some setting that controls the relation between default buttons and the most-recently focused button. Is there a setting that controls this?
I suspect that this is a VCL styles bug. Create a default VCL application that uses the standard OS theme. Then add two buttons and an edit control. Make one of the buttons be the default button.
Now use the tab key to cycle round the focus. When the edit control has the focus, the default button is highlighted. That indicates that if you press ENTER then that button will be pressed.
However, if either of the buttons has the focus, then the button with the focus is highlighted. That's because if you press ENTER when a button has the focus, the focused button is pressed, irrespective of whether it is the default button.
The rules are as follows:
If a button has the focus, it is highlighted as the default button.
If a control other than a button has the focus, the default button, if there is one, is highlighted.
So, here's what the application looks like in XE7 with the system theme. The non-default button has the focus.
Note that only one button is highlighted, and it is not the default button.
And here is the same application in XE7 with the Luna style.
Here we have the default button, and the button with the focus, both being highlighted. I would regard that to be a bug, and it should be reported.

Make popup window close when releasing mouse button on an item on the fly

When clicking on a button I open a popup menu, e.g. using popupMenu.popup().
To select an item I must first release the mouse button and then click on a menu item to execute it.
This is "normal", but what I want is the behavior that I won't have to do an extra click on the menu item. I would like to be able to click on the button, move over a menu item (still holding the button) and execute it immediately after releasing the mouse button.
This is similar to how cascaded sub menus work.
I tried the way using TrackPopupMenu to hook into the messages and execute the item when the button is released. This works, but...
When using images in the popup menu (either bitmap or imagelist items) together with TrackPopupMenu then the menu does not show any entry. Every entry is some pixels wide and empty. You can use them blindly, so they work somehow but the drawing is not done correctly.
I'm using Delphi XE2 Pro.
I also tried to find general articles to hook into menu messages but did not find anything that works without using TrackPopupMenu. Maybe there is a way to have TrackPopupMenu displaying menus with images?
Any help is much appreciated.
You are routing menu messages to the wrong window procedure, you are passing the handle of your form to TrackPopupMenu (you should post your code, then there would be no need to guess what you're doing wrong. And you'd probably receive a much quicker reply).
Forms have menu support for window menus. When a form window procedure receives a, say WM_DRAWITEM, it only draws the item if it belongs to the window menu. For popup menus, VCL uses a utility window which is accessible through the global PopupList. See below example.
var
Pt: TPoint;
begin
Pt := Button1.ClientToScreen(Point(0, Button1.Height));
TrackPopupMenu(PopupMenu1.Handle, TPM_LEFTBUTTON, Pt.X, Pt.Y, 0,
PopupList.Window, nil);

Show different popup menu depending on what column the mouse is over in a Delphi TListView control?

I have a Delphi 6 application that has a TJvListView control. I have a popup menu tied to that control via the control's PopupMenu property. What I would like to do is show a different popup menu based on which column the user had the mouse over when they right clicked, with the additional option to not show a popup menu at all if the current column does not need one. How can I do this?
Thanks to this detailed sample by Remy Lebeau on in-place editing in a TListView I know what row and column the mouse is over except for one wrinkle. The mouse down event where I determine the current row and column occurs after the popup menu is exited.
I now need to know two things. First, how can I get some event to fire before the popup menu shows after a right mouse click so I can record the current list view row and column and suppress the popup menu if I want to, and second, how I can show a different popup based on the current column. I am hoping to avoid having to write a bunch of mini-forms instead of using the TListView PopupMenu property and supporting code. Is there a simple solution, perhaps some fancy footwork in a sub-class I should create around TJvListView?
You could perform the detection in mousemove instead of mousedown/Click and change the popupmenu depending.
You also could remove any popupmenu and call the wished via p.pupup in mousedown as you desire.

AlphaBlend a child form

I'm looking after a way to AlphaBlend a child form, if possible using layered windows as there will be interactive controls behind it.
The problem is I have a component in a regular TForm that paints multiple visual layers (drawings, pictures...). At some point I need to instantiate an editor control on this form (in-place), this control will involve a variety of standard input controls outside of my control (edit box, check box, etc.), however I would like to overlay the layers in front of the layer being edited using alpha blending (and WS_EX_TRANSPARENT to make it click-through).
I first thought of using child forms for that (borderless TForms parented to the component), and that works alright, up to the point where the AlphaBlended TForm isn't alphablended at all, but turns opaque as soon as parented...
I then tried to unparent the alphablended form, set it to fsStayOnTop, and by reacting to the relevant events, keep it in front of the component on screen, that works, but that isn't a truly satisfying solution: the alphablended StayOnTop form is also in front of other modal and modeless forms of the application, should the user decide to move them in front of the component...
So, any other ideas on a way to have a child form be alphablended? (or behave like it is)
According to MSDN you are out of luck, as WS_EX_LAYERED cannot be used for child windows.
Maybe you could hide all editor forms when your form / application loses focus, that would at least keep them from being on top of other windows. Still, it's unsatisfactory...

Resources