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

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.
0
stitch2802
Asked:
stitch2802
  • 12
  • 6
1 Solution
 
AndyAinscowCommented:
In dlg 'A'
CDlgB dlg(this);
dlg.StartProcess(this);
dlg.DoModal();

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

and back in dlg A
void IncrementProgressMeter(int iProg)
{
  update progress meter
    PumpMessages();  //required else it won't update the progress control
    m_Progress.SetPos(iProg);
}

void PumpMessages()
{
    // Must call Create() before using the dialog
    ASSERT(m_hWnd!=NULL);

    MSG msg;
    // Handle dialog messages
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
      if(!IsDialogMessage(&msg))
      {
        TranslateMessage(&msg);
        DispatchMessage(&msg);  
      }
    }
}
0
 
stitch2802Author Commented:
Thanks Andy. I'll try this out and report back. =)
0
 
stitch2802Author Commented:
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
0
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.

 
stitch2802Author Commented:
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
0
 
AndyAinscowCommented:
Which bit don't you understand / isn't working
0
 
stitch2802Author Commented:
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/.
0
 
AndyAinscowCommented:
<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.
0
 
stitch2802Author Commented:
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).
=)

0
 
AndyAinscowCommented:
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.
0
 
stitch2802Author Commented:
<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)
0
 
stitch2802Author Commented:
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?



0
 
stitch2802Author Commented:
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?





0
 
stitch2802Author Commented:
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/.



0
 
stitch2802Author Commented:
Yay, it all works, thanks Andy! =)
0
 
AndyAinscowCommented:
Glad to here it's OK now.
Do you understand all what I suggested and what it is doing?
0
 
stitch2802Author Commented:
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/.
0
 
AndyAinscowCommented:
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


0
 
stitch2802Author Commented:
Thank you Andy - that did it! =)
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.

  • 12
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now