ОБНОВИТЬ: Возможное решение. Объявление диалога 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;
Я делаю что-то неправильно.
Спасибо за помощь.
Обновление: если я вызываю его внутри отдельных функций, он работает нормально!
Использование:
m_progressBar.SetPos (Прогресс + 1);
m_progressBar.SetPos (Прогресс);
и это покажет. Не спрашивай меня почему …
PS: внимание при достижении последнего прогресса!
Похоже, вы не обновляете свой диалог из основного цикла обработки. Я поместил урезанную версию моего диалогового окна прогресса 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;
}
Вам нужно вручную качать сообщения не только в начале диалога, но и после обновлений.
Что-то вроде этого:
void CProgressDialog::SetProgress(int Progress)
{
m_progressBar.SetPos(Progress);
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}