none
关于相应 CHeaderCtrl::OnChildNotify消息的问题 RRS feed

  • 问题

  • 在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()在两个类里面不同导致的,求原因

    2017年6月13日 11:16

全部回复

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

    2017年6月14日 1:30
  • 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;
    };

    2017年6月14日 1:30
  • 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 Yu


    MSDN Community Support<br/> Please remember to click &quot;Mark as Answer&quot; the responses that resolved your issue, and to click &quot;Unmark as Answer&quot; 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>.

    2017年6月14日 8:33
  • 目前我就是按照你说的这样做的,

    还是有问题的 

    pHeader.GetSafeHwnd()是空,导致的问题,

    网上查阅资料,把子类化写在在CMFCListCtrl的OnCreate响应里面,

    OnCreate里面pHeader.GetSafeHwnd()不为空了,

    调用SubclassWindow但是会有莫名的崩溃

    求解决办法,谢谢

    2017年6月14日 10:08
  • >>网上查阅资料,把子类化写在在CMFCListCtrl的OnCreate响应里面,

    在OnCreate里面pHeader.GetSafeHwnd()不为空了,

    调用SubclassWindow但是会有莫名的崩溃

    该成员函数将Windows控件附加到“CWnd”对象,并替换窗口的** WndProc **和** AfxWndProc **函数。 该函数在“CWnd”对象中存储指向旧的** WndProc **的指针。所以请确保调用SubclassWindow函数时,窗口没有附加到其他MFC对象上。

    你可以在调试模式下,查看Call Stack窗口,看看具体崩溃问题出在哪里。

    或者使用Windbg工具,分析dmp文件。这里有篇文档,你可以参考一下。

    https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/analyzing-a-user-mode-dump-file-with-windbg

    希望对你有所帮助。

    Best Regards,
    Sera Yu


    MSDN Community Support<br/> Please remember to click &quot;Mark as Answer&quot; the responses that resolved your issue, and to click &quot;Unmark as Answer&quot; 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>.

    2017年6月20日 7:43