Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Progress Form 1

Status
Not open for further replies.

ZoneVM

Programmer
Apr 7, 2005
30
US
In my C++ Builder 6 application, I have a form which performs lengthy computations / work and reports status back to the user. The user has the option to cancel as well. What I'm shooting for is something like the "Compiling..." dialog that pops up when you run a project from the IDE. My form will have several lines of text, however, that become visible as tasks are completed.

I have tried kicking off the computations using the "OnActivate" and "OnShow" methods of this form, but neither seems to work very well. When I use "OnShow", the form doesn't show up until all computation is done. When I use "OnActivate" the text on the form doesn't show up (although the progress bar on my form does work as it is supposed to). It's like the form doesn't get a chance to display everything before computation begins, and so the screen is not updated as it is supposed to be.

Is there a better way to tackle this problem?
 
Ok, I got it working OK by using the "OnActivate" method and putting Repaint() calls in as required. Still, my intuition tells me there's a better way to start computations when a form is created (or a better way to handle status forms. If anyone can point me in the right direction, I'd be much appreciative.
 
Instead of using Repaint(), try using Application->ProcessMessages() just for a test.


James P. Cottingham
-----------------------------------------
[sup]I'm number 1,229!
I'm number 1,229![/sup]
 
Thanks. It has the same effect, but it seems ProcessMessages might be the more appropriate way to do what I'm after. Do you see any problems with how I'm doing this, or do you think I should use a Frame instead?

 
Don't use the ProcessMessages to often as it could slow down lengthy computations.
I guess you don't need a progres bar that updates every milisecond. When I want to show progres in my applications I use the timer to call ProcessMessages once per second.
 
I often have to test to see which will give me the best results. Like hennep says, there is a downside to using it but it also allow the program to redraw properly if something else may run in the background.

For example, I have a program that I run once a month to clear out old data from a database. I used redraw to get the ProgressBar to update properly but since the process was a long one, sometimes the screen saver would kick in. After that my program wouldn't update until after it was done. Once I strategically put in a ProcessMessages call, I stopped having that problem.

Ultimately, you have to decide which will work best in you situation.

James P. Cottingham
-----------------------------------------
[sup]I'm number 1,229!
I'm number 1,229![/sup]
 
Only a think. I think a Timer is waste resources, why not put a counter and in depencence of lengthy computations, you can do:

if (ntik++ > 9) { // or 20, 90, 1000 ...
Applicatrion->ProcessMessages();
ntik = 0;
}


 
jmmmx,

I wanted to show that your "ntik++" also creates extra resources (especially when executed billions of times) and that the best solution is to run the lengthy process in a seperate thread. My idea is that the Sleep function uses the least resources.
Have a look at this code:
Code:
#include <vcl.h>
#include <mmsystem.hpp>
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
struct process_parameters {
    bool is_running;
    unsigned long value;
};
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { }
//---------------------------------------------------------------------------
unsigned long __stdcall lengthy_process(void *data) {
  struct process_parameters *param = (struct process_parameters *)data;
  unsigned long temp=0;
    for( unsigned long i=0; i<4000000000; i++ ) {
        param->value = i;
        //temp++;
    }
    param->is_running = false;
    return 0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender) {
    struct process_parameters param;
    param.is_running = true;
    param.value=0;
    CreateThread(NULL,0,lengthy_process,&param,0,0);
    unsigned long ms = timeGetTime();
    while(param.is_running) {
        Label1->Caption = param.value;
        Application->ProcessMessages();
        Sleep(100);
    }
    Label1->Caption = param.value;
    AnsiString caption = (float)(timeGetTime() - ms ) / 1000;
    caption += " seconds";
    Label2->Caption = caption;
}
To my surprise the thread runs 5 seconds faster (on my slow laptop) when the "//temp++;" line is uncommented!
Thank you very much jmmmx, for your invention that an extra increment makes the process faster :)

But how can we explain this ???
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top