• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 347
  • Last Modified:

Program will not regain focus once minimized

Hi, if my program looses focus when it is running through its various tasks, it is impossible to get it back again until it finishes what it is doing (which can take upto 15 minutes). Once it has started its tasks, it is also impossible to hit its minimize button, as nothing happens. Any ideas?
0
dsmith2001
Asked:
dsmith2001
  • 8
  • 3
  • 3
  • +3
1 Solution
 
rspahitzCommented:
Try adding a DoEvents to its processing routine.
0
 
rspahitzCommented:
More info:

When a VB program processes a routine, it consumes the entire resources that Windows has given to it until it finishes, after which it starts communicating with Windows again.  If you want to it to talk to Windows while processing, you need to let it "catch its breath" by adding a DoEvent, which temporarily returns control to Windows to see if any other events have occurred which affect the app (such as a click on the Minimize button.)

Since DoEvents does slightly slow down the process, you may want to carefully consider where you put it.

For example, if you have a nested loop where the outer loop occurs 1000 times, and the inner loop occurs 100 times, you may want to add it to the outer loop rather than the inner loop.

My rule of thumb is to use it wherever I think it will occur about ever second of processing time.
0
 
dsmith2001Author Commented:
What would the code for this be ?
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
dsmith2001Author Commented:
I only have 1 loop. This is when the problem occurs.
I take it I would have to add the Do events within this loop ?
0
 
hesCommented:
Yes add it like
Do
 'Your processing
 DoEvents
Loop
0
 
rspahitzCommented:
yup:

For x=1 to something
  ' some code
  DoEvents
  ' more code
Next x

-or-

Do
  ' some code
  DoEvents
  ' more code
Loop until done

--
And DoEvents should probably not be embedded inside an If statement, but that's really up to you.
And if your loop takes more than a second per cycle, you may want to add several at strategic points.

Also, you may want to add the hourglass:

Form1.MousePointer = vbHourglass
' start loop
' ...
   DoEvents
' ...
' end loop
Form1.MousePointer = vbDefault
0
 
dsmith2001Author Commented:
My loop process's around 90 records a second, so what I've done is

count = 1000

do until count = o
DoEvents
...
...
...
count = count - 1
loop

Is this correct. It seems to work!
0
 
rspahitzCommented:
It looks good.  Can you minimize?  If so, problem solved; close the question.
0
 
rkot2000Commented:
just comments on doevents.

if you are using command button or any other user driven call to start loop you need to disable it otherwise  user can restart the same process in the middle.

calling doevents for every step is very bad plus it takes long time to execute (doevents ~ 0.1 * 100000)

you better use something like this

for i = 0 to 100000
  if i mod 100 = 0 then
    doevents
  end if
next i

or even better

cmd_click()
me.windowstate = vbminimazed
doevents
for i = 0 to 1000000



next i

me.windowstate = vbnormal
0
 
rspahitzCommented:
rkot2000, I was wondering about that.

Do you know how many clock cycles it takes to perform 'DoEvents' versus 'if i mod 100 = 0 then'?

I suspect that DoEvents is a processor hog versus if compiles down to almost native processor code (although the mod would take a few extra clock cycles.)

Better yet, I ran my own tests and was surprised with the results (on a 1GHz Athlon in Win2000):

  Dim z As Long
 
  Print Time
  For z = 1 To 1000000
    'If z Mod 100 = 0 Then
    'DoEvents
    'End If
    CurrentX = 1000
    CurrentY = 0
    Print z
  Next z
  Print Time

Test 1:
Above code.
Total time: 0:15

Test 2:
Uncomment out the DoEvents.
Total Time: 0:24 (re-run 0:23)

Test 3:
Uncomment out the If/End If.
Total Time: 0:26 (re-run 0:24)

It appears that in THIS test scenario, and with the mod being every 100, there is no savings with the modulo.  This could certainly change by varying the values, but it appears to me that the savings is insignificant enough to try without it first.  Also, it's easy enough to implement that I would add it and do a time comparison.


0
 
rspahitzCommented:
Hmm. Apparently I mis-ran my test.  The mod gave 16 seconds!

Oh, yes, this was activated with a command button, and Form Autoredraw=false (if=true, then the times double!)
0
 
rkot2000Commented:
rspahitz  - you should use api to capture time not vb time if you want to test performance,
 :)

I agree in some cases you may not get better speed.
for example call to db takes 2s


if you
what about reentering the same code ????
noevents
01:16:38 PM
01:17:21 PM

doevents
01:17:47 PM
01:18:39 PM

mod 1000
01:18:57 PM
01:19:38 PM

mod 10000
01:19:57 PM
01:20:38 PM

0
 
rspahitzCommented:
You're correct about tracking the time, but I simply wanted rough estimates.

Some drawbacks of:

1) No mod If-Block
This will take a huge amount of processing time by Windows, thereby slowing down you entire Windows functioning.

2) If-Block with large number (1000, 10000)
This will make your app very unresponsive because Windows will only look at it at every, say, 10,000 iterations through the loop.

Conclusion:
To maximize the use of this feature, you'll have to play with the various options suggested in the above comments.

0
 
rkot2000Commented:
to rspahitz

try this :

Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long


Private Sub Form_Load()
Me.Show
Dim lvlStart As Long
Dim lvlEnd As Long
Dim i As Long


lvlStart = GetTickCount

For i = 0 To 10000000
 
Next i

lvlEnd = GetTickCount


Debug.Print "nothing - " & lvlEnd - lvlStart


lvlStart = GetTickCount

For i = 0 To 10000000

  If i Mod 10000 = 0 Then
    DoEvents
  End If
 
Next i

lvlEnd = GetTickCount


Debug.Print "MOD - " & lvlEnd - lvlStart



lvlStart = GetTickCount

For i = 0 To 10000000

  DoEvents

Next i

lvlEnd = GetTickCount


Debug.Print "DoEvents - " & lvlEnd - lvlStart
'without show form
'nothing - 218
'MOD - 1844
'DoEvents -36469


'with show form
'nothing - 219
'MOD - 1906
'DoEvents -29000

End Sub
0
 
rspahitzCommented:
My results were:

nothing - 280
MOD - 1983
DoEvents - 22062

I also tried with a mod value of 10, 100, 1000, 10000:
MOD10 - 4186
MOD100 - 2223
MOD1000 - 2003
MOD10000 - 2003 (hmmm...slower the second time!)

Given the unlikely test case presented (who'd want to use a loop that does nothing?) there is little advantage to making the check more than every 1000th time through the loop.

--
In a real world scenario, I think the optimal MOD number would be much smaller than 1000 or you'd start losing responsiveness from the app.  Likewise, the number should large enough that the app does not tie up all of its processor time talking to Windows

So I think your original 100 is probably good as a starting point.  Descrease the number for more responsiveness from the app; increase the number to decrease the processing time.  (Also test this on the slowest machine you think you'll be using and use those setting since the faster machines won't likely notice the difference.)
0
 
DanRollinsCommented:
Hi dsmith2001,
It appears that you have forgotten this question. I will ask Community Support to close it unless you finalize it within 7 days. I will ask a Community Support Moderator to:

    Accept rspahitz's comment(s) as an answer.

dsmith2001, if you think your question was not answered at all or if you need help, just post a new comment here; Community Support will help you.  DO NOT accept this comment as an answer.

EXPERTS: If you disagree with that recommendation, please post an explanatory comment.
==========
DanRollins -- EE database cleanup volunteer
0
 
NetminderCommented:
Per recommendation, force-accepted.

Netminder
CS Moderator
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 8
  • 3
  • 3
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now