В статье мы рассмотрим, как изменить поведение кнопок Caption bar (Maximize и Minimize) в Delphi с использованием сообщения WM_NCHitTest. Мы также обсудим, как можно вызывать один обработчик сообщений из другого, не дублируя код.
Введение
В Delphi, обработчики сообщений (message handlers) — это методы, которые вызываются, когда приложение получает определенное сообщение от Windows. Обычно эти методы объявляются в виде процедур с параметром var Msg: TMessage, который содержит информацию о сообщении.
В некоторых случаях может возникнуть необходимость вызвать один обработчик сообщений из другого. Например, вы можете захотеть выполнить некоторые действия, основанные на результате обработки другого сообщения. Вопрос, который мы рассмотрим в этой статье, заключается в том, как это сделать, не дублируя код в обоих обработчиках.
Пример: Изменение поведения Caption bar button
Рассмотрим пример, в котором мы хотим изменить поведение кнопок Maximize и Minimize Caption bar. Мы хотим, чтобы при нажатии на эти кнопки высота окна устанавливалась в определенное значение, а ширина — в 0 (чтобы окно занимало только необходимую высоту). Кроме того, мы хотим, чтобы при наведении курсора на Caption bar отображался текст "« или »", в зависимости от того, где находится курсор.
Для реализации этого поведения мы можем использовать обработчики сообщений WM_SYSCOMMAND и WM_NCHITTEST. Обработчик WM_SYSCOMMAND вызывается, когда пользователь нажимает на кнопки Maximize или Minimize, а обработчик WM_NCHITTEST — когда курсор находится над Caption bar.
Вот пример кода, который реализует это поведение:
procedure TForm1.WMSysCommand(var Msg: TMessage);
begin
if (Msg.WParam = SC_MAXIMIZE) or (Msg.Result = HTCAPTION) then
begin
if CheckWin32Version(6, 0) then
Constraints.MaxHeight := 507
else
Constraints.MaxHeight := 499;
Constraints.MaxWidth := 0;
end
else if (Msg.WParam = SC_MINIMIZE) or (Msg.Result = HTCAPTION) then
begin
if (EnsureRange(Width, 252, 510) >= (510 / 2)) then
PreviewOpn.Caption := '<'
else
PreviewOpn.Caption := '>';
end;
inherited;
end;
procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest);
begin
if Msg.HTResult = HTCAPTION then
begin
Msg.Result := HTCLIENT;
Msg.HTResult := HTCLIENT;
end;
end;
В этом примере обработчик WM_SYSCOMMAND проверяет, была ли нажата кнопка Maximize или Minimize, или курсор находился над Caption bar. В зависимости от этого, он устанавливает ограничения на высоту и ширину окна и меняет текст на кнопке PreviewOpn.
Обработчик WM_NCHITTEST проверяет, находится ли курсор над Caption bar, и если да, то меняет результат сообщения на HTCLIENT, чтобы указать, что курсор находится внутри клиентской области окна.
Вызов одного обработчика сообщений из другого
Теперь давайте рассмотрим, как вызвать один обработчик сообщений из другого, не дублируя код. Например, мы хотим, чтобы обработчик WM_SYSCOMMAND выполнил некоторые действия, основанные на результате обработки сообщения WM_NCHITTEST.
Один из способов сделать это — использовать процедуру Perform, которая позволяет вызывать обработчик сообщений напрямую, без отправки сообщения через Windows-очередь сообщений. Вот пример кода, который демонстрирует этот подход:
procedure TForm1.WMSysCommand(var Msg: TMessage);
var
Hit: Longint;
begin
Hit := Perform(TForm1, WM_NCHITTEST, Msg.LParam, Msg.Result);
if (Msg.WParam = SC_MAXIMIZE) or (Hit = HTCAPTION) then
begin
if CheckWin32Version(6, 0) then
Constraints.MaxHeight := 507
else
Constraints.MaxHeight := 499;
Constraints.MaxWidth := 0;
end
else if (Msg.WParam = SC_MINIMIZE) or (Hit = HTCAPTION) then
begin
if (EnsureRange(Width, 252, 510) >= (510 / 2)) then
PreviewOpn.Caption := '<'
else
PreviewOpn.Caption := '>';
end;
inherited;
end;
В этом примере мы вызываем процедуру Perform, передавая ей идентификатор сообщения WM_NCHITTEST, параметры сообщения и результат сообщения. Результат этого вызова мы храним в переменной Hit, которую затем используем в условиях, проверяющих, была ли нажата кнопка Maximize или Minimize, или курсор находился над Caption bar.
Заключение
В этой статье мы рассмотрели, как изменить поведение кнопок Caption bar (Maximize и Minimize) в Delphi с использованием сообщения WM_NCHITTEST. Мы также обсудили, как можно вызывать один обработчик сообщений из другого, не дублируя код. Используя процедуру Perform, мы можем вызывать один обработчик сообщений напрямую, основываясь на результате другого обработчика сообщений.
Надеюсь, эта статья поможет вам эффективно работать с обработчиками сообщений в Delphi.
В статье описывается, как изменить поведение кнопок Caption bar (Maximize и Minimize) в Delphi с использованием сообщения WM\_NCHitTest и как вызывать один обработчик сообщений из другого без дублирования кода.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS