Thursday, October 25, 2007

Make non TWinControl descendant response to windows messages

Although using SendMessage and PostMessage isn't a good practice in OO design. However, I do need it in some situation. All the while I wrote TWinControl descendant to handle the custom messages: W := TWinControl_Descendant.Create(nil); W.Parent := Application.MainForm; PostMessage(W.Handle, 10000, 0, 0); I got to set the Parent for the instance else the handle won't be allocated. It is troublesome if the application I wrote isn't a window form application. I raise a post in codegear newsgroup "borland.public.delphi.vcl.components.using.win32" of title "Is that possible to allocate windows handle to TObject direct descendant" and get some great replies. The TTimer component in Delphi VCL already is a good example of how to make a non TWinControl descendant response to windows messages. I then write a prototype to try out and it work as expected.
type
  TMyObject = class(TObject)
  private
    FHandle: THandle;
    procedure WndProc(var Message: TMessage);
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
    property Handle: THandle read FHandle;
  end;

procedure TMyObject.AfterConstruction;
begin
  inherited;
  FHandle := AllocateHWnd(WndProc);
end;

procedure TMyObject.BeforeDestruction;
begin
  inherited;
  DeallocateHWnd(FHandle);
end;

procedure TMyObject.WndProc(var Message: TMessage);
begin
  if Message.Msg = 10000 then
    ShowMessage('Message received')
  else
    Message.Result := DefWindowProc(FHandle, Message.Msg, Message.wParam, Message.lParam);
end;

var C: TMyObject;
begin
  C := TMyObject.Create;
  try
    SendMessage(C.Handle, 10000, 0, 0);
  finally
    C.Free;
  end;
end;

No comments: