TIWMenu and TIWRegion hides Submenus - delphi

When I put a TIWMenu and a TIWRegion on a TIWAppForm with
IWMenu.align := alTop;
IWRegion.align := alClient;
the submenu of IWMenu is hidden behind the region. That means, when I click on File, a submenu should come up with Open, Save, Save As ..., and it does, but I only see the upper border as the rest shows up behind the IWRegion.
I tried to change the z-order, but it does not help. Neither does setting the IWRegion.ClipRegion := False;
Does anybody have a clue what I do wrong?
I am using Delphi BDS4/2006 with IntraWeb 9.0.42, Windows Vista x64, and Firefox 3.5, IE8, and IE Tab in Firefox.
I drop the two components on the form, connect the main menu to IWMenu, and there the problem is.

Could you be more specific about your setup (e.g. Windows version) and steps to reproduce? Sounds like something wrong in how you've set this up.
I can't reproduce this problem, either in BDS2006 (IW ver 8) nor in RAD2009 (IW ver 10).
I started with a standalone IW application, dropped in a TIWMenu (Align=alTop), TIWRegion (Align=alClient), and TMainMenu (with a few menu and submenu items), and attached the TIWMenu to the TMainMenu. Running this under Win XP sp3, I see the menu and submenu items just fine (over the IWRegion).

The problem was with the ServerController that used a style sheet. This prevented the z-index from being set by the application and therefore the z-order was wrong for the TIWMenu component.
Removing the style sheet resolved the problem. The style sheet had some IDs conflicting with IW.

Related

WebView2 (TEdgeBrowser) not working in background (if not visible on screen) - only shows as grey rectangle

I've confirmed this issue using the standard Delphi 10.4 EdgeBrowser VCL demo with the only difference that I have put the panel with the edgebrowser component on a TPageControl Tabsheet.
Now if my app starts with the Edgebrowser not visible directly on screen (because another tabsheet is active), the Edgebrowser will never fully paint on screen at any later date. It will ever only present itself as a grey rectangle and cannot recover from that, unless I call EdgeBrowser.CloseWebView; EdgeBrowser.CreateWebView; while the Edgebrowser component is visible on screen (it must be visible, or once again nothing happens).
This means I cannot issue "Edgebrowser.Navigate" commands or to anything while the Edgebrowser is in the background, on another tabsheet or while the form is hidden, or it will "go grey" again.
I wonder: Is this a bug or am I missing something major here? I tried calling Edgebrowser.Refresh and Edgebrowser.Repaint but neither help. Once it's grey, only closing and re-creating WebView helps to recover it.
It seems clear to me that this is some kind of canvas issue but I have no clue where to go from here.
I hope you can help or at least confirm this strange behaviour.
System Specs:
Delphi 10.4 Update 1 in Windows 10 Pro 20H2 in VMware Workstation 16
microsoft.web.webview2.0.9.579 from nuget and latest Edge Runtime from here (installed with bootstrap installer)
To quickly recreate the same scenario on your system:
open "C:\Users\Public\Documents\Embarcadero\Studio\21.0\Samples\Object Pascal\VCL\WebBrowser\Edge\EdgeBrowser.dproj"; cut pnlWebViewHost to the clipboard (this is the panel that contains the Edgebrowser component); insert TPageControl; add 2 tabsheets and paste the pnlWebViewHost on one of them. Switch to the other, empty tabsheet, then run the app. At runtime, click on the tabsheet with the browser which should only appear now as a grey rectangle.

JVCL Tabbed Docking: No Close Button on Tabs

I am using the jvDocking components and have been unable to figure out how to enable close buttons on the tabs of forms that have been docked together as a set of tabs. I have tried various combinations of options such as:
tJVDoclient.EnableCloseButton := True;
And
tjvDockVSnetStyle.TabServeroption.ShowClosebuttonOnTabs := True;
tjvDockVSnetStyle.TabServeroption.ShowClosebuttonOnGrabber := False;
I am using Delphi XE2 Update 4.
Does anyone have any ideas as to why I can't seem to get the close button to appear on tabs?
Thank you!
It should be shown with CERTAIN docking styles, if you set the ShowCloseButtonOnTabs property to true. It's inside the TabServerOption section of the Dock Style Component (ie TJvDockVIDStyle).
I just tried it though, and it's possible there is a bug in this component as it does not work any more.

Is it OK to hide Delphi's "Application" Window?

