bigracefan
Programmer
I'm trying to use the following code posted by PaulBent. It's basically a way to slow down the application if it's using too much of the cpu. I can't figure out how to declare or how to use "Yield" in this statment.
Public Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Public Const WAIT_ABANDONED = &H80&
Public Const WAIT_ABANDONED_0 = &H80&
Public Const WAIT_FAILED = -1&
Public Const WAIT_IO_COMPLETION = &HC0&
Public Const WAIT_OBJECT_0 = 0
Public Const WAIT_OBJECT_1 = 1
Public Const WAIT_TIMEOUT = &H102&
Public Const INFINITE = &HFFFF
Public Const ERROR_ALREADY_EXISTS = 183&
Public Const QS_HOTKEY = &H80
Public Const QS_KEY = &H1
Public Const QS_MOUSEBUTTON = &H4
Public Const QS_MOUSEMOVE = &H2
Public Const QS_PAINT = &H20
Public Const QS_POSTMESSAGE = &H8
Public Const QS_SENDMESSAGE = &H40
Public Const QS_TIMER = &H10
Public Const QS_MOUSE = (QS_MOUSEMOVE _
Or QS_MOUSEBUTTON)
Public Const QS_INPUT = (QS_MOUSE _
Or QS_KEY)
Public Const QS_ALLEVENTS = (QS_INPUT _
Or QS_POSTMESSAGE _
Or QS_TIMER _
Or QS_PAINT _
Or QS_HOTKEY)
Public Const QS_ALLINPUT = (QS_SENDMESSAGE _
Or QS_PAINT _
Or QS_TIMER _
Or QS_POSTMESSAGE _
Or QS_MOUSEBUTTON _
Or QS_MOUSEMOVE _
Or QS_HOTKEY _
Or QS_KEY)
Declare Function CreateWaitableTimer Lib "kernel32" _
Alias "CreateWaitableTimerA" ( _
Byval lpSemaphoreAttributes As Long, _
Byval bManualReset As Long, _
Byval lpName As String) As Long
Declare Function OpenWaitableTimer Lib "kernel32" _
Alias "OpenWaitableTimerA" ( _
Byval dwDesiredAccess As Long, _
Byval bInheritHandle As Long, _
Byval lpName As String) As Long
Declare Function SetWaitableTimer Lib "kernel32" ( _
Byval hTimer As Long, _
lpDueTime As FILETIME, _
Byval lPeriod As Long, _
Byval pfnCompletionRoutine As Long, _
Byval lpArgToCompletionRoutine As Long, _
Byval fResume As Long) As Long
Declare Function CancelWaitableTimer Lib "kernel32" ( _
Byval hTimer As Long) As Long
Declare Function CloseHandle Lib "kernel32" ( _
Byval hObject As Long) As Long
Declare Function WaitForSingleObject Lib "kernel32" ( _
Byval hHandle As Long, _
Byval dwMilliseconds As Long) As Long
Declare Function MsgWaitForMultipleObjects Lib "user32" ( _
Byval nCount As Long, _
pHandles As Long, _
Byval fWaitAll As Long, _
Byval dwMilliseconds As Long, _
Byval dwWakeMask As Long) As Long
'__________________________________
Public Sub sWait(Byval lngInterval As Long)
'--- Pauses the application thread for the specified number of milliseconds
'--- Parameters
' [In]
' lngInterval: the number of millisecs to pause for
Dim dblDelay As Double 'Pause interval converted to nanoseconds
Dim dblDelayLow As Double 'Low order 32 bits of a 64 bit date/time value
Dim dblUnits As Double 'Units in nanoseconds
Dim lngBusy As Long 'MsgWaitForMultipleObjects function return value
Dim lngRtn As Long 'General function return value
Dim hTimer As Long 'Handle to the timer
Dim strTimerName As String 'Name of timer
Dim udtFT As FILETIME 'Filetime structure to initialize the timer
'Create the timer
strTimerName = "My Apps Timer" & Chr$(0)
hTimer = CreateWaitableTimer(0, True, strTimerName)
'Initialize the timer
udtFT.dwLowDateTime = -1
udtFT.dwHighDateTime = -1
lngRtn = SetWaitableTimer(hTimer, udtFT, 0, 0, 0, 0)
' Convert the units and delay interval to nanoseconds.
dblUnits = Cdbl(&H10000) * Cdbl(&H10000)
dblDelay = Cdbl(lngInterval) * 10000
' By setting the high/low time to a negative number, it tells
' the Wait (in SetWaitableTimer) to use an offset time as
' opposed to a hardcoded time. If it were positive, it would
' try to convert the value to GMT.
udtFT.dwHighDateTime = -Clng(dblDelay / dblUnits) - 1
dblDelayLow = -dblUnits * (dblDelay / dblUnits - _
Fix(dblDelay / dblUnits))
If dblDelayLow < Cdbl(&H80000000) Then
' &H80000000 is MAX_LONG, just making sure
' that we don't overflow when we stick it into
' the FILETIME structure.
dblDelayLow = dblUnits + dblDelayLow
End If
udtFT.dwLowDateTime = Clng(dblDelayLow)
lngRtn = SetWaitableTimer(hTimer, udtFT, 0, 0, 0, False)
Do
' QS_ALLINPUT means that MsgWaitForMultipleObjects will
' return every time the thread in which it is running gets
' a message. If you wanted to handle messages in here you could,
' but by calling Yield we are letting DefWindowProc
' do its normal windows message handling---Like DDE, etc.
lngBusy = MsgWaitForMultipleObjects(1, hTimer, False, _
INFINITE, QS_ALLINPUT)
Yield
Loop Until lngBusy = WAIT_OBJECT_0
' Close the handle
CloseHandle hTimer
End Sub
I used to use this a lot on W98 systems where some batch processes, particularly involving late bound ActiveX servers, would send CPU usage to 100% and the system would grind to a halt. You can let the user select a processor priority from 10 to 1 and assign a pause value in millisecs based on the selection. Then at the end of each loop call sWait.
Select Case cboPriority.Text
Case "10" : lngPause = 0
Case "9" : lngPause = 50
Case "8" : lngPause = 100
'and so on
End Select
Do ....
'.....
sWait lngPause
Loop
Paul Bent
Northwind IT Systems
Public Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Public Const WAIT_ABANDONED = &H80&
Public Const WAIT_ABANDONED_0 = &H80&
Public Const WAIT_FAILED = -1&
Public Const WAIT_IO_COMPLETION = &HC0&
Public Const WAIT_OBJECT_0 = 0
Public Const WAIT_OBJECT_1 = 1
Public Const WAIT_TIMEOUT = &H102&
Public Const INFINITE = &HFFFF
Public Const ERROR_ALREADY_EXISTS = 183&
Public Const QS_HOTKEY = &H80
Public Const QS_KEY = &H1
Public Const QS_MOUSEBUTTON = &H4
Public Const QS_MOUSEMOVE = &H2
Public Const QS_PAINT = &H20
Public Const QS_POSTMESSAGE = &H8
Public Const QS_SENDMESSAGE = &H40
Public Const QS_TIMER = &H10
Public Const QS_MOUSE = (QS_MOUSEMOVE _
Or QS_MOUSEBUTTON)
Public Const QS_INPUT = (QS_MOUSE _
Or QS_KEY)
Public Const QS_ALLEVENTS = (QS_INPUT _
Or QS_POSTMESSAGE _
Or QS_TIMER _
Or QS_PAINT _
Or QS_HOTKEY)
Public Const QS_ALLINPUT = (QS_SENDMESSAGE _
Or QS_PAINT _
Or QS_TIMER _
Or QS_POSTMESSAGE _
Or QS_MOUSEBUTTON _
Or QS_MOUSEMOVE _
Or QS_HOTKEY _
Or QS_KEY)
Declare Function CreateWaitableTimer Lib "kernel32" _
Alias "CreateWaitableTimerA" ( _
Byval lpSemaphoreAttributes As Long, _
Byval bManualReset As Long, _
Byval lpName As String) As Long
Declare Function OpenWaitableTimer Lib "kernel32" _
Alias "OpenWaitableTimerA" ( _
Byval dwDesiredAccess As Long, _
Byval bInheritHandle As Long, _
Byval lpName As String) As Long
Declare Function SetWaitableTimer Lib "kernel32" ( _
Byval hTimer As Long, _
lpDueTime As FILETIME, _
Byval lPeriod As Long, _
Byval pfnCompletionRoutine As Long, _
Byval lpArgToCompletionRoutine As Long, _
Byval fResume As Long) As Long
Declare Function CancelWaitableTimer Lib "kernel32" ( _
Byval hTimer As Long) As Long
Declare Function CloseHandle Lib "kernel32" ( _
Byval hObject As Long) As Long
Declare Function WaitForSingleObject Lib "kernel32" ( _
Byval hHandle As Long, _
Byval dwMilliseconds As Long) As Long
Declare Function MsgWaitForMultipleObjects Lib "user32" ( _
Byval nCount As Long, _
pHandles As Long, _
Byval fWaitAll As Long, _
Byval dwMilliseconds As Long, _
Byval dwWakeMask As Long) As Long
'__________________________________
Public Sub sWait(Byval lngInterval As Long)
'--- Pauses the application thread for the specified number of milliseconds
'--- Parameters
' [In]
' lngInterval: the number of millisecs to pause for
Dim dblDelay As Double 'Pause interval converted to nanoseconds
Dim dblDelayLow As Double 'Low order 32 bits of a 64 bit date/time value
Dim dblUnits As Double 'Units in nanoseconds
Dim lngBusy As Long 'MsgWaitForMultipleObjects function return value
Dim lngRtn As Long 'General function return value
Dim hTimer As Long 'Handle to the timer
Dim strTimerName As String 'Name of timer
Dim udtFT As FILETIME 'Filetime structure to initialize the timer
'Create the timer
strTimerName = "My Apps Timer" & Chr$(0)
hTimer = CreateWaitableTimer(0, True, strTimerName)
'Initialize the timer
udtFT.dwLowDateTime = -1
udtFT.dwHighDateTime = -1
lngRtn = SetWaitableTimer(hTimer, udtFT, 0, 0, 0, 0)
' Convert the units and delay interval to nanoseconds.
dblUnits = Cdbl(&H10000) * Cdbl(&H10000)
dblDelay = Cdbl(lngInterval) * 10000
' By setting the high/low time to a negative number, it tells
' the Wait (in SetWaitableTimer) to use an offset time as
' opposed to a hardcoded time. If it were positive, it would
' try to convert the value to GMT.
udtFT.dwHighDateTime = -Clng(dblDelay / dblUnits) - 1
dblDelayLow = -dblUnits * (dblDelay / dblUnits - _
Fix(dblDelay / dblUnits))
If dblDelayLow < Cdbl(&H80000000) Then
' &H80000000 is MAX_LONG, just making sure
' that we don't overflow when we stick it into
' the FILETIME structure.
dblDelayLow = dblUnits + dblDelayLow
End If
udtFT.dwLowDateTime = Clng(dblDelayLow)
lngRtn = SetWaitableTimer(hTimer, udtFT, 0, 0, 0, False)
Do
' QS_ALLINPUT means that MsgWaitForMultipleObjects will
' return every time the thread in which it is running gets
' a message. If you wanted to handle messages in here you could,
' but by calling Yield we are letting DefWindowProc
' do its normal windows message handling---Like DDE, etc.
lngBusy = MsgWaitForMultipleObjects(1, hTimer, False, _
INFINITE, QS_ALLINPUT)
Yield
Loop Until lngBusy = WAIT_OBJECT_0
' Close the handle
CloseHandle hTimer
End Sub
I used to use this a lot on W98 systems where some batch processes, particularly involving late bound ActiveX servers, would send CPU usage to 100% and the system would grind to a halt. You can let the user select a processor priority from 10 to 1 and assign a pause value in millisecs based on the selection. Then at the end of each loop call sWait.
Select Case cboPriority.Text
Case "10" : lngPause = 0
Case "9" : lngPause = 50
Case "8" : lngPause = 100
'and so on
End Select
Do ....
'.....
sWait lngPause
Loop
Paul Bent
Northwind IT Systems