0

Currently, I call DoEvents in order to check if Button Foo in Form Bar has been clicked. This approach works but it takes too much processing power, delaying the program.

I believe that the delay could be reduced if I could only check if Button Foo has been clicked, instead of all the other forms that DoEvents has to go through.

Any ideas on how can I check if Button Foo was clicked?

Peretz
  • 1,096
  • 2
  • 18
  • 31
  • 3
    Buttons generate an event, and you can write a handler for that event. If you're using DoEvents, you might greatly benefit from reading more about VB6 event handling (hint: DoEvents is *not* a good approach). – jdigital Jan 02 '12 at 20:42
  • One thing you might try that could dramatically improve your performance would be to only DoEvents every 100th loop or some such number. This would allow your program to handle UI interactions and improve your performance. – UnhandledExcepSean Jan 02 '12 at 23:25
  • 2
    Please start by explaining why using the button's event handler will not work. If we knew more about your code structure we might be able to suggest an alternative style that does not suffer from the same problems. – tcarvin Jan 04 '12 at 12:49

2 Answers2

6

VB6 was not really designed for what you seem to be doing (some sort of long-running straight-line code that does not exit back to give the message loop control). Normally such a task would be delegated to a worker thread, and in VB6 this means some external component implemented in C++ most of the time.

There are only a very few kinds of approaches to take to do this for your ad-hoc logic:

  • Hacks creating separate threads via API calls, not very reliable in VB6 for a number of reasons.
  • A tricky thread-per-object ActiveX EXE implementing a class to handle your long-running workload.
  • A separate non-interactive worker process to be run and monitored by your GUI program.

That's pretty much it.

The prescribed method of doing this sort of thing is described in the VB6 documentation. You break your long-running loop up and invert the logic into a repeatable "quantum" of work (like n iterations of your processing loop), and maintain the state of your workload in Form-global data. Then you use a Timer control with its interval set to 1 or 16 (hardly matters, they normally take at least 16ms to trigger) and run your workload quantum within its event handler.

So if you simply had a loop that currently iterates 100,000 times doing something you might break it up so that it runs 500 times for each Timer tick. The quantum size will probably need to be tuned based on what is done within the loop - 500 is just a value chosen for illustration. You'll want to adjust this until it leaves the UI responsive without starving your background workload too much (slowing completion down).

Bob77
  • 13,167
  • 1
  • 29
  • 37
1

If your code is heavy enough to not call DoEvents or just finish running periodically, then your app won't even know the button has been pressed. The DoEvents call allows windows, and your application to catch up on all notifications.

The correct way to resolve this is a worker thread (see this article on how to do something like this in VB6) but failing that, a periodic DoEvents is required and in turn, some re-entrancy blocking on the call into the long running code.

Deanna
  • 23,876
  • 7
  • 71
  • 156