Link to home
Start Free TrialLog in
Avatar of stitch2802
stitch2802

asked on

Connect two dialog windows with a progress bar

Hi,

I have a dialog (A) that asks the user to select an option from a combo box. Dialog (A) also has a progress bar. Depending on the selection, it opens another dialog (B) that does some background processing and then displays results.

What I would like to do is have the progress bar on (A) increment until the background processing in (B) is finished and then just display the results in (B), i.e. (B) is not displayed until after all processing is completed.

Any help would be welcome.
ASKER CERTIFIED SOLUTION
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of stitch2802
stitch2802

ASKER

Thanks Andy. I'll try this out and report back. =)
Hm, I suppose it's my relative inexperience with Windows programming, but could you go into some more detail, please as I'm having some difficulty with the bit you've written?

Thanks,
Suni
Hm, I suppose it's my relative inexperience with Windows programming, but could you go into some more detail, please as I'm having some difficulty with the bit you've written?

Thanks,
Suni
Which bit don't you understand / isn't working
Basic questions - I'm a n00b, please bear with me:

. how would I get a pointer to CDlgA ? getParent() ? should I make a new CDlgB constructor that takes a pointer? Right now the CDlgB object has a constructor as follows :

CDlgB ::CDlgB (CWnd* pParent /*=NULL*/)      :
   CDialog(CDlgB ::IDD, pParent),  m_gametitle(TEXT(""))
{
      m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}


. is processingInIncrements a static boolean? Does it not matter?

. In PumpMessages(), you say must call Create() before using the dialog - for which object?

Thanks for your help =)

S/.
<how would I get a pointer to CDlgA >
I suggested passing it explicitly in the StartProcessing.  (GetParent doesn't always return the window owning it, it seems to look for a FrameWnd whch could be further up the ownership chain.  Using the m_hWndParent, or whatever the member var of CDialog is called, is an alternative.)

<is processingInIncrements a static boolean>
It can be static but it doesn't need to as you have created a variable of type CDlgB and are calling the meber function of that variable.

<In PumpMessages(), you say must call Create() before using the dialog - for which object>
oops, I pulled this code out of a modeless dlg that was to display progress for long ops, I had the comment referring to the ASSERT for me should I make a mistake in it's use some years later.  You can ignore this comment.
I'm STILL not sure how to get a pointer to CDlgA to pass to the StartProcess method - should I create a variable of CDlgA type in my CDlgB header file?

Thanks Andy (notice the increase in points).
=)

In your DlgA where you create the variable of type CDlgB the 'this' keyword is a pointer to the instance of that dialog.  The 'this' keyword is a pointer to the local class you are currently in.  (If you know Visual Basic the equivalent there is Me - at least I think that is correct, I'm not a VB specialist).

In CDlgA where you start the processing off you will have code like.

CDlgB dlg(this);
dlg.StartProcess(this);
dlg.DoModal();


As your progress meter is in an instance of DlgA then you do need a pointer to that running instance of dialogA.
<As your progress meter is in an instance of DlgA then you do need a pointer to that running instance of dialogA.>

What do you mean? I need a reference to dialogA in DlgB?

(thanks for your patience)
Hm, never mind. I understand what you're trying to say, I think.

All of my processing is currently in DlgB's onInitDialog() method - if I rip all of it out of there and put all of it in a new StartWork() method, will the dialog work correctly?



I ran into some errors while trying to compile this method:  void StartProcess ( CDlgA* pDlgA)

The error messages are as follows:
error C2061: syntax error : identifier 'CDlgA'
error C2065: 'pDlgA' : undeclared identifier
error C2448: 'CDlgB::StartProcess' : function-style initializer appears to be a function definition

Help?





Okay, yay! I got everything almost working - (thanks Andy!) except for one thing:

In this method:

void StartProcess(CDlgA* pDlgA)
{
  while(processingInIncrements)
  {
    DoSomeWork();
    pDlgA->IncrementProgressMeter(ProgressOfYourWork):  //eg. as %
  }
}

where it says DoSomeWork, I have a bunch of processing going on and I would like the progress bar to increment at each step, so I repeated this statement:   pDlgA->IncrementProgressMeter(ProgressOfYourWork) after each processing statement, thinking that it would do the trick.

Sadly, no. How would this be possible?

Please advise (TIA)
s/.



Yay, it all works, thanks Andy! =)
Glad to here it's OK now.
Do you understand all what I suggested and what it is doing?
Yes, thank you.  :)

