2012-09-07 38 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); 
    } 
}