小弟现在正使用了一个从 CListView 继承的类 CXXXView,经常用的函数是 GetListCtrl 来得到视图的 CListCtrl 类对象,现在发现 CListCtrl 功能函数太少,想用一个 CListCtrlEx(包括设置单元格字体和背景色的功能) 替抽换,即用 GetListCtrl 时得到的是 CListCtrlEx 对象,追踪MFC的 CListView 发现 
AFXCVIEW_INLINE CListCtrl& CListView::GetListCtrl() const
{ return *(CListCtrl*)this; }
无奈,现不知怎么实现我想要的功能,请各位XDJM帮帮忙!!!
在线等,谢谢!

解决方案 »

  1.   

    追踪MFC的 CListView 发现
    AFXCVIEW_INLINE CListCtrl& CListView::GetListCtrl() const
    { return *(CListCtrl*)this; }???
      

  2.   

    CWnd::SubclassDlgItem
    AFXCVIEW_INLINE CListCtrl& CListView::GetListCtrl() const
    { return *(CListCtrl*)this; }
    在MFC的源代码中确实如此,看一下MFC的源代码就明白了。
      

  3.   

    XCVIEW_INLINE CListCtrlEx& CMyListView::GetListCtrl() const
    { return *(CListCtrlEx*)this; }
    这样不就得了
      

  4.   

    自己从 CView 继承一个类 CXXXView,再在这个类里加一个 CListCtrlEx不就行了
      

  5.   

    兄弟能否发给我一份1。56版无 行数限制的的 locwise到我得 信箱里 ?谢谢了[email protected]
      

  6.   

    问:我看到CListView的成员函数GetListCtrl直接把CListView本身的指针转换为CListCtrl指针。我想知道在什么情况下可以安全地把一个类的指针转化为另一个类的指针?问:我重载了CListCtrl以自定义列表控件,我如何把我的代码移植到CListView?答:关于类型转换的合法性只要你访问的数据的内存表示是完全相同的,那么这种转化就是安全的。考虑MFC从CWnd到CEdit的派生过程,是一个纯粹的封装——既没有增加数据成员也没有增加虚函数(虚函数表的指针实际上是类的第一个成员,你可以在VC的监视窗口看到)——所有的代码只是在操作基类的成员。所以你可以在对话框的成员函数中安全地进行如下调用 CEdit* pEdit=GetDlgItem (IDC_EDIT);
    也就是说,你可以安全地把CWnd指针转化为CEdit指针。在CWnd的窗口类为EDIT的情况下,你可以安全地用这个CEdit指针来访问CEdit具有的而CWnd不具有的特性。由于CEditView的窗口类也是EDIT,同时是从CWnd派生下来的,所以你也可以把CEditView指针转化成CEdit指针。MFC的CCtrlView的派生类都可以做这样的转化。 在这样做之前,你需要查看类的定义头文件以确保类型安全。CEdit, CListCtrl, CTreeCtrl,CToolBarCtrl都是这样的封装,但是CToolTipCtrl是一个例外。除了对TTM_ADDTOOL消息的处理可能不一致之外。 LRESULT CToolTipCtrl::OnAddTool(WPARAM wParam, LPARAM lParam)
    {
    TOOLINFO ti = *(LPTOOLINFO)lParam;
    if ((ti.hinst == NULL) && (ti.lpszText != LPSTR_TEXTCALLBACK)
    && (ti.lpszText != NULL))
    {
    void* pv;
    if (!m_mapString.Lookup(ti.lpszText, pv))
    m_mapString.SetAt(ti.lpszText, NULL);
    // set lpszText to point to the permanent memory associated
    // with the CString
    VERIFY(m_mapString.LookupKey(ti.lpszText, ti.lpszText));
    }
    return DefWindowProc(TTM_ADDTOOL, wParam, (LPARAM)&ti);
    }
    这里访问了CToolTipCtrl的数据成员,这样的话下面的代码看起来就似乎未必安全 _AFXCMN_INLINE CToolTipCtrl* CTreeCtrl::GetToolTips() const
    { ASSERT(::IsWindow(m_hWnd)); return (CToolTipCtrl*)CWnd::FromHandle((HWND)::SendMessage(m_hWnd, TVM_GETTOOLTIPS, 0, 0L)); }
    不过CTreeCtrl::GetToolTips()返回的只是有效的CWnd,TVM_ADDTOOL消息也是被默认窗口过程而不是CToolTipCtrl的代码来处理, 所以上面的用法还是安全的。 顺便说一下,尽管大部分这样的封装是用SendMessage实现的,但是Redmond的家伙似乎很热衷于用DefWindowProc替代SendMessage来节省CPU的时钟周期。这样的一个副作用是MFC不会有处理这样的消息的机会,例如PretranslateMessage和Subclass都会失效了。强制转换的一个副作用是protected修饰符不再是类成员的保护伞。考虑如下情况
    Class A
    {
        protected: int m_iProtected;
    };
        如果我想获得m_iProtected的public访问权,我可以写一个封装类
    Class B:public A
    {
        public:int & GetProtected(){return m_iProtected;}
        friend class C;
    };
    然后把A类型的指针强制转化成B类型的就可以以public方式访问声明为m_iProtected的成员了。在C类中访问B的成员也不受限制。 尽管多继承是C++的一个特性,从理想情况来说,CEditView应该从CCtrlView和CEdit派生出来,但是所有的人都知道多继承是多么的麻烦。对于MFC的CObject派生类,默认的情况是不允许的——尽管你可以通过的MFC技术文档TN016: Using C++ Multiple Inheritance with MFC中提供的方法手动添加多继承支持。实际上,这些特性应该以接口的形式提供——把GetEditCtrl转换成QueryInterface,但是性能上又会损失很多,而且Windows通用控件和MFC对它的封装总是在不断地升级,所以MFC使用了如上的”黑客”方法来提供和多继承类似的功能。 强制类型转换不适合内存表示不同的场合,所以只有你确定指定地址的内存布局和string相同的时候才可以访问。类的内存表示包含虚函数表和成员列表两部分。 通常,只有派生类和基类的类型不同而和基类的内存表示相同,所以派生类指针可以安全地转化为基类指针。一些不安全的类型转换也可能是可行的,只要访问的部分成员内存布局一致并且独立于其它成员就可以了。 一些字符串操作封装类内部维护一个引用计数来避免内存的频繁复制。如果对标准字符串的内存复制成为了程序的瓶颈,那么可以使用这样的类来提高性能关于移植方案如果你的CListCtrl扩展类没有增加成员变量或者虚函数(这似乎是一种缚手缚脚的扩展),那么你可以直接把任何窗口类类型为SysListView32的CWnd对象指针直接转化为你的CListCtrl扩展类指针使用。如果你的CListCtrl扩展类在CListCtrl的基础上增加了成员变量或者虚函数,那么推荐用基于CFormView(或者更麻烦一些,CCtrlView)的类来替代基于CListView的实现:在FormView的对话框上放一个列表控件,在FormView大小变化时移动列表控件以充满视图。如果你希望让视图类而不是视图中的控件来处理和响应消息,你需要捕捉控件收到的用户输入消息并通过发送WM_NOTIFY通知转发到视图,以及捕捉视图收到的控制消息并转发到控件。使用这种方法也可以自行封装基于CCtrlView的自定义控件视图类。如果你的CListCtrl扩展类不依赖于控件的状态——也就是说,由调用者手动初始化而不是自行处理创建消息,那么可以声明一个CListCtrl扩展类对象,之后调用CWnd::Attatch连接到CListView派生类对象来接管窗口过程。其它的通用控件扩展类也可以使用上述方法移植到CCtrlView派生类。