控件不在无模式对话框 MFC 中呈现
Posted
技术标签:
【中文标题】控件不在无模式对话框 MFC 中呈现【英文标题】:Controls not rendering in modeless dialog box MFC 【发布时间】:2012-09-07 16:28:08 【问题描述】:更新:可能的解决方案。在标题中声明 CWait 对话框似乎可以解决这个问题。
UPDATE2:消息泵可能是罪魁祸首。显式“抽水”似乎可以解决问题。
我试图在应用程序中执行某些功能时显示一个模式“请稍候”对话框。我要显示的对话框是这样的:
我正在使用此代码来调用对话框。
CWait dialog;
dialog.Create(IDD_WAIT);
dialog.SetWindowTextW(L"Geocoding");
dialog.ShowWindow(SW_SHOW);
mastImageGeocode(); //Working here
slvImageGeocode();
interfImageGeocode();
cohImageGeocode();
dialog.CloseWindow();
最终显示的是这样的:
我似乎无法弄清楚为什么控件不呈现。
我尝试在使用这种方法初始化对话框后手动处理消息循环:
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;
我是不是做错了什么。
感谢您的帮助。
更新:如果我在单个函数中调用它,它工作正常!
【问题讨论】:
作为一个快速测试,dialog.ShowModal();工作好吗? @JBRWilkinson 你的意思是 doModal() 对吧?CWait dialog; dialog.DoModal();
对我有用。
如果我在 3 个函数中的每一个中都放了相同的代码,它会工作一次,下次就不能工作了(显示)
更新:可能的解决方案。在标题中声明 CWait 对话框似乎可以解决这个问题。
【参考方案1】:
听起来您没有从主处理循环中更新对话框。我在下面放了一个精简版的 MFC 进度对话框。请注意,需要定期调用 SetProgress 来更新屏幕。更一般地说,如果您在 MFC 中使用无模式对话框,则需要调用 OnUpdate(FALSE) 让它们刷新,并确保它们有足够的时间这样做。很多时候,当我认为我需要一个无模式对话框时,实际上通过将任务分成单独的线程来为我提供更好的服务,即处理部分被放置在它自己的工作线程中。 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;
【讨论】:
我发现我在您的代码中犯了一些错误。谢谢!我还没有制作线程程序。有什么好的链接可以轻松进入多线程工作流程吗? (我真的很想学习)【参考方案2】:您不仅需要在对话框开始时手动发送消息,还需要在更新后手动发送消息。 像这样的:
void CProgressDialog::SetProgress(int Progress)
m_progressBar.SetPos(Progress);
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
TranslateMessage(&msg);
DispatchMessage(&msg);
【讨论】:
【参考方案3】:用途:
m_progressBar.SetPos(Progress+1);
m_progressBar.SetPos(进度);
它会显示出来。不要问我为什么... PS.:到达最后一个 Progressstep 时请注意!
【讨论】:
以上是关于控件不在无模式对话框 MFC 中呈现的主要内容,如果未能解决你的问题,请参考以下文章
使用纯 Windows API 设置 StaticText 控件文本,无 MFC