< お手軽矩形塗りつぶし | 汎用キュークラス >

May 11, 2005

CToolTipCtrl で TTS_ALWAYSTIP を指定しても無効コントロールのツールチップが表示されない

タイトルの通り。以下の情報を元に、派生クラスを作成しました。コントロールが重なっている場合に考慮できていませんが。

#pragma once
#pragma warning (disable: 4786)
#include <list>

/********************************************************************
 *    CMaskBitmap クラスの宣言                                      *
 ********************************************************************/

class CAlwaysTipCtrl :public CToolTipCtrl
{
public:
    CAlwaysTipCtrl ();
    virtual BOOL Create (CWnd* pParentWnd, DWORD dwStyle = 0);
    virtual BOOL AddTool (CWnd* pWnd, UINT nIDText, LPCRECT lpRectTool = NULL, UINT_PTR nIDTool = 0);
    virtual BOOL AddTool (CWnd* pWnd, LPCTSTR lpszText = LPSTR_TEXTCALLBACK, LPCRECT lpRectTool = NULL, UINT_PTR nIDTool = 0);
    virtual void DelTool (CWnd* pWnd, UINT_PTR nIDTool = 0);
    virtual void RelayEvent (LPMSG lpMsg);

protected:
    typedef std::list<HWND> WNDLIST;
    WNDLIST m_WndList;
    CWnd* m_pParentWnd;
};

/********************************************************************
 *    CMaskBitmap クラスの実装                                      *
 ********************************************************************/

/*!
コンストラクタ:初期化を行います
*/

inline CAlwaysTipCtrl::CAlwaysTipCtrl ()
: m_pParentWnd (NULL)
{
}


/*!
ウインドウ作成処理:ツール ヒント コントロールを作成し、CToolTipCtrl オブジェクトに結び付けます。
@param pParentWnd [in] ツール ヒント コントロールの親ウィンドウを指定します。 
@param dwStyle [in] ツール ヒント コントロールのスタイルを指定します。
@retval 正しく作成された場合は 0 以外を返します。それ以外の場合は 0 を返します。
*/

inline BOOL CAlwaysTipCtrl::Create (CWnd* pParentWnd, DWORD dwStyle)
{
    m_pParentWnd = pParentWnd;
    return CToolTipCtrl::Create (pParentWnd, dwStyle|TTS_ALWAYSTIP);
}


/*!
ツールチップ追加処理:ツール ヒント コントロールにツールを登録します。
@param pWnd [in] ツールを保持するウィンドウへのポインタ。 
@param nIDText [in] ツールのテキストを表す文字列リソースの ID。 
@param lpRectTool [in] ツールに外接する四角形の座標を保持する RECT 構造体へのポインタ。座標は、pWnd で識別されるウィンドウのクライアント領域の左上隅からの相対値です。 
@param nIDTool [in] ツールの ID。 
@retval 正常終了した場合は 0 以外を返します。それ以外の場合は 0 を返します。
*/

inline BOOL CAlwaysTipCtrl::AddTool (CWnd* pWnd, UINT nIDText, LPCRECT lpRectTool, UINT_PTR nIDTool)
{
    m_WndList.push_back (pWnd->m_hWnd);
    return CToolTipCtrl::AddTool (pWnd, nIDText, lpRectTool, nIDTool);
}


/*!
ツールチップ追加処理:ツール ヒント コントロールにツールを登録します。
@param pWnd [in] ツールを保持するウィンドウへのポインタ。 
@param lpszText [in] ツールのテキストへのポインタ。このパラメータに値 LPSTR_TEXTCALLBACK を指定すると、TTN_NEEDTEXT 通知メッセージは pWnd が指すウィンドウの親に送られます。 
@param lpRectTool [in] ツールに外接する四角形の座標を保持する RECT 構造体へのポインタ。座標は、pWnd で識別されるウィンドウのクライアント領域の左上隅からの相対値です。 
@param nIDTool [in] ツールの ID。 
@retval 正常終了した場合は 0 以外を返します。それ以外の場合は 0 を返します。
*/

inline BOOL CAlwaysTipCtrl::AddTool (CWnd* pWnd, LPCTSTR lpszText, LPCRECT lpRectTool, UINT_PTR nIDTool)
{
    m_WndList.push_back (pWnd->m_hWnd);
    return CToolTipCtrl::AddTool (pWnd, lpszText, lpRectTool, nIDTool);
}


/*!
ツールチップ削除処理:ツール ヒント コントロールがサポートしているツールのコレクションから、pWnd と nIDTool で指定されるツールを削除します。
@param pWnd [in] ツールを保持するウィンドウへのポインタ。 
@param nIDTool [in] ツールの ID。 
*/

inline void CAlwaysTipCtrl::DelTool (CWnd* pWnd, UINT_PTR nIDTool)
{
    WNDLIST::iterator& itr = m_WndList.begin ();
    for (; m_WndList.end () != itr; itr ++)
    {
        if (pWnd->m_hWnd == *itr)
        {
            m_WndList.erase (itr);
            break;
        }
    }
    return CToolTipCtrl::DelTool (pWnd, nIDTool);
}


/*!
メッセージリレー処理:ツール ヒント コントロールにマウス メッセージを渡して処理します。
param lpMsg [in] 受け渡すメッセージを保持する MSG 構造体へのポインタ。 
*/

inline void CAlwaysTipCtrl::RelayEvent (LPMSG lpMsg)
{
    MSG RelayMsg;
    CopyMemory (&RelayMsg, lpMsg, sizeof (MSG));

    if (RelayMsg.message == WM_MOUSEMOVE)
    {
        WNDLIST::iterator& itr = m_WndList.begin ();
        CRect rect;
        for (; m_WndList.end () != itr; itr ++)
        {
            if (!::IsWindowEnabled (*itr))
            {// ツールチップを持つウインドウが無効状態なら、その親のメッセージとして処理されている
                ::GetWindowRect (*itr, &rect);
                CPoint point (RelayMsg.lParam);
                ::ClientToScreen (RelayMsg.hwnd, &point);
                if (rect.PtInRect (point))
                {// ポインタはウインドウ上
                    bool bFound = false;
                    HWND hWnd = *itr;
                    while (hWnd)
                    {// 親探しループ
                        if (hWnd = ::GetParent (hWnd))
                        {// 親あり
                            if (RelayMsg.hwnd == hWnd)
                            {
                                ::ScreenToClient (*itr, &point);
                                RelayMsg.hwnd = *itr;
                                RelayMsg.lParam = MAKELPARAM (point.x, point.y);
                                bFound = true;
                                break;
                            }
                            if (hWnd == m_pParentWnd->m_hWnd)
                            {
                                break;
                            }
                        }
                    }
                    if (bFound)
                    {
                        break;
                    }
                }
            }
        }
    }
    CToolTipCtrl::RelayEvent (&RelayMsg);
}

トラックバック

このエントリーにトラックバック:
http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/956

コメント

コメントする

※ コメントスパム対策のため、コメント本文はおはよう、こんにちわ、こんばんわのいずれかより始めるようにしてください。

name:
email:

※ 必要ですが、表示しません。

url:
情報を保存する ?