Я разработал компонент COM (dll), который реализует метод Edit (), отображающий модальный диалог WTL.
Полный интерфейс этого COM-компонента соответствует программному стандарту, используемому в химической промышленности (CAPE-OPEN), и в результате этот COM-компонент должен использоваться рядом сторонних исполняемых файлов, которые находятся вне моего контроля.
Мой компонент работает должным образом во многих из этих EXE, но для одного, в частности, метод Edit () просто зависает без появления диалогового окна.
Однако, если я вызываю ::MessageBox() непосредственно перед DoModal(), диалоговое окно отображается и ведет себя правильно после первого отображения MessageBox.
У меня есть подозрение, что проблема может быть связана с этим конкретным EXE, запущенным как «приложение со скрытым окном».
Я пробовал использовать как NULL, так и возвращаемое значение из ::GetConsoleWindow() в качестве родителя диалога, но ни один из них не работал.
Сам диалог представляет собой ATL / WTL CPropertySheetImpl.
Рассматриваемое родительское приложение (EXE) находится вне моего контроля, поскольку оно разработано (умеренно враждебной) третьей стороной.
Я знаю, что могу успешно вызвать ::MessageBox() или отобразить стандартный диалог файлов Windows из моего COM-компонента, и что после этого я смогу отобразить свой собственный диалог. Я просто не могу отобразить свой настраиваемый диалог, не открыв сначала «стандартный» диалог.
Может ли кто-нибудь предложить, как я могу заставить его отображать диалоговое окно без предварительного отображения ненужного MessageBox? Я знаю, что это возможно, потому что я видел, как этот EXE отображает диалоговые окна других компонентов COM, соответствующих тому же интерфейсу.





Вы используете родительский элемент для диалога? например
MyDialog dialog(pParent);
dialog.DoModal();
Если да, попробуйте удалить родителя. Особенно, если родителем является окно рабочего стола.
В зависимости от того, как работает приложение «скрытое окно», оно может не отображать окно. Например, службы не имеют «основного цикла сообщений» и, следовательно, не могут обрабатывать сообщения, отправленные в окна в процессе. то есть приложение, отображающее окно, должно иметь что-то вроде этого:
while(GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
в WinMain.
Это не должно быть надежным, но попробуйте :: GetDesktopWindow () в качестве родителя (он возвращает HWND).
Будьте осторожны - если ваше приложение выйдет из строя, оно выйдет из строя вместе с ним. Но мне было бы интересно посмотреть, работает ли это.
Оказывается, я ошибся:
Так что теперь мне просто нужно выяснить, как вывести свой диалог на передний план.
Спасибо за ответы ;-)
Что бы вы ни делали, не использует окно рабочего стола в качестве родителя для вашего модального диалогового окна.
См. Объяснение здесь: http://blogs.msdn.com/b/oldnewthing/archive/2004/02/24/79212.aspx
Процитируем обоснование:
Put this together: If the owner of a modal dialog is the desktop, then the desktop becomes disabled, which disables all of its descendants. In other words, it disables every window in the system. Even the one you're trying to display!