我正在开发一个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个线程正在运行,一个是使用不同消息号的计时器,并且在发生这种情况时不发送任何内容。
答案 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唯一性。