I've been working on a long program that has a non-modal dialog and a subroutine that is perpetually checking the status of about 30 checkboxes in the dialog. The subroutine has two repeat loops each looping 30 times. I was getting frustrated with the length of the delay after making any selection in my dialog. It could take nearly 2 seconds after making a selection before the result would be displayed. I knew the cause was the subroutine with Wait>0.01 inserted to prevent high CPU usage. If I changed that wait to zero the delay was gone. But this dialog will be sitting on user's desktops while they are trying to work in multiple other applications so I cannot just let the CPU run at 80 or 90%.
It occurred to me that I can set the Wait> time through a variable and I can control the variable by testing to see if my dialog is the active window or not. Therefore, If the active window is Excel, my program will only use 2% of the CPU. If the active window is my dialog, my program will use whatever it wants of the CPU.
This might not work in all situations but it is going to work in this case and I thought I'd pass along the idea.
Here's a sample script to illustrate the point. Start this script and watch the results for a minute, then open some other application in a way that you can still see the script's dialog window but the focus needs to be on the newly opened app. You should immediately notice the cycle count slow. The CPU percentage only changes after each one second of CPU use by the program so when the cycles slow it might take a while before you see the percentage drop. Switch focus back to the dialog window and the cycle count should increase and the CPU use should go up.
Code: Select all
VBSTART
VBEND
//Press Esc tp quit
OnEvent>KEY_DOWN,VK27,0,Quit
//Press up arrow to raise wait time
OnEvent>KEY_DOWN,VK38,0,Tup
//Press down arrow to reduce wait time
OnEvent>KEY_DOWN,VK40,0,Tdown
//Acquire process filename for cpu info
Separate>%COMMAND_LINE%,\,path
Let>filename=path_%path_count%
StringReplace>%filename%,",,filename
//A few settings
Let>kk=0
Let>LastTime=0
Let>CycleCount=19
Let>CPUThrottle=0
Let>ThrottleValue=0.01
Let>TTmsg=Throttle Time:
Let>PUDmsg=Press up or down arrow keys%CRLF%to raise or lower throttle time
Dialog>Dialog1
Caption=CPU Time
Width=168
Height=259
Top=CENTER
Left=CENTER
Max=0
Min=1
Close=1
Resize=0
Label=msLabel0,56,48,true
Label=msLabel1,56,128,true
Label=mslabel2,96,208,true
Label=msLabel3,56,88,true
Label=msLabel4,24,2,true
Label=cycles,56,112,true
Label=CPU time (hh:mm:ss),32,32,true
CheckBox=msCheckBox1,CPU Throttle on,24,152,97,False
Label=%TTmsg%,24,208,true
Label=%PUDmsg%,8,176,true
Label=%,96,88,true
Label=Approx. CPU use,40,72,true
EndDialog>Dialog1
Show>dialog1
//A few dialog settings
Let>dialog1.mslabel2=%ThrottleValue%
Let>dialog1.mslabel4=%filename%
RDA>dialog1
Label>Start
GetDialogAction>dialog1,res1
If>res1=2,EOF
//check the CPUThrottle checkbox value to alter wait settings
//and dialog display
If>dialog1.mscheckbox1=True
Let>CPUThrottle=%ThrottleValue%
Let>CycleCount=19
Let>dialog1.mslabel2=%ThrottleValue%
Let>dialog1.mslabel8=%TTmsg%
Let>dialog1.mslabel9=%PUDmsg%
Else
Let>dialog1.mslabel2=%SPACE%
Let>dialog1.mslabel8=%SPACE%
Let>dialog1.mslabel9=%SPACE%
//This is the part I am talking about. If the active window is
//my dialog, set the wait variable to zero thus allowing the process
//to run as quickly as possible. If not, set the wait variable to an
//appropriate value
Let>WIN_USEHANDLE=1
GetActiveWindow>title,WinX,WinY
Let>WIN_USEHANDLE=0
If>%title%<>%dialog1.handle%
Let>CycleCount=19
Let>CPUThrottle=%ThrottleValue%
Else
Let>CycleCount=99
Let>CPUThrottle=0
EndIf
EndIf
//count the cycles through the process for display purposes
add>kk,1
//run tasklist.exe in DOS to acquire cpu info
Let>RP_WAIT=1
Let>RP_WINDOWMODE=0
Run>cmd /c tasklist /fi "imagename eq %filename%" /v /nh> %TEMP_DIR%~cpu~.txt
ReadLn>%TEMP_DIR%~cpu~.txt,2,line
DeleteFile>%TEMP_DIR%~cpu~.txt
Separate>%line%,:,var
Length>%var_1%,varlen
sub>varlen,5
midstr>%var_1%,%varlen%,10,var_1
Midstr>%var_3%,1,2,var_3
concat>var_1,:%var_2%:%var_3%
StringReplace>%var_1%,%SPACE%,,var_1
If>%dialog1.mslabel0%<>%var_1%
GoSub>CPU
Let>dialog1.mslabel0=%var_1%
EndIf
Let>dialog1.mslabel1=%kk%
GoSub>Blast
GetDialogAction>dialog1,res1
RDA>dialog1
Goto>Start
//A little math to simulate doing something useful
//the uses cpu cycles.
SRT>Blast
Let>user=0
Repeat>user
add>user,1
Random>10000,num1
random>10000,num2
Random>10000,num3
add>num3,1
Let>num4={(%num1%*%num2%)/%num3%}
Wait>%CPUThrottle%
Until>user>%CycleCount%
END>Blast
//Calculate CPU percent of use based on one second of CPU
//usage reported by tasklist, divided by the number of
//seconds elapsed since the last one second of CPU usage.
SRT>CPU
If>%LastTime%=0
VBEval>Timer,LastTime
Let>dialog1.mslabel3=Waiting...
Else
VBEval>Timer,timerStarted
Let>dwell=%timerStarted%-%LastTime%
Let>dialog1.mslabel3={(round((1/%dwell%)*100000)/1000)}
//Let>dialog1.mslabel4=%timerStarted%
//Let>dialog1.mslabel5=%LastTime%
Let>LastTime=%timerStarted%
EndIf
RDA>dialog1
END>CPU
//Press Esc to quit
SRT>Quit
goto>EOF
END>Quit
//Press up arrow to raise wait time
SRT>Tup
If>%ThrottleValue%<0.5
Let>ThrottleValue=%ThrottleValue%+0.001
Let>dialog1.mslabel2=%ThrottleValue%
RDA>dialog1
wait>0.01
Else
MDL>MAX Throttle value = 0.5
EndIf
END>Tup
//Press down arrow to reduce wait time
SRT>Tdown
If>%ThrottleValue%>0
Let>ThrottleValue=%ThrottleValue%-0.001
Let>dialog1.mslabel2=%ThrottleValue%
RDA>dialog1
wait>0.01
Else
MDL>Minimum Throttle value = 0.001
EndIf
END>Tdown
Label>EOF