GetMessage中的wparam值不是我的预期(Delphi XE4)

时间:2015-02-27 18:37:56

标签: multithreading delphi delphi-xe4 getmessage

我正在开发一个Delphi XE4服务应用程序。该服务为一些长时间运行的任务启动线程,线程通过PostThreadMessage调用回传状态。

主ServiceExecute循环如下所示:

procedure TScanService.ServiceExecute(Sender: TService);
var
  CurrentMessage: TMsg;
begin
  LogServerEvent('ServiceExecute', 'Starting');
  while not Terminated do
  begin
    if not PeekMessage(CurrentMessage, 0, WM_NULL, msgHigh, PM_NOREMOVE) then
    begin
      Sleep(1000);
      Continue;
    end;

    GetMessage(CurrentMessage, 0, WM_NULL, msgHigh);

    LogServerEvent('ServiceExecute', 'CurrentMessage.message', IntToStr(CurrentMessage.message));
    LogServerEvent('ServiceExecute', 'CurrentMessage.wParam', IntToStr(CurrentMessage.wParam));
    LogServerEvent('ServiceExecute', 'CurrentMessage.lParam', IntToStr(CurrentMessage.lParam));

在线程中,发送消息如下所示:

    gThreadNumber: Integer;

    LogThreadEvent('Execute', 'Found Notice, Thread number: ' + IntToStr(gThreadNumber));
    PostThreadMessage(ParentThreadID, msgFound, gThreadNumber, 6);

消息到达正常,消息号正确(msgFound = WM_USER + 1);但是,我为wParam,lParam发送了0,6,而我收到的是4,0。我错过了什么?

注意:代码只有2个线程正在运行,一个是使用不同消息号的计时器,并且在发生这种情况时不发送任何内容。

1 个答案:

答案 0 :(得分:0)

TService代码中,您可以找到以下代码:

const
  CM_SERVICE_CONTROL_CODE = WM_USER + 1;
....
procedure TService.Controller(CtrlCode: DWord);
begin
  PostThreadMessage(ServiceThread.ThreadID, CM_SERVICE_CONTROL_CODE, CtrlCode, 0);
  if ServiceThread.Suspended then ServiceThread.Resume;
end;

因此TService正在发送与您的消息具有相同消息编号的消息。你怎么能分开他们?好吧,你不能。

来自WM_USER的文档:

  

用于定义私有窗口类使用的私有消息,通常格式为WM_USER + x,其中x是整数值。

通常这将用于发送到窗口的消息,并且消息的含义将是特定于类的。当我阅读TService代码时,设计人员认为他们完全控制了消息队列,并有权确定其私人消息的含义。最终结果是,您无法在WM_USER范围内使用线程消息,因为它们已由TService类保留。

您的主要选择:

  • 将您的消息发送到窗口。
  • 使用RegisterWindowMessage确保消息ID唯一性。
  • 停止使用Windows消息(不是特别用于服务)并使用其他机制进行通信。