Ribbon control bug? (causes cutoff in vista)
-
08-07-2019 - |
Question
I've found that when I take a simple form containing only a ribbon bar and a status bar, it's cutoff. The control you see above the status bar was later removed. The same cutoff occurs whatever control happens to be present. Later I removed the status bar & put a memo control there instead with the same result.
without ribbon bar:
(source: xrw.bc.ca)
with ribbon bar:
(source: xrw.bc.ca)
i've illustrated this with some drawing 2, 4, and 8 pixels from the edge.
(source: xrw.bc.ca)
(source: xrw.bc.ca)
as Chris Lively says below, there's clearly been a miscalculation of the sizes. how can i correct this?
Thank you for your comments!
Solution
I misunderstood the problem with my previous answer.
There is a workaround to this miscalculation problem I've been able to come up with (quickly).
You can use a custom messagehandler for WM_SYSCOMMAND with the SC_MAXIMIZE wParam parameter. You can then resize your form using the following:
type
TForm1 = class(TForm)
// other stuff
procedure WMSyscommand(var Msg: TWMSYSCOMMAND); message WM_SYSCOMMAND;
procedure TForm1.WMSysCommand(var Msg: TWMSYSCOMMAND);
var
R: TRect;
begin
// Test for SC_MAXIMIZE. If found...
if Msg.CmdType = SC_MAXIMIZE then
begin
SystemParametersInfo(SPI_GETWORKAREA, 0, @R, 0);
Top := R.Top;
Left := R.Left;
Width := R.Right - R.Left;
Height := R.Bottom - R.Top;
Msg.Result := 0; // Message handled
end
else
DefaultHandler(Msg);
end;
The code above (tested on Vista 32-bit Home Premium with Aero/Glass enabled) works fine.
OTHER TIPS
The solution proposed by Ken White has a few issues:
- Maximize button stays active, can use resize handles on maximised window
- Unable to restore window back to previous size.
So I propose the following:
// add to form object
procedure WMGetMinMaxInfo(var mmInfo : TWMGETMINMAXINFO); message WM_GETMINMAXINFO;
// implementation
procedure TfrmMain.WMGetMinMaxInfo(var mmInfo: TWMGETMINMAXINFO);
var
R: TRect;
begin
with mmInfo.MinMaxInfo^ do
begin
SystemParametersInfo(SPI_GETWORKAREA, 0, @R, 0);
ptMaxPosition.X := R.Left;
ptMaxPosition.Y := R.Top;
ptMaxSize.X := R.Right - R.Left;
ptMaxSize.Y := R.Bottom - R.Top-1;
end;
end;
Not ideal, as I have to (for some reason) adjust the maxHeight by -1 in order for the default handler to not re-assert itself and move the window to -8,-8,... But it works for me.