none
CMFCToolBarのツールチップ表示で、ウィンドウの重なりが異常になる

    質問

  • CMFCToolBarを持ったウィンドウAから、他のCFrameWndのウィンドウBを表示し、ウィンドウBの下にウィンドウAが重なった状態にします。
    その状態で、ウィンドウAのツールバーボタンの上にマウスを移動してツールチップ(ボタンの説明が表示される小さなウィンドウ)を表示すると、クリックしていないにもかかわらずウィンドウAが手前に表示されてしまいます。(ウィンドウAはアクティブでないです。)
    もっと悪いことに、そのままだとウィンドウBのクライアント領域をクリックしても手前に表示されません。

    ツールチップを表示する時ウィンドウAがトップモストになってしまっているようです。
    ウィンドウAをクリックしてあげれば、その後はウィンドウBをクリックして手前に表示できます。

    CMFCToolBarのバグだと思いますが、何か良い方法はないでしょうか?

    (参考までにMFCのサンプルOutlookDemoでNew Mailのウィンドウを表示した場合も同様です。)

    2017年4月6日 4:36

回答

  • GetActiveWindowでハンドルを取得してpParent と比較してみてはどうでしょう
    • 回答としてマーク 安沢 2017年4月10日 0:54
    2017年4月6日 6:45
  • > GetActiveWindowでハンドルを取得してpParent と比較してみてはどうでしょう

    それで出来ました。ありがとうございます。

    まとめておきます。

    INT_PTR XXXXX::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
    {
        CFrameWnd* pParent = AFXGetParentFrame(this);
        if ((pParent != NULL)  && (pParent->GetSafeHwnd() != ::GetActiveWindow()))
            return -1;
        else
            return CMFCToolBar::OnToolHitTest(point, pTI);
    }

    • 回答としてマーク 安沢 2017年4月6日 7:04
    • 回答としてマークされていない 安沢 2017年4月10日 0:55
    • 回答としてマーク 安沢 2017年4月10日 0:55
    2017年4月6日 7:04

すべての返信

  • 私の環境でも再現しました。

    すみません、問題の解決方法ではなく回避方法ですが、

    ウィンドウAのタイトルバーを1度クリックすると再現しなくなるようなので、CMainFrame::OnCreateで、下記のようなコードを入れてみて解消しますでしょうか?

    SendMessage(WM_NCLBUTTONDOWN, HTCAPTION);
    SendMessage(WM_NCLBUTTONUP, HTCAPTION);
    2017年4月6日 5:25
  • OnCreateに

    SendMessage(WM_NCLBUTTONDOWN, HTCAPTION);
    SendMessage(WM_NCLBUTTONUP, HTCAPTION);

    を入れても駄目でした。

    2017年4月6日 5:42
  • ウィンドウがアクティブでない時はツールチップは表示する必要はないので止めてもいいのですがCMFCToolBar::SetShowTooltips(FALSE);

    をするとアクティブウィンドウのツールバーも含めて全て止まってしまいますし、困ったものです。

    2017年4月6日 5:52
  • CMFCToolBarの派生クラスを作成し、

    INT_PTR CMFCToolBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const

    をオーバライドして、親フレームウィンドウがアクティブでなければ-1を返すようにすればツールチップの表示を止められます。

    親フレームウィンドウは

    CFrameWnd* pParent = AFXGetParentFrame(this);

    で取得できますが、pParent がアクティブかどうかはどうすれば判断できますでしょうか?

    • 回答としてマーク 安沢 2017年4月6日 7:04
    • 回答としてマークされていない 安沢 2017年4月10日 0:54
    2017年4月6日 6:29
  • GetActiveWindowでハンドルを取得してpParent と比較してみてはどうでしょう
    • 回答としてマーク 安沢 2017年4月10日 0:54
    2017年4月6日 6:45
  • > GetActiveWindowでハンドルを取得してpParent と比較してみてはどうでしょう

    それで出来ました。ありがとうございます。

    まとめておきます。

    INT_PTR XXXXX::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
    {
        CFrameWnd* pParent = AFXGetParentFrame(this);
        if ((pParent != NULL)  && (pParent->GetSafeHwnd() != ::GetActiveWindow()))
            return -1;
        else
            return CMFCToolBar::OnToolHitTest(point, pTI);
    }

    • 回答としてマーク 安沢 2017年4月6日 7:04
    • 回答としてマークされていない 安沢 2017年4月10日 0:55
    • 回答としてマーク 安沢 2017年4月10日 0:55
    2017年4月6日 7:04