子类化CTreeView中的CTreeCtrl控件

原文地址: http://blog.chinaunix.net/uid-8193682-id-2513440.html

作者: David Howe


因实际需要,要子类化一个已经编写好的CTreeView中的CTreeCtrl,以实现特定的功能。。。
 
确切的说,我需要的功能是:在对这个CTreeView进行节点的增加、删除、修改时,要做一些额外的工作,举个最简单的例子:写日志记录。------当然,可以在所有进行上述操作的地方去添加写日志的功能,但如果牵扯的地方很多,不愿一一进行修改的话,子类化确实是一个最顺理成章的想法!
 
上网搜了一下,发现有不少人提出这样的问题,不过怎么就没找到谁把具体方法写出来!?(也没怎么认真去搜),于是,只有自己研究了,然后写一篇文,以后谁再有此问题就可以搜的到了。为此专门起了个容易被搜到的贴切标题。^^
 
下面是实现的核心代码:
 
----------------------------------MyTreeView.h----------------------------------
 

CNewTreeCtrl m_wndNewTreeCtrl; // 新的CTreeCtrl对象,将用它来子类化CMyTreeView中的CTreeCtrl控件。
BOOL m_bSubclassed; 
// 是否已经被我们子类化过的标志,初始化为FALSE

// 需要重载这个函数,确保在子类化前后调用它,都会返回正确的结果
CTreeCtrl& GetTreeCtrl() const
{
    if (m_bSubclassed) return (CTreeCtrl&)m_wndNewTreeCtrl; 
// 若子类化了,返回新的引用
    else return CTreeView::GetTreeCtrl(); 
// 若未子类化,调用默认处理
}

 
----------------------------------MyTreeView.cpp----------------------------------
 

void CMyTreeView::OnInitialUpdate()
{
    CMyTreeView::OnInitialUpdate();

    //
    
// 进行子类化的代码
    
//
    CTreeCtrl& tree = GetTreeCtrl(); 
// 得到CTreeCtrl对象的引用
    HWND hwndTreeCtrl = tree.m_hWnd; 
// 记录下它的句柄,下面马上会用到
    tree.UnsubclassWindow(); 
// 因为这个窗口已经是子类化过的(用Spy++可以看出来),要先进行UnsubclassWindow
    m_wndNewTreeCtrl.SubclassWindow(hwndTreeCtrl); 
// 现在实现我的子类化
    m_bSubclassed = TRUE; 
// 设置标志

    
// 下面这句很重要,否则很多API调用会认为CMyTreeView内部的控件窗口句柄无效
    m_hWnd = m_wndNewTreeCtrl.m_hWnd; 
// 修正CMyTreeView的m_hWnd成员变量
}

OK,现在可以通过在CNewTreeCtrl类中重载一些CTreeCtrl的成员函数来实现需要的功能了!


你可能感兴趣的:(MFC)