0

私の Windows 7 デスクトップでは、Windows タスクバーが画面の左側 (デフォルトでは下部) に接続され、カスタム デスクトップ ツールバー ("True Launch Bar") が画面の上部に接続されています。

Delphi XE8 VCL プロジェクトでは、メイン ウィンドウの位置の値 (formMain.TopformMain.Left) をFormCloseイベントに保存し、プログラムの開始時にこれらの値を使用してメイン ウィンドウの位置をイベントに復元しますFormCreate

これは通常うまく機能します。ただしformMain.WindowState、最小化 ( = )しているときにプログラムを閉じるとwsMinimized、フォームの位置の値が間違っている (つまり、ツールバーの幅/高さによって縮小される) ため、プログラムの開始時にウィンドウが間違った位置に復元されます。

では、どうすればこの問題を解決できますか?

編集: Davidが言及した他の解決策を試しました:

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 値のみを取得するため、ツールバーが占有するスペースが考慮されないため、これは同じ問題を引き起こします。

さらに、これはデビッドが述べた重複した質問ではなく、類似の質問です。この問題は、最小化された状態のときに画面の値が間違っていることに起因しますが、もう 1 つの問題は、全体的な状態とサイズの復元に関するものです。

また、注意してください:ウィンドウの状態(最小化など)と位置を復元したくないのですが、ウィンドウの位置のみを復元したいのでSetWindowPlacement、他の質問でDavidが述べたように使用できません。

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);

(ウィンドウが最大化されている場合、ウィンドウの位置を保存して復元するのではなく、最大化されたウィンドウの状態のみを保存して復元します)。

4

1 に答える 1

1

ウィンドウが最小化されると、最後に正規化された境界が記憶されており、ウィンドウを復元するとそこに復元されます。これらの境界は、 を通じて利用可能になりますGetWindowPlacement。この API は、ワークエリアの相対座標を返します。これは、その間に作業領域が変更された場合でも、ウィンドウを最小化して同じ作業領域の相対位置に復元できるためです。

明らかに、最小化されたウィンドウを要求したときに VCL が呼び出されますGetWindowPlacement。他にどのようにして返される座標を取得しますか? そしてもちろん、作業領域の相対座標を返しますが、これが混乱を招きます。これらのプロパティが画面に関連している場合もあれば、作業領域に関連している場合もあるため、バグと考える人もいるかもしれません。LeftTop

あなたの解決策は明らかです。を呼び出してワークエリアの相対座標を取得しGetWindowPlacementます。これらの座標を再適用する必要がある場合は、 を呼び出してSetWindowPlacementください。

SetWindowPlacementウィンドウを強制的に最小化するため、使用できないとのことです。しかし、そうではありません。showCmdメンバーをSW_SHOWNORMALまたはに設定しSW_RESTOREます。

これらの API を使用して、ウィンドウの位置を何年も保存および復元してきました。それらはうまく機能することが知られています。

于 2015-07-21T14:49:41.190 に答える