Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Оптимизация работы TSplitter при изменении размера родительского окна в Delphi

Delphi , Компоненты и Классы , TSplitter

Оптимизация работы TSplitter при изменении размера родительского окна в Delphi

При работе с компонентом TSplitter в Delphi может возникнуть проблема, когда несколько экземпляров TSplitter некорректно реагируют на изменение размера родительского окна. В данной статье мы рассмотрим, как решить эту проблему и обеспечить корректную работу всех экземпляров TSplitter.

Проблема

При использовании нескольких экземпляров TSplitter на форме, только один из них правильно реагирует на изменение размера родительского окна. Это происходит из-за того, что в методе SetParent только для первого экземпляра TSplitter устанавливается обработчик сообщений для родительского окна.

Решение

Для решения этой проблемы можно воспользоваться техникой наследования и переопределения метода SetParent для класса TSplitter. В методе SetParent устанавливаем обработчик сообщений для родительского окна для всех экземпляров TSplitter.

Ниже представлен пример кода, решающий данную проблему:

unit ProportionalSplitterU;

interface

uses
  Windows, SysUtils, Controls, Messages, Classes, CommCtrl, ExtCtrls;

type
  TSPlitterHelper = class helper for TSplitter
  public
    function FindControlEx: TControl;
  end;

  TProportionalSplitter = class(TSplitter)
  private
    FOldWindowProc: TWndMethod;
    FControlRatio: Double;
    FProportionalResize: Boolean;

    procedure SubclassedParentWndProc(var Msg: TMessage);
    procedure SetRatio;
    procedure SetProportionalResize(const Value: Boolean);
  protected
    procedure SetParent(AParent: TWinControl); override;
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure StopSizing; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property ProportionalResize: Boolean read FProportionalResize write SetProportionalResize;
  end;

implementation

{ TProportionalSplitter }

constructor TProportionalSplitter.Create(AOwner: TComponent);
begin
  inherited;
  FProportionalResize := True;
end;

procedure TProportionalSplitter.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited;

  if (Operation = opRemove) and (AComponent = Parent) then
  begin
    Parent.WindowProc := FOldWindowProc;
    FOldWindowProc := nil;
  end;
end;

procedure TProportionalSplitter.SetParent(AParent: TWinControl);
begin
  FControlRatio := -1;

  if Assigned(Parent) then
    Parent.WindowProc := FOldWindowProc;

  inherited SetParent(AParent);

  if Assigned(AParent) then
  begin
    FOldWindowProc := Parent.WindowProc;
    Parent.WindowProc := SubclassedParentWndProc;
    SetRatio;
  end;
end;

procedure TProportionalSplitter.SetProportionalResize(const Value: Boolean);
begin
  FProportionalResize := Value;
  SetRatio;
end;

procedure TProportionalSplitter.SetRatio;
var
  ActiveControl: TControl;
begin
  if FProportionalResize then
  begin
    ActiveControl := FindControlEx;

    if (Parent <> nil) and (ActiveControl <> nil) then
    begin
      case Align of
        alTop, alBottom: FControlRatio := ActiveControl.Height / Parent.Height;
        alLeft, alRight: FControlRatio := ActiveControl.Width / Parent.Width;
      end;
    end;
  end
  else
    FControlRatio := -1;
end;

procedure TProportionalSplitter.StopSizing;
begin
  inherited;
  SetRatio;
end;

procedure TProportionalSplitter.SubclassedParentWndProc(Var Msg: TMessage);
begin
  FOldWindowProc(Msg);

  if Msg.Msg = WM_SIZE then
  begin
    if FControlRatio <> -1 then
    begin
      case Align of
        alTop, alBottom: FindControlEx.Height := Round(Parent.Height * FControlRatio);
        alLeft, alRight: FindControlEx.Width := Round(Parent.Width * FControlRatio);
      end;
    end
    else
      SetRatio;
  end;
end;

{ TSPlitterHelper }

function TSPlitterHelper.FindControlEx: TControl;
begin
  Result := Self.FindControl;
end;

end.

В данном примере класс TProportionalSplitter наследуется от класса TSplitter и переопределяет метод SetParent. В методе SetParent устанавливаем обработчик сообщений для родительского окна для всех экземпляров TSplitter, что позволяет им корректно реагировать на изменение размера родительского окна.

Также в примере представлен класс TSPlitterHelper, который является вспомогательным классом для TSplitter и содержит метод FindControlEx, который используется для получения активного контрола.

Использование данного решения позволит вам добиться корректной работы всех экземпляров TSplitter при изменении размера родительского окна в Delphi.

Создано по материалам из источника по ссылке.

В статье рассматривается решение проблемы корректной работы нескольких экземпляров TSplitter при изменении размера родительского окна в Delphi с помощью наследования и переопределения методов.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: TSplitter ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-10-22 09:33:02/0.0036630630493164/0