Dav*_*way 22 delphi maximize-window delphi-xe2 vcl-styles
在多监视器系统上,"空白"VCL应用程序可以最大化,但启用了样式的相同应用程序(以及一个默认选择的应用程序)最大化不正确.我所看到的是窗口的右侧边缘延伸到第二台显示器(我的主要位于左侧).当我开始与其他Windows应用程序进行比较时,我注意到在Windows 7(至少)下,最大化的窗口甚至在左侧,右侧或底侧都没有非客户端边框.事实上,标准VCL(非样式)应用程序的行为方式相同,没有非客户端边界.
我该如何解决?我注意到TFormStyleHook有一个WMNCCalcSize的处理程序,我还没有解剖,但让我想知道VCL是否可能错误地处理这个消息以获得最大化的窗口.
经过一段时间的努力,我的看法是,这根本不是一个vcl风格的bug.这确实与mghie对该问题的评论中提到的文章中的行为有关.
具体行为是,最大化窗口的大小大于窗口最大化的监视器的工作区域.据说,窗口管理器隐藏了悬垂边界.显然,使用自定义框架并不是这样.请注意,MSDN自己的自定义窗口框架示例似乎遇到了同样的问题(请参阅社区内容中标题为"窗口最大化时出现错误"的帖子).VCL的应用程序与MSDN示例的不同之处在于它不是基于DWM,但我仍然认为它是同一个问题.
悬垂边框具有系统大小边界(SM_C [X | Y] SIZEFRAME)的大小,但这与下面的解决方法无关,因为它忽略了操作系统建议的大小/位置并使用了工作区.
不幸的是,我认为这种解决方法根本不可用.首先,没有记录上述行为,对于两个,解决方法并不完美; 还有一个奇怪的像素.如果将窗口准确地捕捉到工作区域,窗口管理器决定将窗口偏移到它认为应该放置窗口(带有隐藏框架)的位置.(VCL可能会被修改为执行窗口管理器所做的事情,并考虑到悬垂,不要绘制它们或类似的东西,但这将是更多的工作,它仍然是解决无证件的行为..)
无论如何;
type
TForm1 = class(TForm)
..
protected
// overriding styles is not necessary since TFormStyleHook.WMGetMinMaxInfo
// first calls the default window procedure
procedure WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo);
message WM_GETMINMAXINFO;
..
procedure TForm1.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo);
var
R: TRect;
begin
// always arrives with MinMaxInfo.ptMaxPosition = (-SM_CXFRAME, -SM_CYFRAME)
// and MinMaxInfo.ptMaxSize = (PrimaryMonitor.Width (?) + 2 * SM_CXFRAME, ... )
inherited;
// should test for OS, styles etc. before running the below
R := Monitor.WorkareaRect;
InflateRect(R, -1, -1); // odd pixel
OffsetRect(R, -Monitor.Left, -Monitor.Top);
Message.MinMaxInfo.ptMaxPosition := R.TopLeft;
Message.MinMaxInfo.ptMaxSize := Point(R.Width, R.Height);
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2183 次 |
| 最近记录: |