设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
楼主: andymark
打印 上一主题 下一主题

为ACCESS添加多个Timer功能

[复制链接]
31#
发表于 2009-10-13 21:25:03 | 只看该作者
这是好东西
32#
发表于 2009-10-17 16:04:13 | 只看该作者
非常不错,嗯~
33#
发表于 2009-10-31 19:36:33 | 只看该作者
谢谢,分享
34#
发表于 2009-11-21 15:08:30 | 只看该作者
学习
35#
发表于 2009-11-28 17:59:35 | 只看该作者
太粗燥了. 给你定时器类.

'* ******************************************** *

'*  模块名称:Timer.cls

'*  功能:在VB类模块中使用计时器

'* ******************************************** *



Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, _
    Source As Any, ByVal Length As Long)

Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, _
    ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long

Private Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long

Private m_Tag As String

Private m_TimerID As Long

Private m_Enabled As Boolean

Private m_Interval As Long

Private m_EventEnter As Boolean         '事件实例标识, 防止一个早期实例未结束之前开始另一个实例

Public Event ThatTime()

Private Sub Class_Initialize()

    m_Interval = 0

End Sub

Private Sub Class_Terminate()

    If m_TimerID <> 0 Then KillTimer 0, m_TimerID

End Sub

Public Property Get Interval() As Long

    Interval = m_Interval

End Property

Public Property Let Interval(ByVal New_Value As Long)
   
    If New_Value > 0 Then
        '如果事件间隔相同, 退出
        If m_Interval = New_Value Then Exit Property
        
        If m_Enabled Then
            '如果类为Enable, 创建一个新的定时器
            
            m_Interval = New_Value
            '先销毁假设存在的旧定时器,再启动新定时器
            If m_TimerID <> 0 Then KillTimer 0, m_TimerID
            m_TimerID = SetTimer(0, 0, m_Interval, GetFuncAddr(10))     '注意回调函数地址,TimerProc为第10个函数
        
        Else
        ' 定时器disable, 仅修改时间间隔
            m_Interval = New_Value
        End If
        
    Else
   
        '新的事件间隔小于等于0, 销毁定时器
        m_Interval = 0
        If m_TimerID <> 0 Then KillTimer 0, m_TimerID
        m_TimerID = 0
        
    End If

End Property

Public Property Get Enabled() As Boolean

    Enabled = m_Enabled

End Property

Public Property Let Enabled(ByVal New_Value As Boolean)

    If New_Value = m_Enabled Then Exit Property
   
    If New_Value Then
   
        '新值允许定时器启动
        m_Enabled = New_Value
        
        If m_TimerID <> 0 Then      '如果存在旧定时器, 先销毁
            KillTimer 0, m_TimerID
            m_TimerID = 0
        End If
        
        '检查时间间隔, 如果>0 则启动新定时器
        If m_Interval > 0 Then
            m_TimerID = SetTimer(0, 0, m_Interval, GetFuncAddr(10))         '注意回调函数地址,TimerProc为第10个函数
        End If
        
    Else
   
        '新值设定时器disable,销毁定时器
        m_Enabled = False
        If m_TimerID <> 0 Then KillTimer 0, m_TimerID
        m_TimerID = 0
        
    End If

End Property

Public Property Get Tag() As String

    Tag = m_Tag
End Property

Public Property Let Tag(New_Value As String)

    m_Tag = New_Value
End Property

Private Function GetFuncAddr(ByVal IndexOfFunc As Long) As Long
'IndexOfFunc -- 类中第几个函数??
'是从某个类模块中最顶端的函数或属性算起,他是第几个函数

'这个参数有讲究...
'1. 当被查找的函数为 公用函数时,它的值就是自顶端算起的第几个函数,比如你在类模块中最顶端写的一个公用函数 WndProc,那么就传 1
'     如果是第2个公用函数或属性那么就传 2 依次...  注意,计算的时候要算上公用属性,公用属性也要算上,属性相当于函数,算做一个
'
'2. 当被查找的函数为 局部函数时,也就是说如果是 Private 修饰的函数,则此参数值为 所有公用函数个数 + 这是第 N 个私有函数
'     也是从顶端算起 , 同样包括属性

Static AsmCode(33) As Byte

Dim pThis As Long, pVtbl As Long, pFunc As Long
   

    pThis = ObjPtr(Me)

    CopyMemory pVtbl, ByVal pThis, 4

    CopyMemory pFunc, ByVal pVtbl + (6 + IndexOfFunc) * 4, 4

    AsmCode(0) = &H55

    AsmCode(1) = &H8B: AsmCode(2) = &HEC

    CopyMemory AsmCode(3), &H1475FF, 3

    CopyMemory AsmCode(6), &H1075FF, 3

    CopyMemory AsmCode(9), &HC75FF, 3

    CopyMemory AsmCode(12), &H875FF, 3

    AsmCode(15) = &HB9

    CopyMemory AsmCode(16), pThis, 4

    AsmCode(20) = &H51

    AsmCode(21) = &HE8

    CopyMemory AsmCode(22), pFunc - VarPtr(AsmCode(21)) - 5, 4

    AsmCode(26) = &H8B: AsmCode(27) = &HE5

    AsmCode(28) = &H5D

    AsmCode(29) = &HC2

    CopyMemory AsmCode(30), 16, 4

    GetFuncAddr = VarPtr(AsmCode(0))

End Function


Private Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long)

    '如果这个事件的一个早期实例仍然在进行时,不要产生此事件。
    If m_EventEnter Then Exit Sub
   
    'm_EventEnter 标志将阻塞这个事件的未来实例直到当前的事例完成。
    m_EventEnter = True
   
'    Debug.Print "raise event"
    ' Generate the event
    RaiseEvent ThatTime
   
    ' 允许这个事件再次进入 TimerProc。
    m_EventEnter = False

End Sub
36#
发表于 2009-11-29 13:20:21 | 只看该作者
37#
发表于 2009-12-4 21:49:55 | 只看该作者
谢谢分享
38#
发表于 2009-12-21 12:30:51 | 只看该作者
ddddddd
39#
发表于 2009-12-24 08:31:58 | 只看该作者
这个不错哦,一定要顶顶
40#
发表于 2010-1-2 21:35:41 | 只看该作者
谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-3 19:41 , Processed in 0.090264 second(s), 33 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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