23

マルチモニターシステムでは、「空白の」VCLアプリケーションは正常に最大化されますが、スタイルが有効になっている(およびデフォルトとして選択されている)同じアプリケーションは正しく最大化されません。私が見ているのは、ウィンドウの右端が2番目のモニターまで伸びていることです(私のメインは左側にあります)。他のWindowsアプリと比較し始めたとき、(少なくとも)Windows 7では、最大化されたウィンドウの左側、右側、または下側にクライアント以外の境界線さえないことに気付きました。実際、標準のVCL(スタイルなし)アプリは、クライアント以外の境界線がなくても、同じように動作します。

これを修正するにはどうすればよいですか?TFormStyleHookにはまだ分析していないWMNCCalcSizeのハンドラーがあることに気付きましたが、最大化されたウィンドウに対してVCLがこのメッセージを誤って処理しているのではないかと思います。

4

2 に答える 2

5

これを少しいじった後、私の考えでは、これはvclスタイルのバグではありません。これは確かに、mghieによる質問へのコメントで言及された記事の動作に関連しています。

具体的な動作は、最大化されたウィンドウのサイズが、ウィンドウが最大化されたモニターの作業領域よりも大きいことです。おそらく、ウィンドウマネージャーはオーバーハングの境界線を隠します。どうやら、それはカスタマイズされたフレームでは完全にはそうしません。MSDN独自のカスタムウィンドウフレームの例でも同じ問題が発生しているようです(コミュニティコンテンツの「ウィンドウが最大化されたときのバグ」というタイトルの投稿を参照してください)。VCLのアプリケーションは、DWMに基づいていないという点で、MSDNの例とは異なりますが、それでも同じ問題だと思います。

オーバーハングの境界線のサイズはシステムサイズの境界線(SM_C [X | Y] SIZEFRAME)ですが、OSが推奨するサイズ/位置を無視し、作業領域を使用するため、これは以下の回避策とは関係ありません。

残念ながら、この回避策はまったく使用できないと思います。1つは、前述の動作が文書化されていないこと、2つは、回避策が完全ではないことです。まだ奇妙なピクセルがあります。ウィンドウを作業領域に正確にスナップすると、ウィンドウマネージャは、ウィンドウ(非表示のフレームを含む)を配置する必要があると思われる場所にウィンドウをオフセットすることを決定します。(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;
于 2012-08-02T02:16:10.970 に答える
1

私が見つけた唯一の方法は、WM_SIZE イベントを処理し、ウィンドウ領域を変更して余分な境界線を切り刻むことです。

于 2013-10-14T22:28:40.520 に答える