Я знаю, как заставить CDialog всегда оставаться поверх всех других окон в вашей программе … немодально. Как видно из метода тестирования ниже (код), вы не создаете с помощью * .DoModal. Это я поняла.
void CMFCTestAApp::OnOpenNonModalDialog()
{
//dialogTest new_dialog;
//new_dialog.DoModal();
dialogTest* test_dialog = NULL;
test_dialog = new dialogTest();
if(test_dialog != NULL)
{
if(test_dialog->Create(IDD_TestA_DIALOG))
test_dialog->ShowWindow(SW_SHOWNORMAL);
}
}
Тем не менее, мне не удалось сделать то же самое с чем-то, что наследует от CMultiDocTemplate / CFormView
Вопрос: есть ли способ сохранить CFormView, который вставлен в CMultiDocTemplate сверху (на переднем плане … как ведет себя немодальный CDialog), даже если это окно не является окном, которое имеет фокус. Другими словами, я хочу, чтобы classX, который наследуется от CFormView, всегда оставался перед classY, который наследовал от CView.
Частичный успех: мне удалось добиться частичного успеха. Когда был применен метод OnActivateView класса Y (это класс / окно, которое должно быть в фоновом режиме), то в его OnActivateView я бы перебрал все объекты classX (те, которые я хочу впереди) и перенес их на фронт, используя classx-> bringToTop (); Это сработало, однако, происходило смехотворное количество мерцания … Я предполагаю, потому что (1) к тому времени, когда вызывается OnActivateView класса Y, classY уже выведен на передний план всех объектов classX И, потому что (2) OnActivateView вызывается не только один раз, но и шесть раз (не знаю, почему так много раз) … OnActivateView каждого объекта вызывается в любое время. Любое другое окно активируется (не только тогда, когда активируется окно, которое вам нужно).
Вопрос: может ли кто-нибудь найти лучший способ реализовать это, о чем я скучаю или не знаю? Я уже пробовал тестировать classx-> SetWindowPos (&classx-> wndTop, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE), но это не оказало влияния. Я предполагаю, что я использую это в неправильном месте, или это отменяется в другой части кода.
Попробуйте добавить сообщение WM_ACTIVATETOPLEVEL в диалоге и использовать SetWindowPos () при изменении события WA_INACTIVE.
как это:
void CMFCTestAApp::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
CDialogEx::OnActivate(nState, pWndOther, bMinimized);
// TODO: Add your message handler code here
if (nState == WA_INACTIVE)
{
::SetWindowPos( this->m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
}
}
Пытаться
SetWindowPos(&test_dialog->wndTopMost, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);
Я могу подтвердить, что это помогло сделать некоторые панели инструментов самыми передовыми в моем случае. Но так как панели инструментов обернуты в объект CMiniFrame, мне пришлось сделать
CWnd* pWnd= pUserToolbar->GetParentMiniFrame();
if(pWnd)
pWnd->SetWindowPos(&pWnd->wndTopMost, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE);