现在我有多个窗体A(主窗体),B,C..。A中有TIMER1,B中也有TIMER2。
B窗体一直是打开的,TIMER2.Interval = 1000,而且在执行事件。
当我在A窗体中打开C窗体时,B窗体中的TIMER2大部分会停止事件(直到关闭C窗体回到A窗体,B窗体中的事件继续执行。)
有时会继续执行。是线程问题吗?
B窗体一直是打开的,TIMER2.Interval = 1000,而且在执行事件。
当我在A窗体中打开C窗体时,B窗体中的TIMER2大部分会停止事件(直到关闭C窗体回到A窗体,B窗体中的事件继续执行。)
有时会继续执行。是线程问题吗?
由于vb6对回调函数支持不够好,实现多线程是非常麻烦的。改用ACTIVE EXE吧
http://download.csdn.net/source/1371398
如果你是模态窗口打开其他的就阻塞了TIMER2所在窗体消息触发。
但是A窗体操作C的时候就发生上面的情况。
马哥
'B窗体的代码
Private Declare Function CreateRectRgn Lib "gdi32.dll" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function SetWindowRgn Lib "user32" (ByVal hwnd As Long, ByVal hrgn As Long, ByVal bRedraw As Long) As Long
Private Declare Function CombineRgn Lib "gdi32.dll" (ByVal hDestRgn As Long, ByVal hSrcRgn1 As Long, ByVal hSrcRgn2 As Long, ByVal nCombineMode As Long) As Long
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
'Event
Private Enum AnimeEventEnum
aunload = 0
aload = 1
End Enum
'Special effect
Private Enum AnimeEffectEnum
eAppearFromLeft = 0
eAppearFromRight = 1
eAppearFromTop = 2
End Enum
Private Const RGN_AND As Long = 1
Private Const RGN_OR As Long = 2
Private Const RGN_XOR As Long = 3
Private Const RGN_DIFF As Long = 4
Private Const RGN_COPY As Long = 5
'********************
'我担心问题出在这里的Sleep
Private Function AnimateForm(hwndObject As Object, ByVal aEvent As AnimeEventEnum, _
Optional ByVal aEffect As AnimeEffectEnum = 11, _
Optional ByVal FrameTime As Long = 1, _
Optional ByVal FrameCount As Long = 33) As Boolean
On Error GoTo Error:
Dim X1, Y1 As Long
Dim hrgn, tmpRgn As Long
Dim XValue, YValue As Long
Dim XIncr, YIncr As Double
Dim wHeight, wWidth As Long
wWidth = hwndObject.Width / Screen.TwipsPerPixelX
wHeight = hwndObject.Height / Screen.TwipsPerPixelY
hwndObject.Visible = True
Select Case aEffect
Case eAppearFromLeft
XIncr = wWidth / FrameCount
For X1 = 0 To FrameCount
'Define the size of current frame/Create it
XValue = X1 * XIncr
hrgn = CreateRectRgn(0, 0, XValue, wHeight)
'If unload then take the reverse(anti) region
If aEvent = aunload Then
tmpRgn = CreateRectRgn(0, 0, wWidth, wHeight)
CombineRgn hrgn, hrgn, tmpRgn, RGN_XOR
DeleteObject tmpRgn
End If
'Set the new region for the window
SetWindowRgn hwndObject.hwnd, hrgn, True: DoEvents
Sleep FrameTime
Next X1
Case eAppearFromRight
XIncr = wWidth / FrameCount
For X1 = 0 To FrameCount
XValue = wWidth - X1 * XIncr
hrgn = CreateRectRgn(XValue, 0, wWidth, wHeight)
If aEvent = aunload Then
tmpRgn = CreateRectRgn(0, 0, wWidth, wHeight)
CombineRgn hrgn, hrgn, tmpRgn, RGN_XOR
DeleteObject tmpRgn
End If
SetWindowRgn hwndObject.hwnd, hrgn, True: DoEvents
Sleep FrameTime
Next X1
Case eAppearFromTop
YIncr = wHeight / FrameCount
For Y1 = 0 To FrameCount
YValue = Y1 * YIncr
hrgn = CreateRectRgn(0, 0, wWidth, YValue)
If aEvent = aunload Then
tmpRgn = CreateRectRgn(0, 0, wWidth, wHeight)
CombineRgn hrgn, hrgn, tmpRgn, RGN_XOR
DeleteObject tmpRgn
End If
SetWindowRgn hwndObject.hwnd, hrgn, True: DoEvents
Sleep FrameTime
Next Y1
End Select
AnimateForm = True
Exit Function
Error:
AnimateForm = False
End FunctionPrivate Sub ImgTimer_Timer()
Advertisement
End SubPrivate Sub Advertisement()
Dim sEffect As Integer sEffect = Int(Rnd * 2)
AnimateForm Pic, aload, sEffect, 15, 30
End SubPrivate Sub Form_Load() sSpecialTime = oIni.ReadKey("TableManager", "SpecialTime")
If sSpecialTime = "NOT EXIST" Then
sSpecialTime = "0"
oIni.WriteKey "TableManager", "SpecialTime", "0"
End If
sSpecialCount = oIni.ReadKey("TableManager", "SpecialCount")
If sSpecialCount = "NOT EXIST" Then
sSpecialCount = "0"
oIni.WriteKey "TableManager", "SpecialCount", "0"
End If ImgTimer.Interval = 1000
Me.Move oMSA.MiscArea3.Width, 1000, oMSA.MiscArea3.Width, oMSA.MiscArea3.Height
MakeTransparent Me.hwnd, 5
End Sub
事件就会中断,何况是2个窗体的timer
好在还是单线程,用全局变量可以很好解决
改用 SetTimer 创建高精度的定时器,来进行帧的循环。
Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
是这样用吗?SetTimer form1,lmgtimer,30,null
Command1
ProgressBar1*******************************
模块里Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
Public id_timer As Integer '用来存放返回的定时器的ID
Const inc_step As Integer = 5 '设置ProgressBar值的增量'Starttimer过程调用SetTimer函数生成定时器,hwnd和nIDEvent送入0表示在回调过程中不使用它们,uElapse置为100,让程序每100毫秒就调用一次回调函数;lpTimerFunc参数由AddressOfTimerProc将
'TimerProc的地址送入函数.Public Sub StartTimer()
id_timer = SetTimer(0, 0, 100, AddressOf TimerProc)
Form1.ProgressBar1.Value = 0
Form1.Command1.Caption = "Stop"
End Sub
'Endtimer清除定时器,同时给用户一个信息反馈。
Public Sub EndTimer()
KillTimer 0, id_timer
id_timer = 0
MsgBox "Timer has been killed!", vbExclamation, "Done!"
Form1.Command1.Caption = "Start"
End Sub'Updateprogressbar过程用来更新进程条的显示。
Public Sub updateprogressbar()
Dim percentdone As Integer
percentdone = Form1.ProgressBar1.Value + inc_step
If percentdone > 100 Then
Form1.ProgressBar1.Value = 100
EndTimer
Else
Form1.ProgressBar1.Value = percentdone
End If
End Sub'----建立回调过程,这里回调过程只是调用updateprogressbar过程来更新显示。
Public Sub TimerProc()
updateprogressbar
End Sub窗体Private Sub Command1_Click()
If id_timer > 0 Then
EndTimer
Else
StartTimer
End If
End Sub