Search code examples
delphidelphi-2009delphi-2010

How do I send and handle message between TService parent thread and child thread?


I am using Delphi 2010 to create a Windows service that will monitor several registry keys, and perform an action when a change occurs. I am using RegMonitorThread from delphi.about.com, and my issue is that my main service thread never receives the message that is sent from the TRegMonitorThread.

type
  TMyService = class(TService)
    procedure ServiceExecute(Sender: TService);
    procedure ServiceShutdown(Sender: TService);
    procedure ServiceStart(Sender: TService; var Started: Boolean);
  private
    function main: boolean;
    { Private declarations }
  public
    function GetServiceController: TServiceController; override;
    procedure WMREGCHANGE(var Msg: TMessage); message WM_REGCHANGE;
    { Public declarations }
  end;

--

procedure TMyService.ServiceStart(Sender: TService; var Started: Boolean);
begin
    with TRegMonitorThread.Create do
    begin
        FreeOnTerminate := True;
        Wnd := ServiceThread.Handle;
        Key := 'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters';
        RootKey := HKEY_LOCAL_MACHINE;
        WatchSub := True;
        Start;
    end;
end;

Here is where I attempt to handle the message sent from the registry notification thread...but this never seems to be called.

procedure TMyService.WMREGCHANGE(var Msg: TMessage);
begin
  OutputDebugString(PChar('Registry change at ' + DateTimeToStr(Now)));
end;

I have confirmed that the message is being sent, and is reaching this point of code in the RegMonitorThread.pas unit

procedure TRegMonitorThread.Execute;
begin
  InitThread;

  while not Terminated do
  begin
    if WaitForSingleObject(FEvent, INFINITE) = WAIT_OBJECT_0 then
    begin
      fChangeData.RootKey := RootKey;
      fChangeData.Key := Key;

      SendMessage(Wnd, WM_REGCHANGE, RootKey, longint(PChar(Key)));
      ResetEvent(FEvent);

      RegNotifyChangeKeyValue(FReg.CurrentKey, 1, Filter, FEvent, 1);
    end;
  end;
end;

Any ideas on what I'm missing here? I'll mention it because it may be relevant to the problem, I am on Windows 7.


Solution

  • TServiceThread.Handle is a thread handle, not a window handle. You can't use it to receive windows messages (it is available to be used in thread management functions), you have to setup a window handle. You can find an example here: http://delphi.about.com/od/windowsshellapi/l/aa093003a.htm