Подтвердить что ты не робот

Пользовательские сообщения в не-оконных классах - нужен обработчик по умолчанию?

С классом (TObject) у меня есть:

private
  FHwnd : HWND;
  procedure HandleMyMessage(var Message : TMessage); message TH_MYMESSAGE;

где TH_MYMESSAGE = WM_USER + 1

В конструкторе класса:

FHwnd := AllocateHWND(HandleMyMessage);

Единственным объектом, который получает ссылку на FHwnd, является частный пользовательский TThread (созданный в этом классе), и единственным сообщением, которое он публикует, является TH_MYMESSAGE. Я понимаю, что директива message в объявлении процедуры ограничивает ее обработку только TH_MYMESSAGE.

Это отлично работает при тестировании, но после интеграции в гораздо более крупное приложение, я получаю обратную связь, что HandleMyMessage запускает и другие сообщения (с очевидными нежелательными результатами).

Это было легко исправлено, добавив if Message.Msg <> TH_MYMESSAGE then Exit; в HandleMyMessage. Мой вопрос: почему это происходит?

Мое лучшее предположение состоит в том, что AllocateHWND сделал HandleMyMessage эквивалент a DefWndProc, несмотря на то, что он имеет директиву message. Есть ли правильный способ реализовать это, что мне не хватает?

4b9b3361

Ответ 1

Ну да, конечно. AllocateHWnd принимает TWndMethod, чтобы действовать как оконная процедура созданного окна. Путаница, я думаю, вызвана тем, что компилятор принимает директиву messsage. Не ставьте:

private
  FHwnd : HWND;
  procedure HandleMyMessage(var Message : TMessage);

..

procedure TMyClass.HandleMyMessage(var Message: TMessage);
begin
  case Message.Msg of
    TH_MYMESSAGE: //
  end;
  Message.Result := DefWindowProc(FHWnd, Message.Msg, Message.WParam, Message.LParam);
end;


изменить: (ответ на комментарий). Чтобы сообщение обрабатывалось классом, создавшим окно утилиты, вы можете перенаправить свое сообщение из окна AllocateHWnd, созданного в ваш класс:
private
  FHwnd : HWND;
  procedure HandleMyMessage(var Message : TMessage);
  procedure THMyMessage(var Message: TMessage); message TH_MYMESSAGE;

..

procedure TMyClass.HandleMyMessage(var Message: TMessage);
begin
  case Message.Msg of
    TH_MYMESSAGE: Dispatch(Message);
  end;
  Message.Result := DefWindowProc(FHWnd, Message.Msg, Message.WParam, Message.LParam);
end;

procedure TMyClass.THMyMessage(var Message: TMessage);
begin
  //
end;