Я их породил, я их и...
От: Мыкола Россия  
Дата: 15.10.02 11:58
Оценка:
Здравствуйте, уважаемые!
Мне тут понадобилась возможность принудительно позакрывать все диалоги в моем приложении. Покопался в форумах, что-то по этому поводу было, но проблемма так и не была решена. Набросал такую функцию:

BOOL CloseAllDialogs()
{
    HWND hWnd=GetLastActivePopup();
    if(hWnd==m_hWnd) return TRUE;
    HANDLE hTimer=::CreateWaitableTimer(NULL,FALSE,NULL);
    if(hTimer==NULL) return FALSE;
    LARGE_INTEGER t; t.QuadPart=-200; int cntr=100;
    while((hWnd!=m_hWnd)&&(cntr>0))
    {
        ::EndDialog(hWnd,IDCANCEL);
        if(!::SetWaitableTimer(hTimer,&t,0,NULL,NULL,FALSE)) break;
        AtlWaitWithMessageLoop(hTimer);
        // ???
        hWnd=GetLastActivePopup();
        cntr--;
    }
    ::CloseHandle(hTimer);
    return (hWnd==m_hWnd);
}


Таймер создаю и жду с помощью AtlWaitWithMessageLoop чтобы не дублировать код цикла ожидания сообщений. А сообщения надо пообрабатывать чтобы диалог реально разрушился (вычитал в MSDN'е что EndDialog() только взводит флаг, который анализируется системой при обработке первого сообщения).
Тем не менее, вызов GetLastActivePopup() внутри цикла не возвращает мне m_hWnd, как я ожидал (похоже, там так и остается HWND только что прибитого окна).
Может, кто-нибудь подскажет мне недостающее звено?
Re: Я их породил, я их и...
От: Мыкола Россия  
Дата: 15.10.02 12:08
Оценка:
Забыл уточнить:
1. Ф-я должна вернуть TRUE, когда прибьет все окна диалога.
2. Ф-ю вызываю из окна верхнего уровня — главного окна приложения.
3. Одно окно диалога она мне прибивает, но возвращает FALSE.
4. Если окон диалога несколько (напр. одно открыло другое и т.д.), то закрывается только последнее.
Re: Я их породил, я их и...
От: old Dutchman Беларусь http://blogs.rsdn.org/ikemefula
Дата: 15.10.02 12:17
Оценка:
Здравствуйте Мыкола, Вы писали:

М>Здравствуйте, уважаемые!

М>Мне тут понадобилась возможность принудительно позакрывать все диалоги в моем приложении. Покопался в форумах, что-то по этому поводу было, но проблемма так и не была решена. Набросал такую функцию:

Делай так


#define WM_KILLDIALOG (WM_APP+1)


{
    AfxGetMainWnd()->PostMessage(WM_KILLDIALOG); // сообщение должно разойтись по всем окнам

}



И в каждый диаложек добавляешь


BEGIN_MESSAGE_MAP( CDialog, CMyDialogN102 )
    //{{AFX_MSG_MAP( CMyWnd
    // ... Possibly more entries to handle additional messages

    ON_MESSAGE(WM_KILLDIALOG,OnKillDialog)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP( )



afx_msg LRESULT CMyDialogN102::OnKillDialog(WPARAM, LPARAM)
{
    if(m_bModal)
    {
    // Тут его прибиваем

    }
}



Еще нужно переопределить метод DoModal — он виртуальный

int CMyDialogN102::DoModal()
{
    int iRet; // это чтоб можно было диалог юзать и модально, и немодально

    m_bModal = TRUE;
    CDialog::DoModal();

    return iRet;
}


Ну и в заголовочный файл добавить соответствующие описания методов и BOOL m_bModal;
Re[2]: Я их породил, я их и...
От: old Dutchman Беларусь http://blogs.rsdn.org/ikemefula
Дата: 15.10.02 12:28
Оценка:
Здравствуйте old Dutchman, Вы писали:

Не заметил я, что ATL/WTL — из почты отвечал
Re[2]: Я их породил, я их и...
От: Мыкола Россия  
Дата: 15.10.02 12:32
Оценка:
Здравствуйте old Dutchman, Вы писали:


OD>Делай так

[]

Эхе-хе...
Муторно это — все диалоги в приложении так дополнять. А вдруг кого забуду? А если еще месседжбокс болтается?

Я так попробовал: в цикле перед EndDialog() всобачил ::SetActiveWindow(::GetParent(hWnd)); В простом тесте сработало. Но насколько это будет универсальным решением?.. Вдруг парентом будет нулл...
Суть шаманского прикола в том, чтобы сделать активным предыдущее (следующее? ) открытое окно диалога в проге, а когда таких окон больше нет — главное окно программы. Тогда GetLastActivePopup() вернет то что надо. Но как бы это сделать не ссылаясь на парента?
Re: Я их породил, я их и...
От: old Dutchman Беларусь http://blogs.rsdn.org/ikemefula
Дата: 15.10.02 12:33
Оценка:
Здравствуйте Мыкола, Вы писали:

Посмотри мой ответ на MFC и сделай так

::PostThreadMessage(thisthread,WM_KILLDIALOG,0,0);

Вешаешь обработчик на такое сообщение и в неи прибиваешь.

Проверяешь по m_bModal — ее добавлять не надо.
Re[3]: Я их породил, я их и...
От: Мыкола Россия  
Дата: 15.10.02 12:34
Оценка:
Здравствуйте old Dutchman, Вы писали:

OD>Здравствуйте old Dutchman, Вы писали:


OD>Не заметил я, что ATL/WTL — из почты отвечал


Ну это не суть важно, идея понятна .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.