原文地址: 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的成员函数来实现需要的功能了!