Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Messages in Non-Windowed Classes - need a default handler?

With a class (TObject) I have :

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

where TH_MYMESSAGE = WM_USER + 1

In the class constructor:

FHwnd := AllocateHWND(HandleMyMessage);

The only object which receives a reference to FHwnd is a private custom TThread (created within this class) and the only message it posts is TH_MYMESSAGE. My understanding is that the message directive in the procedure declaration restricts its handling to only TH_MYMESSAGE.

This was working fine in testing, but upon integration into a much larger application I am getting feedback that HandleMyMessage is firing for other messages as well (with obvious undesired results).

This was easily corrected by adding if Message.Msg <> TH_MYMESSAGE then Exit; in HandleMyMessage. My question is : Why is this happening?

My best guess is that AllocateHWND has made HandleMyMessage the equivalent of a DefWndProc despite it having the message directive. Is there a correct way to implement this which I'm missing?

like image 565
J... Avatar asked Jun 06 '12 12:06

J...


1 Answers

Well, yes of course. AllocateHWnd accepts a TWndMethod to act as the window procedure of the created window. The confusion, I guess, is caused by that the compiler accepts the messsage directive. Don't put it:

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;


edit: (Response to comment). To have the message handled on the class that created the utility window, you can route your message from the window AllocateHWnd creates to your class:
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;
like image 83
Sertac Akyuz Avatar answered Nov 12 '22 06:11

Sertac Akyuz