重绘前如何控制黑底?
How to prevent black background under control before it is repainted?
屏幕截图是在 window 激活期间截取的。可以看出,一些控件首先被涂上了黑色背景。它们是 TCheckBox、TButton、TStringGrid。我希望控件下的黑色区域具有 clBtnFace 形式的颜色。我该如何解决这个问题?
编辑:
它发生在 VCL,Delphi 10.3.3,Windows 10。
通过 window 激活,我的意思是该应用程序已经 运行 并且已最小化到任务栏。表单上只有很多控件。有7个TPanels,可以看到大约60个TEdits,旁边还有大约60个TLabels还没有画,剩下的黑色背景是几个TCheckBoxes,TButtons和一个空的TStringGrid。
使用空表单进行测试,放置一个 TPanel 并在其上面放置 300 个 TEdits,并且行为相同。因此,根据设计,某些控件首先使用黑色背景绘制。那么我怎样才能将默认背景颜色更改为其他颜色呢?
编辑2:
在表单上测试了 400 个 TPanel。这些是按预期绘制的,没有将 TPanel 下的 Rect 设置为黑色。
编辑3:
不幸的是,1000 个 TPanel 的表单重绘速度足够慢,所以我能够观察到黑色背景。
这是我用来测试控件的代码:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.ExtCtrls, Vcl.StdCtrls;
const
ControlsNum=800;
Columns=40;
type
TControlTestList=array of TButton;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
var CList:TControlTestList;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
W,H:integer;
begin
Self.Width:=1400;
Self.Height:=800;
W:=Self.ClientWidth div Columns;
H:=Self.ClientHeight div (ControlsNum div Columns);
SetLength(CList,ControlsNum);
for i:=0 to ControlsNum-1 do
begin
CList[i]:=TButton.Create(Self);
with (CList[i] as TButton) do
begin
Parent:=Self;
Top:=H*(i div Columns);
Left:=W*(i mod Columns);
Width:=W;
Height:=H;
Caption:=IntToStr(i);
end;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
i:integer;
begin
for i:=0 to Length(CList)-1 do FreeAndNil(CList[i]);
SetLength(CList,0);
end;
end.
编辑4:
On Windows 10: 在任何类型的表单调整大小时,控件下的黑色背景都不会出现。只有当 window 的最小化并把它带回来时才完成。
在 Windows 8.1:调整表单大小时也会出现黑色背景。
试试这个:
interface
TForm1 = class(TForm)
....
protected
procedure CreateParams(var Params: TCreateParams); override;
public
....
end;
implementation
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WindowClass.hbrBackground := COLOR_BTNFACE + 1;
end;
屏幕截图是在 window 激活期间截取的。可以看出,一些控件首先被涂上了黑色背景。它们是 TCheckBox、TButton、TStringGrid。我希望控件下的黑色区域具有 clBtnFace 形式的颜色。我该如何解决这个问题?
编辑: 它发生在 VCL,Delphi 10.3.3,Windows 10。 通过 window 激活,我的意思是该应用程序已经 运行 并且已最小化到任务栏。表单上只有很多控件。有7个TPanels,可以看到大约60个TEdits,旁边还有大约60个TLabels还没有画,剩下的黑色背景是几个TCheckBoxes,TButtons和一个空的TStringGrid。
使用空表单进行测试,放置一个 TPanel 并在其上面放置 300 个 TEdits,并且行为相同。因此,根据设计,某些控件首先使用黑色背景绘制。那么我怎样才能将默认背景颜色更改为其他颜色呢?
编辑2: 在表单上测试了 400 个 TPanel。这些是按预期绘制的,没有将 TPanel 下的 Rect 设置为黑色。
编辑3: 不幸的是,1000 个 TPanel 的表单重绘速度足够慢,所以我能够观察到黑色背景。
这是我用来测试控件的代码:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.ExtCtrls, Vcl.StdCtrls;
const
ControlsNum=800;
Columns=40;
type
TControlTestList=array of TButton;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
var CList:TControlTestList;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
W,H:integer;
begin
Self.Width:=1400;
Self.Height:=800;
W:=Self.ClientWidth div Columns;
H:=Self.ClientHeight div (ControlsNum div Columns);
SetLength(CList,ControlsNum);
for i:=0 to ControlsNum-1 do
begin
CList[i]:=TButton.Create(Self);
with (CList[i] as TButton) do
begin
Parent:=Self;
Top:=H*(i div Columns);
Left:=W*(i mod Columns);
Width:=W;
Height:=H;
Caption:=IntToStr(i);
end;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
i:integer;
begin
for i:=0 to Length(CList)-1 do FreeAndNil(CList[i]);
SetLength(CList,0);
end;
end.
编辑4: On Windows 10: 在任何类型的表单调整大小时,控件下的黑色背景都不会出现。只有当 window 的最小化并把它带回来时才完成。 在 Windows 8.1:调整表单大小时也会出现黑色背景。
试试这个:
interface
TForm1 = class(TForm)
....
protected
procedure CreateParams(var Params: TCreateParams); override;
public
....
end;
implementation
procedure TForm1.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WindowClass.hbrBackground := COLOR_BTNFACE + 1;
end;