My Delphi application initially starts by showing the main form, but with a user login panel only. I hide the main menu, so that the unauthenticated user is not able to access it. Upon user login, I dynamically assign the menu by setting Form.Menu := MyMainMenu;.
However, when the user logs in, and I assign the main menu as mentioned, it isn't immediately visible until the form is resized in some way. Minimizing the window and showing it again also triggers the main menu to show. However, I need it to show right away when I assign it.
I have tried adding the following attempts just after assigning the main menu, but makes no difference:
Self.Repaint;
Self.Refresh;
Application.ProcessMessages;
The only thing I can do is to slightly resize the form in run-time, then it triggers it to show. However, not only is this sloppy, but my application shows in the Maximized state by default.
Note: I am using VCL Styles. Without styles, it shows just fine. Trying Vcl-Styles-Utils and its fixes does not make a difference.
How do I get the newly assigned main menu to immediately show without a "resize" hack?
On a side note, when I close the application, I have a memory leak:
Without VCL Styles, this memory leak doesn't occur. Not that I'm asking for a solution for that, but an additional symptom which might help identify the root issue.
Related
I have recently come to need some popup menus to be linked with multiple TTreeViewItem controls. The first time, I right click any of the TTreeViewItems, the delay in the showing of the popup is enough to make me believe that the click didn't register somehow and then it appears. All the subsequent times I click, the reaction is instantaneous.
I have to make my applications so that they are compatible and smooth even on Pentium 4s and the subsequent buit-in horsepower of their generation.
To reproduce:
Place a TTreeView on an empty form.
Add 5 or 6 TTreeViewItems.
Add a TPopupMenu and add a single TMenuItem to it.
Link the TPopupMenu with 2-3 of the TTreeViewItems.
Optionally add another TPopMenu with a single TMenuItem and link with the rest.
Run the application and right-click on any of the TTreeViewItems.
Is there a method I can call to bring the popup menu into the cache immediately after form creation and also not make it visible in doing so?
I encountered yet another problem with ribbon. When I have two forms (one of them is main) and I put ribbon on both of them, they behave strangely. When I open the second form by Form2.Show;, every time I click a ribbon menu button on the second form, it loses focus and the main form gets it.
This happens at pure blank project, so what could I possibly be doing wrong?
Here is a video, just in case: Watch YT
And to be clear, the Action1 button has only Caption:='a'; code.
The ribbon control assumes that there is only one per application, and misbehaves if it is not the only control. You could try to modify the Ribbon.pas code, but it is doing some hacks that probably rely on Ribbon.Parent being Application.MainForm only.
My application has many forms, there is also one more important form, that is the main form, the behaviour is in general ok but in same cases (for example when I open a file dialog from a subform) the beahviour is: subform is hidden and mainform is shown.
How to avoid this?
Make sure you either implicitly or explicitly set the PopupParent of both the sub-form and the dialog. If you open both the sub-form and the dialog from some random bit of code somewhere and don't tell Windows about the correct Z-order, stacking issues can happen.
Windows in my application are popping up off the edge of the screen, and this of course is a problem because some of the windows are modal and can't be dismissed (you don't even know they are there).
I'm using the TurboPower Orpheus component which remembers the location and size of each form, then restores it when the form is shown again. It saves the size and placement in an INI file.
What can I do to prevent windows from ever showing off the side of the screen?
It's common for this sort of thing to happen if you use multiple monitors and then disconnect one, such as when undocking a laptop. Or if you dock a laptop to a screen with a higher resolution. Or use remote desktop, etc..
The remedy is to override the "remember my position" behavior with a sanity check, to see if the left+width exceeds the width of the screen (Screen.Monitors array, actually - thanks guys), and vice-versa for the top+height.
Ideally, you "bump" by subtracting the difference, so you're butting up against the edge that the window wanted to straddle.
Also, see if there are updates to Orpheus that fix this. If not, you can get the source, make the correction (optional), and contribute it back to the project. It's OSS, as I recall.
You may want to give a look at their DefaultMonitor property and read the code from TCustomForm.SetWindowToMonitor to see how to deal with positioning relatively to Screen.Monitors.
Use DefaultMonitor to associate a form with a particular monitor in a multi-monitor application. The following table lists the possible values:
Value Meaning
dmDesktop No attempt is made to position the form on a specific monitor.
dmPrimary The form is positioned on the first monitor listed in the global screen object's Monitors property.
dmMainForm The form appears on the same monitor as the application's main form.
dmActiveForm The form appears on the same monitor as the currently active form.
Note: DefaultMonitor has no effect if the application does not have a main form.
To recall the previous position of a form, without having it suddenly in an area which is no longer available (due to a plugged off screen or changed resolution), you just call
TForm.MakeFullyVisible;
That's it. See the documentation.
I'm attempting to run this in a timer:
Application.Minimize;
ShowWindow( Application.handle, SW_HIDE );
It's been in the code forever and we just discovered that it doesn't work when you have a popupmenu active, it doesn't minimize the MDI parent window.
I figure if I can close the popup menu before running this code, then I'll be ok. Problem is, this code is in an MDI Parent and I have no idea where the current popup menu is. It doesn't matter if it's part of another form's tool bar, this forms tool bar, the product of a right click or that seemingly pointless key next to the space bar.
So, is there a way to hide the active popup menu in my entire program?
Also, if there's a better hunk of code than what I'm using to minimize that'll circumvent this issue, that'd be awesome info too.
To close a popup menu you can use
if GetCapture <> 0 then
SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
in your code before you try to minimize the form.