We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x

Connect two dialog windows with a progress bar

stitch2802
stitch2802 asked
on
Medium Priority
342 Views
Last Modified: 2013-11-20
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.
Comment
Watch Question

Freelance programmer / Consultant
CERTIFIED EXPERT
Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview

Author

Commented:
Thanks Andy. I'll try this out and report back. =)

Author

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

Author

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
AndyAinscowFreelance programmer / Consultant
CERTIFIED EXPERT

Commented:
Which bit don't you understand / isn't working

Author

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/.
AndyAinscowFreelance programmer / Consultant
CERTIFIED EXPERT

Commented:
<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.

Author

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).
=)

AndyAinscowFreelance programmer / Consultant
CERTIFIED EXPERT

Commented:
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.

Author

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)

Author

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?



Author

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?





Author

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/.



Author

Commented:
Yay, it all works, thanks Andy! =)
AndyAinscowFreelance programmer / Consultant
CERTIFIED EXPERT

Commented:
Glad to here it's OK now.
Do you understand all what I suggested and what it is doing?

Author

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/.
AndyAinscowFreelance programmer / Consultant
CERTIFIED EXPERT

Commented:
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


Author

Commented:
Thank you Andy - that did it! =)
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a free trial preview!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.