2012-09-07 51 views
2

更新:可能的解决方案。在头文件中声明CWait对话框似乎解决了这个问题。控件在非模态对话框中不呈现MFC

UPDATE2:消息泵可能是罪魁祸首。明确的“抽”似乎解决了问题。

我试图显示一个模式“请稍候”对话框,而一些功能在应用程序中执行。我想要显示的对话框是: enter image description here

使用此代码调用对话框。

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

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

dialog.CloseWindow(); 

什么最终显示是这样的: enter image description here

我似乎无法弄清楚,为什么控件不渲染。

我试着手工处理的消息循环使用这种方法的对话框的初始化后:

MSG stMsg; 

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

没有真正发挥作用。

我也试过指针方式

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; 

难道我做错了什么。

感谢您的帮助。

更新:如果我在个别函数中调用它,它工作正常!

+0

作为一个快速测试,做dialog.ShowModal();工作好吗? – JBRWilkinson

+0

@JBRWilkinson你的意思是doModal()对不对? 'CWait对话框; \t \t dialog.DoModal();'确实对我有效。 – shaunakde

+0

如果我将相同的代码放在3个函数中的每一个中,它将会工作一次,下一次不会工作(显示) – shaunakde

回答

1

这听起来像你没有更新你的主要处理循环中的对话框。我在下面放置了一个我的MFC进度对话框的减少版本。请注意,有必要定期拨打SetProgress更新屏幕。作为一个更一般的观点,如果你在MFC中使用无模式对话框,你需要调用OnUpdate(FALSE)来刷新它们,并确保它们有足够的时间这样做。很多时候,当我认为我需要一个无模式对话框时,实际上通过将任务分解为单独的线程来实现更好的服务,即处理部分被放置在它自己的工作线程中。因人而异。

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; 
} 
+0

我看到我从你的代码中犯了一些错误。谢谢!我还没有制作线程程序。任何可以轻松融入多线程工作流程的良好链接? (我真的很想知道) – shaunakde

0

您不仅需要在对话框的开头,而且还需要在更新之后手动泵送消息。 类似这样的:

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

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