Windows notification for change of the periodic time adjustment
Can I monitor changes to the System Time Adjustment (which is change by SetSystemTimeAdjustment()
)?
I need to monitor s开发者_如何学编程uch changes for a high-accuracy real-time spectrogram view.
Note:
I know that WM_TIMECHANGE
is sent whenever the system time is changed. This is not what I'm asking for.
This MSDN Magazine article indicates that there is no notification mechanism in the OS - you need to monitor changes by polling GetSystemTimeAdjustment()
. From "Implementing a Continuously Updating, High-Resolution Time Provider for Windows" by Johan Nilsson (MSDN Magazine, March 2004):
There are a couple of problems with this, though. The first is that enabling (and changing) the time adjustment alters your reference frequency—the flow of time. The second, which is a bigger problem, is that there is no notification sent by the system when the time adjustment is changed, enabled, or disabled. Changing the time adjustment even by the minimum possible increment (one 100-nanosecond unit) on a system with a default time increment of 156250 units causes a change in the reference frequency of 6.4 PPM (1/156250). Once again, this might not sound like much, but considering that you might want to keep within 50 microseconds from the system time, it could mean that you exceed that limit after a few seconds without resynchronization.
To lessen the impact of such adjustments, the time provider has to monitor the current time adjustment settings. With no help from the operating system itself, this is implemented by calling the
SetSystemTimeAdjustment
companion APIGetSystemTimeAdjustment
. By performing this check repeatedly at short enough intervals and adjusting the internal frequency as needed, you can avoid drifting too far from the system time.
It's possible that there's been OS-level support for notification added since the article was published, but I didn't find anything documented.
I'd assume that WM_TIMECHANGE is send to WndProc(), so you will want to override WndProc SOMETHING like this:
public override void WndProc(ref Message m) {
if(m==WM_TIMECHANGE) {
//dostuff
}
base.WndProc();
}
精彩评论