2
votes

UPDATE: Possible solution. Declaring the CWait dialog in the header seems to solve this.

UPDATE2: Message pump may be the culprit. Explicit "pumping" seems to resolve problem.

Im trying to display a modal "Please Wait" Dialog box while some functions execute in an application. The dialog I want to display is this: enter image description here

Im using this code to call the dialog box.

CWait dialog;
dialog.Create(IDD_WAIT);
dialog.SetWindowTextW(L"Geocoding");
dialog.ShowWindow(SW_SHOW);

mastImageGeocode(); //Working here
slvImageGeocode();
interfImageGeocode();
cohImageGeocode();

dialog.CloseWindow();

What ends up displaying is this: enter image description here

I cant seem to figure out why the controls don't render.

I tried manually processing the message loop after initialization of the dialog with this approach:

MSG stMsg;

             while (::PeekMessage (&stMsg, NULL, 0, 0, PM_REMOVE)) 
            {
            ::TranslateMessage (&stMsg);
            ::DispatchMessage (&stMsg);
            }

Did not really work.

I also tried the pointer approach

Cwait * dialog; //THis is in header
dialog = new CWait(this);
dialog->Create(IDD_WAIT);
dialog->SetWindowTextW(L"Geocoding");
dialog->ShowWindow(SW_SHOW);

mastImageGeocode(); //Some work here
slvImageGeocode();
interfImageGeocode();
cohImageGeocode();

dialog->CloseWindow();
delete dialog;

Am I doing something wrong.

Thanks for the help.

Update: If I call it inside the individual functions, it works fine!

3
As a quick test, does dialog.ShowModal(); work okay?JBRWilkinson
@JBRWilkinson You mean doModal() right? CWait dialog; dialog.DoModal(); does work for me.shaunakde
If I put the same code in each of the 3 functions, it works once and doesnt work the next time (display)shaunakde
UPDATE: Possible solution. Declaring the CWait dialog in the header seems to solve this.shaunakde

3 Answers

1
votes

It sounds like you're not updating your dialog from your main processing loop. I've put a cut down version of my MFC progress dialog below. Note that it is necessary to call SetProgress regularly to update the screen. As a more general point, if you're using modeless dialogs in MFC, you need to call OnUpdate(FALSE) for them to refresh, and ensure they have enough time to do so. Quite often when I think I need a modeless dialog, I'm actually served better by splitting the task into separate threads, i.e. the processing part gets placed in its own worker thread. YMMV.

class CProgressDialog : public CDialog
{
public:
    CProgressDialog(LPCTSTR Name,int Max,CWnd* pParent = NULL);  
    CProgressDialog(UINT NameID,int Max,CWnd* pParent = NULL);   
    virtual ~CProgressDialog();

    int m_Max;
    void SetProgress(int Progress);
    void SetRange(int Range);
    enum { IDD = IDD_PROGRESS_DIALOG };
    CProgressCtrl   m_Progress;
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);  
protected:
    virtual BOOL OnInitDialog();
    DECLARE_MESSAGE_MAP()
};


CProgressDialog::CProgressDialog(LPCTSTR Name,int Max,CWnd* pParent /*=NULL*/)
    : CDialog(CProgressDialog::IDD, pParent)
{
    Create(CProgressDialog::IDD, pParent);
    SetWindowPos(&wndTop,1,1,0,0,SWP_NOSIZE | SWP_SHOWWINDOW);
    SetWindowText(Name);
    m_Max = Max;
}


CProgressDialog::~CProgressDialog()
{
    DestroyWindow();    
}

void CProgressDialog::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_PROGRESS, m_Progress);
}


BEGIN_MESSAGE_MAP(CProgressDialog, CDialog)
END_MESSAGE_MAP()

BOOL CProgressDialog::OnInitDialog() 
{
    CDialog::OnInitDialog();
    m_Progress.SetRange32(0,m_Max);
    return TRUE; 
}

void CProgressDialog::SetProgress(int Progress) 
{
    m_Progress.SetRange32(0,m_Max);
    m_Progress.SetPos(Progress);
    UpdateData(FALSE);
}

void CProgressDialog::SetRange(int Range) 
{
    m_Max = Range;
}
1
votes

You need to manually pump messages not just at the beginning of the dialog, but after updates as well. Something like this:

void CProgressDialog::SetProgress(int Progress) 
{
    m_progressBar.SetPos(Progress);

    MSG msg;
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
0
votes

Use:

m_progressBar.SetPos(Progress+1);

m_progressBar.SetPos(Progress);

and it will show. Don't ask me why ... PS.: attention when reaching the last Progressstep!