5

カスタム コントロールの作成中に、既定のBorderWidthプロパティを正しく実装しようとしているときに、スクロール バーが表示されているときの描画動作のバグに遭遇したようです: スクロール バーとコントロールの範囲の間のスペースが描画されません。

バグを再現するOnCreateには、新しいプロジェクトのメイン フォームに次のハンドラーを実装します。

procedure TForm1.FormCreate(Sender: TObject);
begin
  AutoScroll := True;
  BorderWidth := 20;
  SetBounds(10, 10, 200, 200);
  with TGroupBox.Create(Self) do
  begin
    SetBounds(300, 300, 50, 50);
    Parent := Self;
  end;
end;

D7 と XE2 の結果:

ここに画像の説明を入力

これは、Delphi XE2 でようやく修正されたようです。おそらく、このバグは にあると思われますがTWinControl.WMNCPaint、 を見てみるとControls.pas、D7 と XE2 の間の実装に大きな違いは見当たりません。

私は答えを得たいです:

  • この奇妙さに対するバグ修正の書き方、
  • このバグはどの Delphi バージョンから修正されたようです。
4

1 に答える 1

4

Delphi のどのバージョンから修正されましたか?

BorderWidthの QualityCentral での検索結果は、このバグが以前に報告されていないことを示しています。バグQC 2433 (D2010 アップデート 4 で解決済み) は関連しているようですが、コメントから、問題のバグは D2007 には存在しないことがわかります。

ただし、ここのコミュニティからの検証がさらに必要です。

バージョン < D2007 の修正方法は?

WM_NCPAINTメッセージ ハンドラをオーバーライドします。

  private
    procedure WMNCPaint(var Message: TWMNCPaint); message WM_NCPAINT;

procedure TForm1.WMNCPaint(var Message: TWMNCPaint);
{$IF CompilerVersion < 19}
var
  DC: HDC;
  WindowStyle: Longint;
  TotalBorderWidth: Integer;
{$IFEND}
begin
{$IF CompilerVersion < 19}
  DC := GetWindowDC(Handle);
  try
    WindowStyle := GetWindowLong(Handle, GWL_STYLE);
    if WindowStyle and WS_VSCROLL <> 0 then
      TotalBorderWidth := (Width - ClientWidth - GetSystemMetrics(SM_CXVSCROLL)) div 2
    else
      TotalBorderWidth := (Width - ClientWidth) div 2;
    if WindowStyle and WS_HSCROLL <> 0 then
      FillRect(DC, Rect(0, Height - TotalBorderWidth, Width, Height), Brush.Handle);
    if WindowStyle and WS_VSCROLL <> 0 then
      FillRect(DC, Rect(Width - TotalBorderWidth, 0, Width, Height), Brush.Handle);
  finally
    ReleaseDC(Handle, DC);
  end;
{$IFEND}
  inherited;
end;

描画された 2 つの四角形は意図的に大きすぎて、サイズ変更の結果が向上します。

于 2013-02-10T13:29:12.413 に答える