【问题标题】:Hiding an MFC dialog box隐藏 MFC 对话框
【发布时间】:2012-01-05 12:10:48
【问题描述】:

好的,所以我正在使用此代码来隐藏基于对话框的 MFC 应用程序 (VC++) 的任务栏图标。每当我单击十字或关闭按钮时,任务栏图标和对话框都会隐藏。但我不能把这件事做对。每当我从标题栏点击关闭或十字按钮时,对话框首先闪烁并显示一种中间对话框,然后隐藏。这很烦人。经过两天徒劳的努力,我在这里发布了我的代码。所以请大家帮帮我。提前致谢。

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;
}

这是对话框的屏幕截图。当我按下关闭或交叉按钮时,最初看起来像this 的对话框在不到半秒的时间内变成了this,然后消失(隐藏)。

【问题讨论】:

  • 如果您不想在任务栏中显示对话框,请更改窗口样式。不要弄乱不可见的父窗口(不可见的窗口的子窗口......不可见)。查看 WS_EX_TOOLWINDOW。
  • 另外你不应该直接切换 WS_VISIBLE。使用 ShowWindow(SW_HIDE)。

标签: c++ visual-studio winapi visual-c++ mfc


【解决方案1】:

也许是一件显而易见的事情,但是当您在重新设置对话框之前进行隐藏时会发生什么?还有如果不直接修改窗口样式而是使用ShowWindow(SW_HIDE)怎么办?

最后,您是否尝试过在调用 SetParent() 之前将对话框的窗口样式切换为 WS_CHILD 和/或可能将其移出客户区以便不再显示窗口(MoveWindow(-1000, -1000)或类似的东西)。

【讨论】:

  • 除非您有示例代码显示它可以工作,否则它不太可能会工作。包括MFC专家在内的很多人都试过了。在推测之前研究 MFC 源代码。我会解释为什么这个响应不起作用,但我已经有很多年没有尝试解决这个问题了。
  • 所以你还是没有头绪,你觉得有必要对一个 6 岁的问题发表一个聪明的回答吗?为什么还要麻烦?
  • 再看一遍。发表评论后,我继续复制我在Hiding a Dialog Initially 中的答案。发表我所做的评论的一个很好的理由是为人们节省一些时间。
  • 很多年前,我花了很多时间,包括研究MFC源代码,初步解决了隐藏模态对话框的问题。主要问题是与其他代码混合的是显式显示模式对话框的代码和需要替换相对大部分代码的覆盖。
  • 您确实说过“将其移出客户区”,但您不确定。这很接近,但并不完全是实际需要的。
【解决方案2】:

如果您使用CDialog::DoModal() 显示对话框,框架将确保显示您的对话框。只有一种方法可以防止显示模式对话框:

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);
}

【讨论】:

  • 此方法在 Windows 10 中按 Alt + Tab 时不会隐藏应用程序。
【解决方案3】:

我认为 Paul DiLascia 推荐了以下内容。这仅适用于模式对话框。

可以将以下代码放入 OnInitDialog 以将对话框移出屏幕。您需要实现一种方法,以便在适当的时候将其移回屏幕。

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

l33t 的答案看起来不错,可能更好,但这是一个替代方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    相关资源
    最近更新 更多