Repeating this statement:  pDlgA->IncrementProgressMeter(ProgressOfYourWork) after each processing statement, did not increment the progress bar, though - it only did it once (I had to set the ProgressOfYourWork variable to 75, so that it would work).

What am I doing wrong?

Here's my code:

void CLayerPresentationGUI2MFCDlg::StartProcess(SplashDialog* pSplashDlg)
{
      int workProgress = 75;

      processingWorkIncrements = true;
      ErrorHandler::RaiseError( ErrorLevels::Debug, TEXT("FileSystem::GetInstance...") );
                FileSystem& fs = FileSystem::GetInstance();
      TCHAR activepath[MAX_PATH+1] = {0};

                ErrorHandler::RaiseError( ErrorLevels::Debug, TEXT("ApplicationLogic::GetInstance...") );
                ApplicationLogic& logic = ApplicationLogic::GetInstance();

                while(processingWorkIncrements)
      {
            pSplashDlg->IncrementProgressMeter(workProgress);
            ErrorHandler::RaiseError( ErrorLevels::Debug, TEXT("Dumping resources...") );
            // Prepare the environment
            DumpResources::DumpFileResources( m_hWnd );
       
            
   
            ErrorHandler::RaiseError( ErrorLevels::Debug, TEXT("logic.LoadSoftwareData...") );
            logic.LoadSoftwareData( TEXT("EasyReqs.xml") );
            pSplashDlg->IncrementProgressMeter(workProgress);
        
            ErrorHandler::RaiseError( ErrorLevels::Debug, TEXT("logic.LoadHardwareData...") );
            logic.LoadHardwareData();
            pSplashDlg->IncrementProgressMeter(workProgress);
        
      
            ErrorHandler::RaiseError( ErrorLevels::Debug, TEXT("logic.DoComparison...") );
            logic.DoComparison();
            //pSplashDlg->IncrementProgressMeter(workProgress);
            //pSplashDlg->IncrementProgressMeter(workProgress);
        

            ErrorHandler::RaiseError( ErrorLevels::Debug, TEXT("logic.GenerateXml...") );
            fs.GenerateFilePath( activepath, MAX_PATH, SystemPaths::Documents, TEXT("EasyInfo.xml") );
            Archiver::XsltPath.Set( TEXT("EasyInfo.xsl") );
            
            logic.GenerateXml( activepath );
            //pSplashDlg->IncrementProgressMeter(workProgress);

            ErrorHandler::RaiseError( ErrorLevels::Debug, TEXT("logic.GenerateXmlNoXslt...") );
            fs.GenerateFilePath( activepath, MAX_PATH, SystemPaths::Documents, TEXT("SansXSLT.xml") );
            logic.GenerateXmlNoXslt( activepath );
            //pSplashDlg->IncrementProgressMeter(workProgress);

            ErrorHandler::RaiseError( ErrorLevels::Debug, TEXT("Store Data (HTML)...") );
            fs.GenerateFilePath( activepath, MAX_PATH, SystemPaths::Documents, TEXT("EasyInfo.htm") );
            Archiver::XsltPath.Set( TEXT("EasyInfo.xsl") );
            logic.GenerateXml( activepath );
            //pSplashDlg->IncrementProgressMeter(workProgress);

            AsHtml foo;
                  
            FileSystem::GetInstance().GenerateFilePath( activepath, MAX_PATH, SystemPaths::Documents, TEXT("EasyInfo.htm") );
                foo.WriteToFile( logic.hardware.Data, logic.compinfo, activepath );
                  
            
            processingWorkIncrements = false;
      }


}

Any advice, Andy?

TIA,
S/.
You have a line
int workProgress = 75;
and then each call to
pSplashDlg->IncrementProgressMeter(workProgress);
is in reality
pSplashDlg->IncrementProgressMeter(75);

You need to change the value of workProgress to display the progress.

eg. When you initialise the progress control use SetRange(0, 100) to set the min and max values and also SetPos(0) so the initial start position is zero (it is always safest to initialise so you know the values are what you require).

Then as you process
pSplashDlg->IncrementProgressMeter(5);
...
pSplashDlg->IncrementProgressMeter(18);
...
pSplashDlg->IncrementProgressMeter(47);

and so on


Thank you Andy - that did it! =)