MFC 基于CListCtrl类的可编辑列表类

最近要用到,自己以网友的思路写了一个很简单但是很使用的MFC拓展类。将代码贴在这里。

头文件中

class CSolidListCtrl:public CListCtrl
{
public:
    CSolidListCtrl()
    {};
    ~CSolidListCtrl()
    {};
    LVHITTESTINFO info;
    CEdit m_edit;
    DECLARE_MESSAGE_MAP()
    afx_msg void OnHdnBegintrack(NMHDR *pNMHDR, LRESULT *pResult);
    afx_msg void OnHdnDividerdblclick(NMHDR *pNMHDR, LRESULT *pResult);
    afx_msg void OnHdnEndtrack(NMHDR *pNMHDR, LRESULT *pResult);
    afx_msg void OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult);
    afx_msg void OnEnKillfocusEdit();
    afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
};

实现部分

BEGIN_MESSAGE_MAP(CSolidListCtrl, CListCtrl)
    ON_NOTIFY(HDN_BEGINTRACKA, 0, &CSolidListCtrl::OnHdnBegintrack)
    ON_NOTIFY(HDN_BEGINTRACKW, 0, &CSolidListCtrl::OnHdnBegintrack)
    ON_NOTIFY(HDN_DIVIDERDBLCLICKA, 0, &CSolidListCtrl::OnHdnDividerdblclick)
    ON_NOTIFY(HDN_DIVIDERDBLCLICKW, 0, &CSolidListCtrl::OnHdnDividerdblclick)
    ON_NOTIFY(HDN_ENDTRACKA, 0, &CSolidListCtrl::OnHdnEndtrack)
    ON_NOTIFY(HDN_ENDTRACKW, 0, &CSolidListCtrl::OnHdnEndtrack)
    ON_NOTIFY_REFLECT(NM_DBLCLK, &CSolidListCtrl::OnNMDblclk)
    ON_EN_KILLFOCUS(101, &CSolidListCtrl::OnEnKillfocusEdit)
    ON_WM_MOUSEWHEEL()
END_MESSAGE_MAP()

//禁止移动列表宽度,如有需要可以改回0
void CSolidListCtrl::OnHdnBegintrack(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
    //*pResult = 0;
    *pResult = -1;
}


void CSolidListCtrl::OnHdnDividerdblclick(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
    //*pResult = 0;
    *pResult = -1;
}


void CSolidListCtrl::OnHdnEndtrack(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);
    //*pResult = 0;
    *pResult = -1;
}

//增加滚轮滚动时取消edit控件
BOOL CSolidListCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    if (m_edit.m_hWnd != NULL)
    {
        this->SetFocus();
    }
    return CListCtrl::OnMouseWheel(nFlags, zDelta, pt);
}

//获取所选单元格并显示一个无边框的Edit控件在上面
void CSolidListCtrl::OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

    info.pt = pNMItemActivate->ptAction;
    if (this->SubItemHitTest(&info) != -1)
    {
        if (info.iSubItem == 0)//不能改变项的名称,只能改变后面的值,如需要这里可以去掉
        {
            return;
        }
        if (m_edit.m_hWnd == NULL) // m_edit为一输入框控件, 
        {
            RECT rt;
            rt.left = 0;
            rt.top = 0;
            rt.bottom = 15;
            rt.right = 200;
            m_edit.Create(WS_CHILD | ES_LEFT| ES_AUTOHSCROLL | ES_WANTRETURN | ES_MULTILINE, rt, this, 101);
            m_edit.SetFont(this->GetFont(), FALSE);
        }
        CRect rect;
        this->GetSubItemRect(info.iItem, info.iSubItem, LVIR_BOUNDS, rect);
        rect.left += 2;
        rect.bottom += -1;
        m_edit.SetWindowText(this->GetItemText(info.iItem, info.iSubItem));
        m_edit.MoveWindow(&rect, TRUE);
        m_edit.ShowWindow(SW_SHOW);
        m_edit.SetFocus();
    }
    *pResult = 0;
}

//当Edit控件失焦时把Edit里的文本填入单元格中
void CSolidListCtrl::OnEnKillfocusEdit()
{
    CString str;
    m_edit.GetWindowText(str);
    this->SetItemText(info.iItem,info.iSubItem,str);
    m_edit.ShowWindow(SW_HIDE);
}

如果在对话框中使用,只要拖入listctrl控件,view属性设为报表类型,添加变量,在对话框头文件中将变量类型从CListCtrl改为CSolidListCtrl类就行了。

猜你喜欢

转载自blog.csdn.net/sssaaaannnddd/article/details/78861914
今日推荐