最近要用到,自己以网友的思路写了一个很简单但是很使用的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类就行了。