Можно ли с помощью CreateProcess запустить приложение чтоб его окно было модальным по отношению к запускающему приложению, проблема в том что я запускаю приложение и жду окончание его работы WaitForSingleObject, моё приложение при этом просто висит, и если убрать окно запускаемого приложения на задний план, то можно подумать что оно действыительно зависло, надо сделать так чтоб окно приложения нельзя было убрать на задний план по отношению к окну моего приложения.
Здравствуйте, 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) Но, на мой взгляд, лучше завести модальный диалог с кнопкой "наплевать и не ждать". А запуск и ожидание процесса выполнить из рабочего потока, подконтрольного этому диалогу.