We just moved our application from a MDI container to a single document interface. Our users are used to using a "Windows" menu in the MDI parent to show windows side by side. We want to train them to right click on the Windows taskbar and use the window management functions there.
With Delphi applications we noticed that the windows shell leaves room for the hidden "Application" window. So if I only have two windows open it will arrange room for three. The Application window is not really shown but there is space left for it.
This is made worse by the fact that we have two different applications. If they only have one window open in each application and want to show them side by side windows will actually try to account for 4 windows.
So instead of seeing two windows each taking 1/2 of the screen I see two windows that take up 1/4 of the desktop and the rest of the screen is open.
I found that adding a line to hide the application window as my application starts up will fix this problem.
ShowWindow(Application.Handle, SW_HIDE);
Edit in case someone does not read
down to the answer. Based on Craig's
answer below I am setting the windows
style to WS_EX_TOOLWINDOW instead of
hiding the window.
SetWindowLong(Application.Handle, GWL_EXSTYLE,
GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
My (original) questions is: Is this safe (hiding the application window)? I'm wondering if I may be breaking something else by hiding the Application window. Are there any side effect I need to be aware of? Is there a better way to solve this issue?
I'm using Delphi 2007. The issues seem to be consistent across Windows XP, Vista, and 7.
Update: Some of the answers seem to think the problem is with the Application forms icon being visible. That is not the case. I already have MainFormOnTaskbar set to true.
Also if you are testing this be aware that the Delphi IDE (only tested with 2007) makes things worse. Try this. Open the Delphi IDE and two instances of notepad. Minimize the IDE but have both notepads un-minimized. Right click on choose Show Windows Side by Side. You will see each notepad take up 1/3 of the screen. Close the IDE and choose Show Windows Side by Side again and each will take up 1/2 half of the screen.
In Delphi 2007 (and above) the Application Window does not show on TaskBar at all if
Application.MainFormOnTaskbar := True;
line is in a project file (*.dpr). For example
begin
Application.Initialize;
Application.MainFormOnTaskbar := True; // <--
Application.CreateForm(TForm7, Form7);
Application.CreateForm(TForm8, Form8);
Application.Run;
end.
That is default setting for new applications, but this line is absent if you ported an application from previous Delphi version - you should add this line manually.
As long as MainFormOnTaskBar is true, you can fix the problem by adding this to your DPR:
SetWindowLong(Application.Handle, GWL_EXSTYLE,
GetWindowLong(Application.Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW);
Later versions of Delphi automatically include the WS_EX_TOOLWINDOW flag when they create the TApplication handle.
I'm still using Delphi 7, and I've been using this technique in combination with the 'WndParent:=GetDesktopWindow' trick to get a taskbar button for each window, somewhat like Microsoft Office started doing since some version (I guess XP?)
I believe at this is the way that applications minimize to the system tray.

Delphi TListBox contents overflow when selecting (Win7, 32bit, themed)

I've a TListBox on a Windows form with 966 elements in it. When I click a button on my form, a subset of these strings are selected (roughly 200 of them).
If I now unfocus my application by clicking somewhere on the task bar, the entries from my TListBox bleed upward, so as they are visible above the boundaries of the TListBox. They are thankfully bleeding out behind the TGroupBox component which is directly above them - however this still looks extrememly unpolished.
I'm able to reproduce this only on one Win 7 x64 machine using the Aero theme (I've another Win 7 x64 laptop which doesn't exhibit the same problem with the same theme setting).
I've tried issuing a PostMessage( Self.Handle, WM_PAINT, 0, 0) directly after changing the select status, preceded by a ListBox.Refresh. This doesn't help.
Any help would be much appreciated. Please advise if you need more details.
Cheers, Duncan
Are you using the XPManifest unit, or have you enabled themes for your app? If so, try not using it to see what happens. It can be very bad if you dont have a good video card.
My 2 cents? Avoid using themes at all. It simple does not work very well.

Menu Accelerator Keys Not Showing Up (Delphi 2009)

I've tried my best and cannot figure out what happened here. It worked fine in Delphi 4. After upgrading to Delphi 2009, I don't know if this is the way it is supposed to work, or if it's a problem:
This is what my program's menu looks like in Design Mode under Delphi 2009:
Notice that every word in the Main Menu and the File submenu have one letter underlined. It is supposed to be like this. This underlined letter is called the Accelerator Key and is standard in Windows applications so that you can use the Alt-key and that letter to quickly select the menu item and then submenu item with the keyboard rather than with your mouse.
You get them this way by using the "&" character as part of the caption of the item, for example: Save &As...
When I run my application, and use the mouse to open the File menu, it looks like this:
The characters are underlined in the main menu, but are not underlined in the File menu.
If instead, I use the Alt-F key to open up the File submenu, then it looks correct like this:
and all the Accelerator Key letters are properly underlined.
I've played with the AutoHotKeys option but that's not the problem.
Has someone encountered this problem before? Is the example in the 2nd image correct behavior that I don't know of? Or is there some option or coding mistake that I might have missed?
Nov 2009 (one year later): mghie seems to have got to the root of this and figured out the problem. See his accepted answer below.
There is a standard Windows setting (under display properties) to normally hide those accelerators unless the Alt key is held down. That would explain why opening the menu with Alt+F10 shows them for you. Maybe that's the cause?
[EDIT]: No, it's not. I just tried, and a simple TForm with a menu item shows the accelerator, but as soon as I add a TImageList and set the ImageIndex of the single menu item, or simply set OwnerDraw to true, then the accelerator underline disappears. I guess that really is a bug in the VCL.
BTW, this is on Windows XP.
Workaround:
I have debugged this using Delphi 2009 on Windows XP 64, and the root cause for the missing accelerators seems to be that Windows sends WM_DRAWITEM messages with the ODS_NOACCEL flag set, which it shouldn't if the system is set to show accelerators at all times. So you could say that it is not a VCL bug, but a Windows problem which the VCL does not work around.
However, you can work around it in your own code, you just need to reset the flag before passing the message to the VCL. Override the window proc
protected
procedure WndProc(var Message: TMessage); override;
like so:
procedure TYourForm.WndProc(var Message: TMessage);
const
ODS_NOACCEL = $100;
var
pDIS: PDrawItemStruct;
ShowAccel: BOOL;
begin
if (Message.Msg = WM_DRAWITEM) then begin
pDIS := PDrawItemStruct(Message.LParam);
if (pDIS^.CtlType = ODT_MENU)
and SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, #ShowAccel, 0)
then begin
if ShowAccel then
pDIS^.itemState := pDIS^.itemState and not ODS_NOACCEL;
end;
end;
inherited;
end;
This is demonstration code only, you should not call SystemParametersInfo() every time a WM_DRAWITEM message is received, but once at program start, and then every time your program receives a WM_SETTINGCHANGE message.
It is a "feature" introduced with Windows 2000:
The Old New Thing: Why does Windows hide keyboard accelerators and focus rectangles by default?
It would appear that Delphi 4 didn't support this Windows feature.
To have 2000 and XP menus show accelerator keys, right-click an empty spot on the desktop, choose Properties, click the Appearance tab, and under Effects, uncheck Hide Underlined Letters for Keyboard Navigation until I Press the Alt Key. Click OK twice.
Not sure how to do it in Vista.
I don't think it is a Delphi generated bug as you have the same behavior with Notepad on Vista. Also in Delphi itself BTW...
I must confess that I did not pay attention before your question. Thanks for pointing it out.
As Jim McKeeth noted above (correctly), this is "by design" behavior. If the menus are triggered through keyboard action the accelerators should be shown, but if triggered by the mouse the accelerators are intentionally not shown.
I have my XP configured to show accelerators at all times, but a quick test with that option changed confirms that the menus should not show underlines either (Visual Studio responded as I expected, no underlines when using the mouse). However, Microsoft Office ignores this setting and always shows the underlines. So it looks like a bug in how the menus are drawn in Delphi (I don't have any experience with Delphi myself).
I found the option for Vista as well: http://www.vistax64.com/vista-general/42125-always-show-menu-underline-keyboard-accelerators.html
You can turn this on in the new Ease of Access Center (go to Control
Panel, click Ease of Access and then click Ease of Access Center). In
the Ease of Access Center, click Make the keyboard easier to use, and
at the very bottom select the Underline keyboard shortcuts and access
keys check box.
While doing further research I found this related bug on Delphi forums: http://qc.codegear.com/wc/qcmain.aspx?d=37403
It looks like in your case the child windows (the drawn menus) aren't getting or aren't handling WM_UIUPDATESTATE message from their parent window, which is what causes the redraw with accelerators.

Resources