Как вы отображаете диалог из скрытого окна приложения? - PullRequest
2 голосов
/ 01 сентября 2008

Я разработал 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, соответствующих тому же интерфейсу.

Ответы [ 5 ]

1 голос
/ 01 сентября 2008

Оказывается, я ошибся:

  • Если я создаю свой диалог с родителем NULL, он не отображается, и родительское приложение зависает
  • Однако, если я создаю свой диалог с :: GetConsoleWindow () в качестве родителя, то диалог отображается; он просто обманул меня, потому что он отображался за окном приложения, которое запустило родительское приложение

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

Спасибо за ответы; -)

1 голос
/ 01 сентября 2008

В зависимости от того, как работает приложение «скрытое окно», оно может не отображать окно. Например, сервисы не имеют «основного цикла сообщений» и, следовательно, не могут обрабатывать сообщения, отправленные окнам в процессе. то есть приложение, отображающее окно, должно иметь что-то вроде этого:

    while(GetMessage(&msg, NULL, 0, 0))
    {
        if(!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

в WinMain.

1 голос
/ 01 сентября 2008

Это не должно быть надежно - но попробуйте :: GetDesktopWindow () как родитель (он возвращает HWND).

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

1 голос
/ 01 сентября 2008

Вы используете родителя для диалога? например,

MyDialog dialog(pParent);
dialog.DoModal();

Если это так, попробуйте удалить родителя. Особенно если родителем является окно рабочего стола.

0 голосов
/ 09 марта 2011

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

См. Здесь для объяснения: http://blogs.msdn.com/b/oldnewthing/archive/2004/02/24/79212.aspx

Цитирую обоснование:

Составьте это: если владелец модальный диалог - рабочий стол, затем рабочий стол отключается, что отключает всех его потомков. В другими словами, это отключает каждое окно в системе. Даже тот, который ты пытаюсь отобразить!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...