0

我知道如何强制 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 的行为一样),即使该窗口不是具有焦点的窗口。所以换句话说,我希望继承自 CFormView 的 classX 始终位于继承自 CView 的 classY 前面。

部分成功:我能够取得部分成功。当 classY 的 OnActivateView 方法被击中时(这是应该在后台的类/窗口),然后,在其 OnActivateView 中,我将遍历所有 classX 对象(我想要在前面的对象)并使用它们将它们带到前面classx->bringToTop(); 这确实有效,但是,闪烁的次数非常可笑......我猜是因为(1)在调用 classY 的 OnActivateView 时,classY 已经被带到所有 classX 对象的前面,并且因为(2) OnActivateView 不只是被调用一次,而是大约六次(不知道为什么这么多次)......每个对象的 OnActivateView 随时被调用任何其他窗口被激活(不仅仅是当你关心的窗口被激活时)。

问题:任何人都可以用更好的方法来实现我所缺少或不知道的这一点吗?我已经尝试过测试 classx->SetWindowPos(&classx->wndTop,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE) 但这没有影响。我猜我在错误的地方使用它,或者它在代码的另一部分被撤消。

4

2 回答 2

1

尝试

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);
于 2016-05-07T22:12:50.387 回答
1

尝试在对话框中添加 WM_ACTIVATETOPLEVEL 消息,并在 WA_INACTIVE 事件时使用 SetWindowPos()。

像这样:

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 );
    } 
}
于 2016-05-05T02:42:11.843 回答