简体   繁体   中英

Controls not rendering in modeless dialog box MFC

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: 在此处输入图片说明

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: 在此处输入图片说明

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!

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, ie 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;
}

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);
    }
}

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM