Как определить END изменения размера формы, возможно, с помощью компонента TApplicationEvents?

В приложении Delphi 10.4 VCL мне нужно определить, когда FORM RESIZING ENDS. (Например, после того, как пользователь изменил размер формы, перетащив ее размер).

Итак, я поместил на форму компонент TApplicationEvents и создал его обработчик событий OnMessage, пытаясь перехватить сообщение WM_EXITSIZEMOVE:

procedure TformMain.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  if (Msg.Message = WM_EXITSIZEMOVE) then
  begin
    CodeSite.Send('TformMain.ApplicationEvents1Message: WM_EXITSIZEMOVE');
  end;
end;

Но обработчик события с WM_EXITSIZEMOVE не выполняется после изменения размера формы.

Итак, как я могу определить END изменения размера формы, возможно, с помощью компонента TApplicationEvents?


person user1580348    schedule 18.08.2020    source источник


Ответы (1)


Сообщение WM_EXITSIZEMOVE отправлено прямо в окно. Таким образом, он не обнаруживается обработчиком TApplicationEvents OnMessage, потому что при этом обнаруживаются только те сообщения, которые отправлены в основную очередь сообщений.

Итак, вместо этого вам нужно переопределить WndProc() формы:

type
  TForm1 = class(TForm)
  private
  protected
    procedure WndProc(var Message: TMessage); override;
  public
  end;

implementation

procedure TForm1.WndProc(var Message: TMessage);
begin
  inherited;
  case Message.Msg of
    WM_EXITSIZEMOVE:
      ShowMessage('Yes!');
  end;
end;

Или вместо этого можно использовать message процедуру:

type
  TForm1 = class(TForm)
  private
  protected
    procedure WMExitSizeMove(var Message: TMessage); message WM_EXITSIZEMOVE;
  public
  end;

implementation

procedure TForm1.WMExitSizeMove(var Message: TMessage);
begin
  inherited;
  ShowMessage('Yes!');
end;

Однако имейте в виду, что это сообщение, как следует из его названия, отправляется не только при изменении размера окна, но и после его перемещения. И в обоих случаях только тогда, когда операция включала модальный цикл.

Например, если вы развернете окно, дважды щелкнув его строку заголовка, или переместите его на другой экран, нажав Shift+Win+Вправо< /kbd> это сообщение вообще не отправляется.

person Andreas Rejbrand    schedule 18.08.2020
comment
В случае максимизации и движения клавиатуры вместо этого вы можете перехватывать другие сообщения, например WM_SYSCOMMAND, WM_MOV(ING|E), WM_WINDOWPOSCHANG(ING|ED). Обратите внимание, что есть также WM_SIZ(ING|E) сообщения. - person Remy Lebeau; 19.08.2020
comment
Чтобы различать ПЕРЕМЕЩЕНИЕ и ИЗМЕНЕНИЕ РАЗМЕРА формы, мне нужно СРАВНИТЬ размер формы ДО того, как он начнет изменять размер, и ПОСЛЕ того, как он был изменен. (Меня интересует только ИЗМЕНЕНИЕ РАЗМЕРА). Итак, как я могу поймать начало изменения размера формы (непосредственно перед тем, как она начала изменять размер)? - person user1580348; 19.08.2020
comment
@user1580348: WM_ENTERSIZEMOVE, наверное? - person Andreas Rejbrand; 19.08.2020