【问题标题】:WTL how to use 2 custom-draw CListViewCtr in the same windowWTL如何在同一个窗口中使用2个自定义绘制CListViewCtr
【发布时间】:2014-03-27 22:19:38
【问题描述】:

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)
    {
        ...
    }
    ............
}

【问题讨论】:

    标签: c++ wtl


    【解决方案1】:

    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 的这种用法对我来说毫无意义。

    【讨论】:

    • 你在正确的地方,CHAIN_MSG_MAP_MEMBER 是错误的路径......谢谢。
    猜你喜欢
    • 1970-01-01
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    相关资源
    最近更新 更多