gpt4 book ai didi

delphi - 如何在 Windows 服务中收到时间更改通知

转载 作者:行者123 更新时间:2023-12-03 15:22:14 24 4
gpt4 key购买 nike

我创建了一个 WindowProc 来接收系统时间更改的通知:

constructor TJJWScheduler.Create;
begin
fTimeChangeWnd := Classes.AllocateHWnd(TimeChangeWndProc);
end;

procedure TJJWScheduler.TimeChangeWndProc(var msg: TMessage);
var
i: integer;
begin
case msg.Msg of
WM_TIMECHANGE:
begin
// my things
end;
end;
end;

此代码在 Windows 服务内运行。问题是当我更改系统时间时它不会被触发!

为什么广播消息(WM_TIMECHANGE)没有传递到我的窗口?还有另一种方法可以在不循环的情况下执行此操作吗?

<小时/>

编辑

我不知道为什么,但我硬编码了 PeekMessage 来处理发送到该窗口的消息,并且一切正常。下面的代码解决了我的问题:

 var 
msg: TMsg;

if PeekMessage(msg, fTimeChangeWnd, WM_TIMECHANGE, WM_TIMECHANGE, PM_REMOVE) then
begin
TranslateMessage(msg);
DispatchMessage(msg);
end;

这种解决方法非常奇怪,因为我已经有其他窗口处理消息(通过通用 ProcessMessages),只有这个没有处理其消息。

最佳答案

您的窗口未收到 WM_TIMECHANGE 消息的原因是您的窗口是从辅助线程创建的。

进程中的每个线程都有自己的消息队列。当您为消息队列提供服务时,就会传递同步消息,因此对于像 WM_TIMECHANGE 这样的非排队消息,您确实需要为辅助线程消息队列提供服务,以便传递消息。

例如,查看 GetMessage 的文档,最常见的拉取队列消息的方式:

The function dispatches incoming sent messages until a posted message is available for retrieval.

PeekMessage 也是如此。它在查看队列之前调度传入的已发送消息。

还有一些其他方法可以分派(dispatch)已发送的消息,但这些是主要的方法。

现在,我怀疑您定期从辅助线程发送消息可能会很不方便。如果辅助线程不执行任何其他操作,那么它可以简单地位于传统的 GetMessage、TranslateMessage、DispatchMessage 循环中。大多数时候,它会愉快地阻止 GetMessage 调度任何传入的已发送消息。但是,如果您的辅助线程执行更多工作,那么这可能不是一个可行的选择。

您已经在主服务线程上运行并服务消息队列。让您的监听器窗口与主服务线程具有亲和性可能更有意义。通过从主服务线程中运行的代码创建它来做到这一点。

另请注意,AllocateHWnd 被记录为不是线程安全的。您不得从进程主线程以外的任何线程调用它。因此,如果您确实希望保留在辅助线程上,则需要使用 CreateWindow 而不是 AllocateHWnd。但这也许是将此窗口移至主线程的另一个好理由。

关于delphi - 如何在 Windows 服务中收到时间更改通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14872757/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com