События Delphi, TVirtualStringTree, WM_SIZE при изменении размера столбцов - PullRequest
2 голосов
/ 29 апреля 2019

У меня есть потомок класса TVirtualStringTree с моей собственной процедурой авторазмера столбцов.Чтобы заставить его работать всякий раз, когда изменяется размер элемента управления, я переопределил процедуру 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;

Все работает отлично, кроме одной вещи: изменение размера столбцов вручную (с помощью мыши на заголовке) без изменения фактическогоРазмер элемента управления вызывает генерацию нежелательных WM_SIZE событий с разными LParams (размер элемента управления).И, таким образом, вызывается Resize, и столбцы автоматически корректируют свою ширину, что я не имел в виду.Как сделать так, чтобы авторазмер работал только при фактическом изменении ширины элемента управления?

1 Ответ

3 голосов
/ 30 апреля 2019

Вы можете добавить логический флаг FColumnResize, который вы установите на True в методе DoColumnResize.

В методе 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, вероятно, лучше переопределить и установить FColumnResize в True в DoHeaderMouseDown и обратно в False в DoHeaderMouseUp. в этом случае удалите FColumnResize := False в методе Resize.

...