询问者
关于相应 CHeaderCtrl::OnChildNotify消息的问题

问题
-
在CListCtrl下是可以相应到该消息
但是在CMFCListCtrl下不能相应该消息
CListCtrl代码如下
void CMyListCtrl::PreSubclassWindow()
{
ModifyStyle(0, LVS_OWNERDRAWFIXED);
CListCtrl::PreSubclassWindow();
ModifyStyle(0, LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS);
CHeaderCtrlEx *pHeader = (CHeaderCtrlEx*)this->GetHeaderCtrl();
m_ctrlHeader.SubclassWindow(pHeader->GetSafeHwnd());
}是完全没有问题的
但是在CMFCListCtrl这个下就有问题
代码如下
void CMyListCtrl::PreSubclassWindow()
{
ModifyStyle(0, LVS_OWNERDRAWFIXED);
CMFCListCtrl::PreSubclassWindow();
ModifyStyle(0, LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS);
CHeaderCtrlEx &pHeader = (CHeaderCtrlEx&)this->GetHeaderCtrl();
m_ctrlHeader.SubclassWindow(pHeader.GetSafeHwnd());
}不知道什么原因,个人怀疑是GetSafeHwnd()在两个类里面不同导致的,求原因
全部回复
-
IMPLEMENT_DYNAMIC(CHeaderCtrlEx, CMFCHeaderCtrl) CHeaderCtrlEx::CHeaderCtrlEx() { m_bLocked = FALSE; } CHeaderCtrlEx::~CHeaderCtrlEx() { } BEGIN_MESSAGE_MAP(CHeaderCtrlEx, CMFCHeaderCtrl) END_MESSAGE_MAP() BOOL CHeaderCtrlEx::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult) { // TODO: 在此添加专用代码和/或调用基类 HD_NOTIFY *phdn = (HD_NOTIFY*)lParam; NMHDR& nmh = *(NMHDR*)lParam; if (nmh.code == HDN_BEGINTRACKA || nmh.code == HDN_BEGINTRACKW || nmh.code == HDN_DIVIDERDBLCLICKA || nmh.code == HDN_DIVIDERDBLCLICKW) { CRect Rect; GetItemRect(phdn->iItem , Rect); if (Rect.Width() == 0) { return *pLResult = TRUE; } } return CMFCHeaderCtrl::OnChildNotify(message, wParam, lParam, pLResult); } IMPLEMENT_DYNAMIC(CMyListCtrl, CMFCListCtrl) CMyListCtrl::CMyListCtrl() { } CMyListCtrl::~CMyListCtrl() { } BEGIN_MESSAGE_MAP(CMyListCtrl, CMFCListCtrl) END_MESSAGE_MAP() void CMyListCtrl::PreSubclassWindow() { ModifyStyle(0, LVS_OWNERDRAWFIXED); CMFCListCtrl::PreSubclassWindow(); ModifyStyle(0, LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS); CHeaderCtrlEx &pHeader = (CHeaderCtrlEx&)this->GetHeaderCtrl(); m_ctrlHeader.SubclassWindow(pHeader.GetSafeHwnd()); } void CMyListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { }
-
class CHeaderCtrlEx : public CMFCHeaderCtrl { DECLARE_DYNAMIC(CHeaderCtrlEx) public: CHeaderCtrlEx(); virtual ~CHeaderCtrlEx(); protected: DECLARE_MESSAGE_MAP() public: virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult); BOOL m_bLocked; }; class CMyListCtrl : public CMFCListCtrl { DECLARE_DYNAMIC(CMyListCtrl) public: CMyListCtrl(); virtual ~CMyListCtrl(); protected: DECLARE_MESSAGE_MAP() virtual void PreSubclassWindow(); virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); public: CHeaderCtrlEx m_ctrlHeader; };
-
Hi Hota_CT,
感谢在MSDN论坛发帖。
>>不知道什么原因,个人怀疑是GetSafeHwnd()在两个类里面不同导致的,求原因
CListCtrl::GetHeaderCtrl返回的是CHeaderCtrl类型的指针。
CHeaderCtrl* GetHeaderCtrl();
而CMFCListCtrl::GetHeaderCtrl返回的是CMFCHeaderCtrl类型的引用。
virtual CMFCHeaderCtrl& GetHeaderCtrl();
建议你改为以下代码。
CMFCHeaderCtrl &pHeader = (CMFCHeaderCtrl&)this->GetHeaderCtrl(); m_ctrlHeader.SubclassWindow(pHeader.GetSafeHwnd());
希望对你有所帮助。
Best Regards,
Sera YuMSDN Community Support<br/> Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact <a href="mailto:MSDNFSF@microsoft.com">MSDNFSF@microsoft.com</a>.
-
>>网上查阅资料,把子类化写在在CMFCListCtrl的OnCreate响应里面,
在OnCreate里面pHeader.GetSafeHwnd()不为空了,调用SubclassWindow但是会有莫名的崩溃
该成员函数将Windows控件附加到“CWnd”对象,并替换窗口的** WndProc **和** AfxWndProc **函数。 该函数在“CWnd”对象中存储指向旧的** WndProc **的指针。所以请确保调用SubclassWindow函数时,窗口没有附加到其他MFC对象上。
你可以在调试模式下,查看Call Stack窗口,看看具体崩溃问题出在哪里。
或者使用Windbg工具,分析dmp文件。这里有篇文档,你可以参考一下。
希望对你有所帮助。
Best Regards,
Sera YuMSDN Community Support<br/> Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact <a href="mailto:MSDNFSF@microsoft.com">MSDNFSF@microsoft.com</a>.