Solved

Program will not regain focus once minimized

Posted on 2001-08-07
17
334 Views
Last Modified: 2012-05-04
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
Comment
Question by:dsmith2001
  • 8
  • 3
  • 3
  • +3
17 Comments
 
LVL 22

Accepted Solution

by:
rspahitz earned 25 total points
ID: 6360166
Try adding a DoEvents to its processing routine.
0
 
LVL 22

Expert Comment

by:rspahitz
ID: 6360191
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
 

Author Comment

by:dsmith2001
ID: 6360215
What would the code for this be ?
0
 

Author Comment

by:dsmith2001
ID: 6360220
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
 
LVL 20

Expert Comment

by:hes
ID: 6360355
Yes add it like
Do
 'Your processing
 DoEvents
Loop
0
 
LVL 22

Expert Comment

by:rspahitz
ID: 6360361
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
 

Author Comment

by:dsmith2001
ID: 6360379
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
 
LVL 22

Expert Comment

by:rspahitz
ID: 6360487
It looks good.  Can you minimize?  If so, problem solved; close the question.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 5

Expert Comment

by:rkot2000
ID: 6360758
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
 
LVL 22

Expert Comment

by:rspahitz
ID: 6360833
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
 
LVL 22

Expert Comment

by:rspahitz
ID: 6360866
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
 
LVL 5

Expert Comment

by:rkot2000
ID: 6360934
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
 
LVL 22

Expert Comment

by:rspahitz
ID: 6361003
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
 
LVL 5

Expert Comment

by:rkot2000
ID: 6361262
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
 
LVL 22

Expert Comment

by:rspahitz
ID: 6361400
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
 
LVL 49

Expert Comment

by:DanRollins
ID: 7198532
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
 
LVL 5

Expert Comment

by:Netminder
ID: 7213262
Per recommendation, force-accepted.

Netminder
CS Moderator
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now