ドロップダウンリストをサブクラス化する方法

ご存知のように、ドロップダウンリストはコンボボックスの一形態で、コンボボックスはエディットボックスとリストボックスとの複合コントロールです。

WTL::CComboBoxでは、そのままでは、内包されたコントロールを操作できません。

WTL::CComboBoxExでは、メンバ関数の GetEditCtrl() を使用することでエディットコントロールを取得できます。 しかし、やはりリストボックスを操作することはできません。

実は、WIN_VER >= 0x0500 で使用可能な GetComboBoxInfo() API を使用することでハンドルを取得できます。
これで取得されたウィンドウハンドルを元に、サブクラス化してやれば、メッセージも補足できます。

開発環境:Windows2000sp4/VC++6sp6/WTL7.0

ドロップダウンリストをサブクラス化

    // stdafx.h
    #define WIN_VER    0x0500

    // declare
        CListCtrl m_cbMode;
        CContainedWindowT<CListBox> m_wndComboList;

    // constructor
        CxxxxDialog() : 
            m_wndComboList(this, 3) // register message loop ID
        {
        }

    // message map
        BEGIN_MSG_MAP(CxxxxDialog)
            MSG_WM_INITDIALOG(OnInitDialog)
        ALT_MSG_MAP(3)    // m_wndComboList
            MSG_WM_RBUTTONDOWN(OnRButtonDownComboList)
        END_MSG_MAP

    // message handlers
        LRESULT OnInitDialog(HWND /*hWnd*/, LPARAM /*lParam*/)
        {
            m_cbMode.Attach( GetDlgItem(IDC_COMBO1) );

            // subclass window
            m_wndComboList.SubclassWindow( RtlGetComboBoxListBoxCtrl(m_cbMode) );

            return TRUE;
        }

        void OnRButtonDownComboList(UINT /*nFlags*/, CPoint /*point*/)
        {
            SetMsgHandled(FALSE);
            ATLTRACE("HERE!\n");
        }

    // helper methods
        CListBox RtlGetComboBoxListBoxCtrl(HWND hWndCmb)
        {
            COMBOBOXINFO cbi = { sizeof(COMBOBOXINFO) };
            if( ::GetComboBoxInfo(hWndCmb, &cbi) ){
                return cbi.hwndList;
            }else{
                return NULL;
            }
        }

下記のメッセージハンドラの記述で、3 とあるのは、メッセージループID です。
ここでは、3 としていますが、数字は重複していなければ何でも構いません。
ただし、コンストラクタで指定したIDとメッセージマップのIDは一致させる必要があります。

補足

    m_wndComboList(this, 3)    
    ALT_MSG_MAP(3)

[HOME]-[RTL]
Copyright© 2005-2006 RAPT.