7

I need to send a windows message to a TDataModule in my Delphi 2010 app.

I would like to use

PostMessage(???.Handle, UM_LOG_ON_OFF, 0,0);

Question:

The TDataModule does not have a Handle. How can I send a windows message to it?

Fabrizio
  • 7,603
  • 6
  • 44
  • 104
Charles Faiga
  • 11,665
  • 25
  • 102
  • 139

2 Answers2

10

You can give it a handle easily enough. Take a look at AllocateHWND in the Classes unit. Call this to create a handle for your data module, and define a simple message handler that will process UM_LOG_ON_OFF.

Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477
  • Does AllocateHWND just create a hidden window? – Gregor Brandt Aug 23 '10 at 22:48
  • @gbrandt: It creates a *window handle,* which is not quite the same thing. All visual controls must have a window handle in order to receive messages and handle their own drawing, (and visual controls without a handle can't draw themselves or receive messages,) but not every handle neds to be bound to a visual element. – Mason Wheeler Aug 23 '10 at 23:56
  • 1
    @gbrandt: Have a look at this link http://www.delphidabbler.com/articles?article=1 on "How a non-windowed component can receive messages from Windows" – Charles Faiga Aug 24 '10 at 08:14
  • 4
    Note that the AllocateHWND of the Forms unit is deprecated. Use the one available in Classes instead. And yes, AllocateHWND creates an hidden window, but in the sense of the Windows API, not in the sense of a Delphi TForm: this window is an API handle, which is used to receive GDI messages. – A.Bouchez Aug 24 '10 at 12:25
1

Here is an example demonstrating how to create a TDataModule's descendant with an Handle

uses
  Windows, Winapi.Messages,
  System.SysUtils, System.Classes;

const
  UM_TEST = WM_USER + 1;

type
  TMyDataModule = class(TDataModule)
  private
    FHandle: HWND;
  protected
    procedure   WndProc(var Message: TMessage); virtual;
  public
    constructor Create(AOwner : TComponent); override;
    destructor  Destroy(); override;
    property    Handle : HWND read FHandle;
  end;

...

uses
  Vcl.Dialogs;

constructor TMyDataModule.Create(AOwner : TComponent);
begin
  inherited;

  FHandle := AllocateHWND(WndProc);
end;

destructor  TMyDataModule.Destroy();
begin
  DeallocateHWND(FHandle);

  inherited;
end;

procedure   TMyDataModule.WndProc(var Message: TMessage);
begin
  if(Message.Msg = UM_TEST) then
  begin
    ShowMessage('Test');
  end;
end;

Then we can send messages to the datamodule, like this:

procedure TForm1.Button1Click(Sender: TObject);
begin
  PostMessage(MyDataModule.Handle, uMyDataModule.UM_TEST, 0, 0);
end;
Fabrizio
  • 7,603
  • 6
  • 44
  • 104