Почему CFileDialog::DoModal() зависает?

Я разработал довольно большую программу на С++ в VS 6.0 на платформе Win XP и теперь перешел на новую машину под управлением Win 7 (все еще работает с VS 6.0). Код включает функцию для создания экземпляра и запуска объекта CFileDialog для поиска и открытия файла ASCII с определенным расширением из определенного исходного каталога. Но теперь программа висит на линии

if (t1.DoModal()==IDOK)

... где t1 — экземпляр CFileDialog. Чтобы выяснить, почему стандартный класс CfileDialog перестал работать, я создал отдельный тестовый проект в VS 6.0 с простым диалоговым окном с одной кнопкой, содержащим этот код:

void CFileDialogTestDlg::OnOpenFileDialogButton() 
{
  CFileDialog t1(true);
  if(t1.DoModal()==IDOK)
  {
    CString s3=t1.GetPathName();
    MessageBox(s3);
  }
}

Этот тест работает нормально и отображает диалоговое окно с файлами. Я также могу продублировать то, что хочу, в своем большом проекте с точки зрения исходного каталога и т. д., изменив члены m_ofn t1.

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

Когда я увеличил пространство стека для своего тестового проекта, чтобы он соответствовал моему большому проекту (400 МБ), я воспроизвел поведение зависания, идентичное большому проекту.

Может ли кто-нибудь объяснить, почему увеличение пространства стека должно таким образом влиять на выполнение диалогового окна файла, и есть ли способ обойти проблему, имея в виду, что мне нужно большое пространство стека, чтобы избежать полной перезаписи моего проекта?


person Rob P    schedule 08.07.2014    source источник
comment
Использует ли ваш реальный проект многопоточность?   -  person tzerb    schedule 08.07.2014
comment
Да, отладка многопоточной DLL (настройки проекта)   -  person Rob P    schedule 08.07.2014


Ответы (2)


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

person tzerb    schedule 08.07.2014
comment
Вам нужно использовать поток пользовательского интерфейса. Проверьте, вызываете ли вы модальное окно из потока, созданного вашей программой. msdn.microsoft.com/en-us/library/b807sta6.aspx - person tzerb; 08.07.2014

Используйте PostMessage() API для отправки команд из любого потока в поток, который владеет модальным диалогом. Это должен быть владеющий (и блокирующий) поток, который в конечном итоге получает команду принять/отменить диалог, чтобы он вернулся из своей процедуры накачки сообщений.

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

person JBRWilkinson    schedule 08.07.2014