GreateProcess Модальный
От: VEZ Россия  
Дата: 10.11.05 12:08
Оценка:
Можно ли с помощью CreateProcess запустить приложение чтоб его окно было модальным по отношению к запускающему приложению, проблема в том что я запускаю приложение и жду окончание его работы WaitForSingleObject, моё приложение при этом просто висит, и если убрать окно запускаемого приложения на задний план, то можно подумать что оно действыительно зависло, надо сделать так чтоб окно приложения нельзя было убрать на задний план по отношению к окну моего приложения.
Re: GreateProcess Модальный
От: McQwerty Россия  
Дата: 10.11.05 13:12
Оценка:
VEZ>Можно ли с помощью CreateProcess запустить приложение чтоб его окно было модальным по отношению к запускающему приложению, проблема в том что я запускаю приложение и жду окончание его работы WaitForSingleObject, моё приложение при этом просто висит, и если убрать окно запускаемого приложения на задний план, то можно подумать что оно действыительно зависло, надо сделать так чтоб окно приложения нельзя было убрать на задний план по отношению к окну моего приложения.

Может, спрятаться на момент работы запускаемого приложения?
Re: GreateProcess Модальный
От: Кодт Россия  
Дата: 10.11.05 13:12
Оценка:
Здравствуйте, VEZ, Вы писали:

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


Готового способа, по-видимому, нет. Но вручную сделать, наверное, несложно.
1) Научимся ждать без зависания. Это либо MsgWaitForSingleObject, либо WaitForSingleObject с нулевым таймаутом.
Примерно так:
enum WaitResult { W_R_SUCCEEDED, W_R_TIMEOUT, W_R_POSTQUIT, W_R_FAULT };

WaitResult WaitAndPumpMessages(HANDLE object, DWORD timeout)
{
  bool realistic = timeout!=0 && timeout!=INFINITE; // в случае ненулевого и небесконечного таймаутов требуется перевычислять ожидания
  DWORD start, elapsed, expiry; // начало работы, сколько прошло и сколько осталось (если !realistic, не используются)
  if(realistic)
    start = GetTickCount();
  if(!realistic)
    expiry = timeout; // будем ждать "мгновенно" или "бесконечно" - настроим ровно один раз

  while(true) // пока не надоест...
  {
    if(realistic)
    {
      elapsed = GetTickCount()-start; // допускается перекручивание через 0
      expiry = (elapsed > timeout) ? 0 : elapsed-timeout; // min(0,elapsed-timeout) нельзя - у нас беззнаковая арифметика
      // elapsed > timeout может произойти, если между start= и elapsed= поток был вытеснен. Дадим последний шанс.
    }

    DWORD waited = MsgWaitForSingleObject(1, &object, true, expiry, QS_ALLEVENTS);
    if(waited == WAIT_OBJECT_0) // процесс перешёл в сигнальное состояние
      return W_R_SUCCEEDED;
    if(waited == WAIT_OBJECT_0 + 1) // пришло сообщение
    {
      MSG msg;
      BOOL quit = GetMessage(&msg,NULL,0,0);
      if(quit) // WM_QUIT
        return W_R_POSTQUIT;
      TranslateMessage(&msg);
      DispatchMessage(&msg);
      continue;
    }
    if(waited == WAIT_TIMEOUT)
      return W_R_TIMEOUT;
    return W_R_FAULT;
  }
}


2) Обеспечим модальность. Самое дубовое решение — это сказать своему главному окну, что оно disabled. А по окончании — вернём в enabled.

Если дочерний процесс — "свой", то можем передать в него хэндл нашего окна, и пусть он свои окна делает дочерними от нашего. Тогда попытка активизировать наши окна приведёт к активизации окон процесса. "Я так думаю".



3) Но, на мой взгляд, лучше завести модальный диалог с кнопкой "наплевать и не ждать". А запуск и ожидание процесса выполнить из рабочего потока, подконтрольного этому диалогу.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.