Delphi、TVirtualStringTree、WM_SIZE 调整列大小时的事件
Delphi, TVirtualStringTree, WM_SIZE events when resizing columns
我有一个 TVirtualStringTree
class 的后代,使用我自己的自动调整列大小程序。为了使其在控件大小更改时起作用,我覆盖了 Resize
过程:
type
TMyVirtualStringTree = class(TVirtualStringTree)
protected
procedure Resize; override;
end;
.....
procedure TMyVirtualStringTree.Resize;
var
cb: Integer;
begin
inherited;
if Header.Columns.Count > 0 then
for cb := 0 to Header.Columns.Count - 1 do
Header.Columns[cb].Width := round((Width - 20) / Header.Columns.Count);
end;
一切正常,除了一件事:手动调整列的大小(通过 header 上的鼠标)而不更改控件的实际大小会导致生成不需要的 WM_SIZE
具有不同 LParams(控件大小)的事件.因此 Resize
被调用并且列自动调整它们的宽度,我不是故意的。如何让 autosize 只在控件宽度实际改变时才起作用?
您可以添加一个布尔标志 FColumnResize
,您在 DoColumnResize
方法中将其设置为 True
。
在 Resize
方法中检查标志,即:
type
TVirtualStringTree = class(VirtualTrees.TVirtualStringTree)
protected
FColumnResize: Boolean;
procedure Resize; override;
procedure DoColumnResize(Column: TColumnIndex); override;
end;
...
procedure TVirtualStringTree.DoColumnResize(Column: TColumnIndex);
begin
inherited;
FColumnResize := True;
end;
procedure TVirtualStringTree.Resize;
var
cb: Integer;
begin
inherited;
if not FColumnResize then
begin
Header.Columns.BeginUpdate; { Important: do not trigger OnColumnResize }
try
if Header.Columns.Count > 0 then
for cb := 0 to Header.Columns.Count - 1 do
Header.Columns[cb].Width := round((Width - 20) / Header.Columns.Count);
finally
Header.Columns.EndUpdate;
end;
end;
FColumnResize := False;
end;
另一个选项而不是覆盖 DoColumnResize
可能更好的做法是在 DoHeaderMouseDown
中覆盖并将 FColumnResize
设置为 True
,然后返回到 False
DoHeaderMouseUp
。在这种情况下,删除 Resize
方法中的 FColumnResize := False
。
我有一个 TVirtualStringTree
class 的后代,使用我自己的自动调整列大小程序。为了使其在控件大小更改时起作用,我覆盖了 Resize
过程:
type
TMyVirtualStringTree = class(TVirtualStringTree)
protected
procedure Resize; override;
end;
.....
procedure TMyVirtualStringTree.Resize;
var
cb: Integer;
begin
inherited;
if Header.Columns.Count > 0 then
for cb := 0 to Header.Columns.Count - 1 do
Header.Columns[cb].Width := round((Width - 20) / Header.Columns.Count);
end;
一切正常,除了一件事:手动调整列的大小(通过 header 上的鼠标)而不更改控件的实际大小会导致生成不需要的 WM_SIZE
具有不同 LParams(控件大小)的事件.因此 Resize
被调用并且列自动调整它们的宽度,我不是故意的。如何让 autosize 只在控件宽度实际改变时才起作用?
您可以添加一个布尔标志 FColumnResize
,您在 DoColumnResize
方法中将其设置为 True
。
在 Resize
方法中检查标志,即:
type
TVirtualStringTree = class(VirtualTrees.TVirtualStringTree)
protected
FColumnResize: Boolean;
procedure Resize; override;
procedure DoColumnResize(Column: TColumnIndex); override;
end;
...
procedure TVirtualStringTree.DoColumnResize(Column: TColumnIndex);
begin
inherited;
FColumnResize := True;
end;
procedure TVirtualStringTree.Resize;
var
cb: Integer;
begin
inherited;
if not FColumnResize then
begin
Header.Columns.BeginUpdate; { Important: do not trigger OnColumnResize }
try
if Header.Columns.Count > 0 then
for cb := 0 to Header.Columns.Count - 1 do
Header.Columns[cb].Width := round((Width - 20) / Header.Columns.Count);
finally
Header.Columns.EndUpdate;
end;
end;
FColumnResize := False;
end;
另一个选项而不是覆盖 DoColumnResize
可能更好的做法是在 DoHeaderMouseDown
中覆盖并将 FColumnResize
设置为 True
,然后返回到 False
DoHeaderMouseUp
。在这种情况下,删除 Resize
方法中的 FColumnResize := False
。