【发布时间】:2015-07-21 10:07:43
【问题描述】:
在我的 Windows 7 桌面上,我将 Windows 任务栏附加在屏幕左侧(而不是默认设置在底部),并在屏幕顶部附加了一个自定义桌面工具栏(“True Launch Bar”)。
在一个 Delphi XE8 VCL 项目中,我将主窗口位置值(formMain.Top 和 formMain.Left)保存在 FormClose 事件中,然后在程序启动时,我使用这些值在 @ 中恢复主窗口位置987654326@事件。
这通常运作良好。 然而,当程序在 MINIMIZED (formMain.WindowState = wsMinimized) 时关闭时,表单位置值是错误的(即被工具栏的宽度/高度减少),因此窗口被恢复在程序开始时位置错误。
那么我该如何解决这个问题呢?
编辑:我试过大卫提到的other solution:
var
WindowPlacement: TWindowPlacement;
R: TRect;
....
WindowPlacement.Length := SizeOf(WindowPlacement);
Win32Check(GetWindowPlacement(formMain.Handle, @WindowPlacement));
R := WindowPlacement.rcNormalPosition;
CodeSite.Send('formMainLeft by WinAPI', R.Left); // normal: 323 minimized: 323
CodeSite.Send('VCL formMain.Left', formMain.Left); // normal: 423 minimized: 323
但是,这会产生同样的问题,因为它没有考虑工具栏占用的空间,因为它只获取 WORK AREA 值。
此外,这不是大卫提到的重复问题,而是类似的问题。这个问题源于最小化状态下的错误屏幕值,而另一个问题是关于整体恢复状态和大小。
另请注意:我不想恢复窗口状态(例如最小化)AND 位置,但只恢复窗口位置,所以我不能使用 David 在另一个问题中提到的 SetWindowPlacement。
EDIT2:我现在已经用这段代码解决了这个问题:
if formMain.WindowState = wsMinimized then
begin
MinimizedOffsetTop := Screen.WorkAreaTop;
MinimizedOffsetLeft := Screen.WorkAreaLeft;
end
else if formMain.WindowState = wsNormal then
begin
MinimizedOffsetTop := 0;
MinimizedOffsetLeft := 0;
end;
SettingsIni.WriteInteger('Persistence', 'Top', formMain.Top + MinimizedOffsetTop);
SettingsIni.WriteInteger('Persistence', 'Left', formMain.Left + MinimizedOffsetLeft);
(在窗口最大化的情况下,我不保存和恢复窗口位置,只保存和恢复最大化窗口状态)。
【问题讨论】:
-
您可以使用 JediVCL 库,其中有
TJvFormPlacement和TJvFormStorage组件可以自动保存和自动恢复 -
虽然 JEDI 无疑为此提供了有用的类,但包括 JEDI 通常会强制您包含大量依赖项。在顶部到达两个 Win32 API。
-
我不想为此使用 JEDI,因为我想完全控制自己的保存和恢复。
-
@kobik
GetWindowRect在窗口最小化时得到错误的值。例如:R.Left则变为 -32000! -
不要使用 screen.workareatop/left,您的表单可能不在与主监视器具有相同工作区偏移量的监视器上。见stackoverflow.com/questions/29747238/…
标签: delphi desktop-application delphi-xe8 window-position