WTL如何在同一窗口中使用2个自定义绘制CListViewCtr

时间:2014-02-25 15:19:15

标签: c++ wtl

如何将CHAIN_MSG_MAP_MEMBER用于两名成员? 以下示例适用于单个列表视图和单个CHAIN_MSG_MAP_MEMBER. 我两个都崩溃了。

class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>,
        public CMessageFilter, public CIdleHandler
{
public:
    DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)

    virtual BOOL PreTranslateMessage(MSG* pMsg)
    {
        return CFrameWindowImpl<CMainFrame>::PreTranslateMessage(pMsg);
    }

    BEGIN_MSG_MAP(CMainFrame)
        MESSAGE_HANDLER(WM_CREATE, OnCreate)
        COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
        COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
        COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
        CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
        CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
        CHAIN_MSG_MAP_MEMBER(m_listView)            //< 
        CHAIN_MSG_MAP_MEMBER(m_listView2)           //< ISSUE: crash with both, works with one.
    END_MSG_MAP()

    LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
    {
         // create a list box   
        RECT r = {0,0,182,80};    
        m_listView.Create(m_hWnd,r,CListViewCtrl::GetWndClassName(),WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | LVS_REPORT, WS_EX_CLIENTEDGE    );

        RECT r2 = {0,80,182,80+80};    
        m_listView2.Create(m_hWnd,r2,CListViewCtrl::GetWndClassName(),WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | LVS_REPORT, WS_EX_CLIENTEDGE    );

        ...

        populate

    }
} 

class MyListView : public CWindowImpl<MyListView, CListViewCtrl>,
                   public CCustomDraw<MyListView>                   
{
public:

  BEGIN_MSG_MAP(MyListView)    
    CHAIN_MSG_MAP(CCustomDraw<MyListView>)
    END_MSG_MAP()           

    DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
    {       
        ...
    }

    DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
    {
        ...
    }

    DWORD OnSubItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
    {
        ...
    }
    ............
}

1 个答案:

答案 0 :(得分:4)

CCustomDraw是WTL类,并假设您使用BEGIN_MSG_MAP_EX,而不是ATL的BEGIN_MSG_MAP

#include <atlcrack.h>

class MyListView : public CWindowImpl<MyListView, CListViewCtrl>,
                   public CCustomDraw<MyListView>                   
{
public:

BEGIN_MSG_MAP_EX(MyListView) // <<--- Here we go   
    CHAIN_MSG_MAP(CCustomDraw<MyListView>)
END_MSG_MAP()           

};

经验法则是,只要你利用WTL,就永远不要使用BEGIN_MSG_MAP

另外,值得一提的是CHAIN_MSG_MAP_MEMBER的使用对我来说毫无意义。