Hiding an MFC dialog box

2019-03-16 17:44发布

问题:

Ok so I am using this code to hide the taskbar icon of a dialog based MFC application(VC++). The taskbar icon and the dialog box hide whenever I click on the cross or the close buttons. But I can’t get this one thing right. Whenever I hit the close or the cross button from title bar, the dialog box first flickers and shows a sort of intermediate dialog box and then hides. This is very annoying. I am posting my code here after two days of vain effort. So guys please help me. Thanks in advance.

void CMyAppDlg::OnBnClickedCancel()
{
  // TODO: Add your control notification handler code here
  CWnd* pWnd;
  pWnd = AfxGetMainWnd();

  RemoveTaskbarIcon(pWnd);
  pWnd->ModifyStyle(WS_VISIBLE, 0);
  mVisible = FALSE;
}

BOOL CMyAppDlg::RemoveTaskbarIcon(CWnd* pWnd)
{
  LPCTSTR pstrOwnerClass = AfxRegisterWndClass(0);

  // Create static invisible window
  if (!::IsWindow(mWndInvisible.m_hWnd))
   {
    if (!mWndInvisible.CreateEx(0, pstrOwnerClass, _T(""),
             WS_POPUP,
             CW_USEDEFAULT,
             CW_USEDEFAULT, 
             CW_USEDEFAULT, 
            CW_USEDEFAULT,
             NULL, 0))
      return FALSE;
   }

   pWnd->SetParent(&mWndInvisible);

  return TRUE;
}

Here are the screen shots of dialog box. When I press the close or cross button, the dialog box which looks like this in the first place turns into this for like less than half a second and then disappears (hides).

回答1:

If you show your dialog using CDialog::DoModal() the framework will make sure your dialog is shown. There is only one way to prevent a modal dialog from being shown:

BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
    ON_WM_WINDOWPOSCHANGING()
END_MESSAGE_MAP()

BOOL CHiddenDialog::OnInitDialog()
{
    CDialog::OnInitDialog();
    m_visible = FALSE;

    return TRUE;
}

void CHiddenDialog::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) 
{
    if (!m_visible)
        lpwndpos->flags &= ~SWP_SHOWWINDOW;

    CDialog::OnWindowPosChanging(lpwndpos);
}


回答2:

Maybe an obvious thing, but what happens when you do the hide before you reparent the dialog? Also what if you don't directly modify the window style but use ShowWindow(SW_HIDE)?

Finally, have you tried switching the dialog's window style to WS_CHILD before calling SetParent() and/or maybe moving it out of the client area so that the window isn't shown any more (MoveWindow(-1000, -1000) or something like that).



回答3:

I think Paul DiLascia recommended the following. This is for modal dialogs only.

The following code can be put in OnInitDialog to move the dialog off-screen. You will need to implement a method for moving it back on-screen when appropriate.

CRect DialogRect;
GetWindowRect(&DialogRect);
int DialogWidth = DialogRect.Width();
int DialogHeight = DialogRect.Height();
MoveWindow(0-DialogWidth, 0-DialogHeight, DialogWidth, DialogHeight);

The answer from l33t looks good and is probably better but this is an alternative.