找回密码
 加入
搜索
查看: 3639|回复: 7

请教一下,如何截获系统时间更改事件

[复制链接]
发表于 2009-3-6 22:11:41 | 显示全部楼层 |阅读模式
RT
查了一下系统消息代码,好像是
WM_TIMECHANGE
但具体是怎么截取?
另外,从网上找到一段VB的代码,能有高人将其转为AU3吗?
´窗体form1(需要一个timer控件,interval=1000):

Private Sub Form_Load()
Timer1_Timer
RegisterWindow Me.hwnd ´为窗口设置子类
End Sub

Private Sub Form_Unload(Cancel As Integer)
unRegisterWindow Me.hwnd ´取消窗口的子类
End Sub

Private Sub Timer1_Timer()
OldTime = Now
End Sub

´模块modle1:

Option Explicit
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" (ByVal lpString As String) As Long
Public OldTime As String
Public ChangeFlag As Boolean
Public Const WM_TIMECHANGE As Long = &H1E ´当系统的时间变化时发送此消息给所有顶级窗口
Public oldproc As Long
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
Private Declare Function SetLocalTime Lib "kernel32" (lpSystemTime As SYSTEMTIME) As Long

Public Function RegisterWindow(hwnd As Long) As Long
If hwnd <> 0 Then
oldproc = SetWindowLong(hwnd, -4, AddressOf WinProc)
End If
End Function
Public Function unRegisterWindow(hwnd As Long) As Long

If hwnd <> 0 Then
SetWindowLong hwnd, -4, oldproc
End If

End Function
Public Function WinProc(ByVal hwnd As Long, ByVal msg As Long, ByVal lpara As Long, ByVal wpara As Long) As Long

Dim i, mytt

If msg = WM_TIMECHANGE And ChangeFlag = False Then ´系统时间被修改了而且不是本程序修改的

ChangeFlag = True ´本程序要修改系统时间

Call SetToOldTime ´修改系统时间

Exit Function

End If


ChangeFlag = False

WinProc = CallWindowProc(oldproc, hwnd, msg, lpara, wpara)


End Function
Public Function SetToOldTime() As String ´将时间恢复到设置前的状态
Dim tmp As String
tmp = OldTime ´从保存的时间中取出修改前的系统时间
Dim lpSystemTime As SYSTEMTIME
lpSystemTime.wYear = Year(tmp) ´取出年份
lpSystemTime.wMonth = Month(tmp) ´取出月份
lpSystemTime.wDayOfWeek = -1
lpSystemTime.wDay = Day(tmp) ´取出日
lpSystemTime.wHour = Hour(tmp) ´取出小时
lpSystemTime.wMinute = Minute(tmp) ´取出分钟
lpSystemTime.wSecond = Second(tmp) ´取出秒
lpSystemTime.wMilliseconds = 0
´set the new time
SetLocalTime lpSystemTime

End Function
BTW:最近写了个同步时间工具,居然改不过其它软件,汗ing...............

[ 本帖最后由 ceoguang 于 2009-3-6 22:13 编辑 ]
发表于 2009-3-6 22:15:52 | 显示全部楼层
呵呵 完全靠别人
 楼主| 发表于 2009-3-6 22:16:39 | 显示全部楼层
楼上的什么意思?
发表于 2009-3-6 22:22:27 | 显示全部楼层
原帖由 ceoguang 于 2009-3-6 22:16 发表
楼上的什么意思?

我是说我不行 完全得看别人的了
发表于 2009-3-7 01:05:23 | 显示全部楼层
这类问题一般都可以在MSDN上找到的,http://msdn.microsoft.com/en-us/library/ms725498.aspx
楼主依自己的需求自己改下吧~

#include <winAPI.au3>
If not IsDeclared("WM_TIMECHANGE") Then $WM_TIMECHANGE=0x001e

$hGui = GuiCreate("Test Of WM_TIMECHANGE", 400, 300)
GUISetState()

;$btnTest = GuiCtrlCreateButton("Test", 100, 100, 70, 20)

$tcProc = DllCallbackRegister("_tcProc", "int", "hwnd;uint;wparam;lparam")
$pTcProc = DllCallbackGetPtr($tcProc)
$tcOldProc = _WinAPI_SetWindowLong($hGUI, -4, $pTcProc)

while True
        If GuiGetMsg() = -3 then ExitLoop
WEnd

Func _tcProc($hWnd, $msg, $wParam, $lParam)
        ;consoleWrite("TIMECHANGE")
        If $msg = $WM_TIMECHANGE then
                msgbox(0, '', "time change")
                return 0
        EndIf
        return _winAPI_CallWindowProc($tcOldProc, $hWnd, $msg, $wParam, $lParam)
EndFunc        ;==>_tcProc()


[ 本帖最后由 pusofalse 于 2009-3-7 01:11 编辑 ]

评分

参与人数 1金钱 +10 收起 理由
ceoguang + 10 谢谢,能不能给新手指点下事件注册的详细写法 ...

查看全部评分

 楼主| 发表于 2009-3-7 18:27:39 | 显示全部楼层
楼上的好强,能不能给新手指点下事件注册的详细写法
 楼主| 发表于 2009-3-7 19:43:42 | 显示全部楼层
原帖由 pusofalse 于 2009-3-7 01:05 发表
这类问题一般都可以在MSDN上找到的,http://msdn.microsoft.com/en-us/library/ms725498.aspx
楼主依自己的需求自己改下吧~

[Au3]#include
If not IsDeclared("WM_TIMECHANGE") Then $WM_TIMECHANGE=0x001e

...

遇到一问题,CSDN上曾有人提过,会接收到两次消息,该怎么解决?
发表于 2009-3-7 21:14:05 | 显示全部楼层

回复 7# ceoguang 的帖子

同样遇到了如此的问题,我的做法是定义一个布尔变量,接收到第二次消息(布尔值为真)时弹出提示。还有wm_timechange的wparam和lparam两个参数在这里都是没有用处的,所以测试这段代码并不能正确读取出修改前的时间,正确率<5%(?)。在寻求好的能够获取修改前的时间的方法,应该只是思路的问题~
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-12-24 00:26 , Processed in 0.071911 second(s), 22 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表