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 版本修复?

在 QualityCentral on BorderWidth中的搜索结果显示之前没有报告过此错误。错误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;

两个绘制的矩形故意太大,在调整大小时给出更好的结果。

于 2013-02-10T13:29:12.413 回答