Открыть модальный диалог в MFC - PullRequest
5 голосов
/ 04 декабря 2009

Мне нужно открыть диалоговое окно, созданное дважды из одного и того же класса. Когда я пытаюсь это

CdelmeDlg dlg;
dlg.DoModal();
dlg.DoModal();

Второй вызов открывает диалог только на долю секунды, затем он закрывается. Моя ставка была в том, что в очереди сообщений есть оставшееся сообщение, поэтому я добавил это между вызовами

MSG msgCur;
while (::PeekMessage(&msgCur, NULL, NULL, NULL, PM_REMOVE))
    ;

Это решает проблему, но кажется, что это неправильно. Есть ли способ правильно обработать оставшееся сообщение?

Ответы [ 6 ]

1 голос
/ 28 января 2010

Почему вы не можете написать это так:

CdelmeDlg dlg; 
dlg.DoModal(); 

CdelmeDlg dlg1; 
dlg1.DoModal(); 
1 голос
/ 15 декабря 2009

Я на самом деле думаю, что у YeenFei есть хороший момент.

Прошло много времени с тех пор, как я играл с MFC (слава богу), но из памяти таймер может вызываться или не вызываться из потока пользовательского интерфейса в зависимости от того, какой из них вы используете. Если таймер поднимается в главном потоке пользовательского интерфейса, то модальное диалоговое окно, скорее всего, остановит основной поток до его закрытия, после чего он будет вызван следующим таймером. Если таймер поднят в отдельном потоке, то ваш диалог не блокирует основной поток пользовательского интерфейса, как это показано в отдельном потоке.

Это кажется более правдоподобным, так как YeenFei указал, что вы хотите повторно показывать свой диалог каждый раз, когда таймер срабатывает, скрывая его, когда пользователь нажимает на кнопку, чтобы закрыть его. Таким образом, если время увеличивается снова, все, что он делает, это повторно показывает диалог, независимо от того, открыто оно в данный момент или нет.

Здесь есть отличный пост (www.eggheadcafe.com) о таймерах и параллелизме, который может показаться вам интересным и может сделать вещи более понятными, чем то, что мне удалось сделать.

1 голос
/ 04 декабря 2009

Не вызывать EndDialog (IDOK);

Чтобы обработать нажатие кнопок «ОК» или «Отмена», просто наследуйте OnOk или OnCancel ... В противном случае EndDialog будет вызываться дважды, и вы получите проблему, которую получаете!

0 голосов
/ 06 марта 2014

Может быть, ваш код имеет строку:

m_pMainWnd = &dlg;

Если это так, чем приложение после первого вызова DoModal () будет завершено, все остальные вызовы DoModal () вернут -1 Из MSDN:

Библиотека классов Microsoft Foundation автоматически прервет ваш поток, когда окно, на которое ссылается m_pMainWnd, будет закрыто. Если этот поток является основным потоком для приложения, приложение также будет прервано.

0 голосов
/ 28 января 2010

Я решил проблему, скрыв диалоговое окно вместо его закрытия и запустив другой поток, который сначала спит, а затем скрывает диалоговое окно.

0 голосов
/ 14 декабря 2009

Если вы хотите, чтобы ваше приложение запускалось в фоновом режиме без пользовательского интерфейса, почему бы не временно скрыть его? простая функция this-> ShowWindow (SW_HIDE) сделает всю работу за вас.

Я думаю, вам следует пересмотреть свое проектное решение, так как для приложения кажется нелогичным вести себя так, как вы хотели.

...