2016-10-11 3 views
0

Мое приложение должно создать несколько дорогих вещей в InitInstance(). Я хочу сообщить пользователю о ходе, поэтому я решил создать немодальное диалоговое окно в методе InitInstance().Modeless Dialog in App :: InitInstance()

Проблема моя, диалог не нарисован. Он обновляется сразу после

CStartStopDlg dlg(_T("Start")); 
dlg.Create(IDD_START_STOP_DLG); 
dlg.ShowWindow(SW_SHOW); 

// expensive stuff 

m_pMainWnd->ShowWindow(SW_SHOW); 
m_pMainWnd->UpdateWindow(); 

Даже когда я спал после этих строк, он обновляет диалоговое окно. Проблема в том, что MainFrame использует мои созданные ресурсы, поэтому я не могу изменить эти строки.

Как решить эту проблему?


EDIT: дорогостоящая материал подключение к камерам, подключение к Ио оборудования, подключение к базам данных и создания рабочих потоков. Объект приложения владеет всем этим материалом, а мэйнфрейм и его представления и т. Д. Используют это. Поскольку этот материал не связан с документом в приложении.

В зависимости от нагрузки на ethernet для соединения требуется время.

Модальный диалог не требует отклика. Я просто хочу что-то вроде диалога начала Adobe Reader.

Подсказка с UpdateWindow() была в правильном направлении, и я добавил вызов этой функции, когда обновил статус. Это решило мою проблему.

+0

Для того, чтобы диалог рисовал, приложение должно уступить. И даже если вы вызываете dlg.UpdateWindow() или что-то, диалог не будет реагировать на ввод пользователя во время выполнения этого «дорогой вещи». Может быть, создать диалоговое окно в другом потоке? Альтернативной версией было бы вместо этого выполнить «дорогой материал» под другим потоком, запланированным после инициализации приложения (например, с использованием таймера); Элементы пользовательского интерфейса должны быть отключены до тех пор, пока «дорогой материал» не будет завершен. –

ответ

2

Похоже, что ваш «дорогой материал» связан с вычислением и не позволяет обновлять нити (ы) UI. Эти типы проблем обычно решаются путем использования отдельного потока для обеспечения обратной связи с результатами. Вы можете взглянуть на Using Worker Threads для получения некоторого фона для использования потоков для решения этой проблемы.

+0

* «Похоже, что ваш« дорогой материал »связан с вычислением» * - Ничто в вопросе не указывает на это, и если бы это было так, это было бы неуместно. Важная деталь заключается в том, что она ** синхронна **. Боюсь, что бросить кусочки, чтобы скрыть недостаток проницательности, не собирается летать. Остальная часть этого предлагаемого ответа настолько расплывчата, что она заслуживает * «Этот ответ не полезен» * голосовать. – IInspectable

+0

@Inpectable, хотя я могу уважать ваше мнение, я часто удивляюсь тому, как вы реагируете на многих людей на этом сайте. По крайней мере, один человек считал мой ответ полезным, но вы пытаетесь очернить меня, не зная о первой вещи обо мне. Пришло время посмотреть в зеркало и посмотреть, откуда эта неприятная полоска. – rrirower

+0

Я не знаю, почему вы решили взять это на личном уровне. Я прокомментировал качество ответа (и вы можете отбросить этот ** один голос вверх, что, как правило, означает, что OP говорит * «Спасибо» *, но в противном случае не служит показателем качества). Этот предложенный ответ начинается с неправильного предположения и пытается предложить решения (которые применяются только по совпадению, если вообще). Если вы удивлены, я оставляю комментарий о том, почему я предлагаю ответы, предлагайте ответы, идите и поражайтесь всем, что хотите. Я могу сделать исключение для вас в будущем. – IInspectable

3

CStartStopDlg dlg(_T("Start")); создает диалог owned, так как pParentWnd неявно устанавливается в NULL (см CDialog::CDialog). Этот диалог принадлежит основному окну приложения.

Одной из особенностей принадлежащих окнам является то, что они скрыты, когда их владелец скрыт. Поэтому, пока вы не позвоните по номеру m_pMainWnd->ShowWindow(SW_SHOW);, ваш собственный диалог также не появится.

Существует множество способов обойти это.

  1. Очевидным решением является немедленное отображение основного окна приложения. Однако это может быть непрактичным (и не решает проблему с блокировкой потока пользовательского интерфейса).
  2. Распространить дорогостоящую инициализацию рабочего потока:
    Это необходимо, чтобы поток пользовательского интерфейса мог обслуживать входящие сообщения, например. в результате взаимодействия с пользователем. Вам нужно реализовать какую-то связь между рабочим потоком и потоком графического интерфейса пользователя. Обычно обычно достаточно отправить обычное сообщение (WM_APP + x) в основное окно приложения.
  3. Отложить дорогостоящую инициализацию:
    InitInstance не должно быть больше, чем требуется для запуска этого экземпляра приложения. Любые виды дорогостоящих операций следует отложить до момента, когда пользователь может увидеть пользовательский интерфейс (и, возможно, отменить эту операцию).
    Общим подходом является создание таймера с одним выстрелом для этого. Поскольку сообщения WM_TIMER являются низкоприоритетными, эти сообщения поступают только после того, как все остальные сообщения были обработаны, и приложение находится в рабочем состоянии. На этом этапе вы можете разгрузить свою дорогостоящую инициализацию в рабочий поток и отобразить диалоговое окно modal, пока оно не будет завершено.