如何在listcontrol上实现直接修改数据值?(类似于datagrid) 我利用listcontrol只能简单的用于显示数据如果想修改数据还要通过其他手段,而不能像在datagrid控件上一样通过点击某一字段然后进行修改。这样实在是麻烦。求教! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 Drag and Drop between and within a CListCtrlBy David Fleming An article showing how to drag and drop items between CListCtrls or reorder items within a CListCtrl http://www.codeproject.com/listctrl/dragtest.asp sorryEditable subitemshttp://www.codeguru.com/listview/edit_subitems.shtml Easy Navigation Through an Editable List View http://www.codeguru.com/listview/ListEditor1.shtml // ClientView.h : interface of the CClientView class///////////////////////////////////////////////////////////////////////////////#if !defined(AFX_CLIENTVIEW_H__BC1F0C70_61FC_4836_965C_FFE877A71E14__INCLUDED_)#define AFX_CLIENTVIEW_H__BC1F0C70_61FC_4836_965C_FFE877A71E14__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include "ListEdit.h"class CClientDoc;class CClientView : public CListView{protected: // create from serialization only CClientView(); DECLARE_DYNCREATE(CClientView)// Attributespublic: CClientDoc* GetDocument(); CEdit* EditSubLabel(int nItem,int nCol); //编辑第nItem,nCol列 int HitTestEx(CPoint &point,int *nCol); //计算鼠标点击的是那个列表项// Operationspublic: CStringArray m_arrColTypeName; CDWordArray m_arrColDataType; BOOL m_bSetColumnWidth; BOOL m_bViewInit; BOOL m_bEditing; //用于标记是否处于编辑状态 CListEdit* m_pEdit; //自定义的编辑控件 CListCtrl* m_pListCtrl; CString m_strOldText; //纪录listCtrl视图中正在编辑项的文本 BOOL m_bChanged; //文本是否更改 CUIntArray m_arrChangedLine; // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CClientView) public: virtual void OnDraw(CDC* pDC); // overridden to draw this view virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: virtual void OnInitialUpdate(); // called first time after construct virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult); //}}AFX_VIRTUAL// Implementationpublic: virtual ~CClientView();#ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const;#endifprotected:// Generated message map functionsprotected: //{{AFX_MSG(CClientView) afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult); afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult); //}}AFX_MSG DECLARE_MESSAGE_MAP()};#ifndef _DEBUG // debug version in ClientView.cppinline CClientDoc* CClientView::GetDocument() { return (CClientDoc*)m_pDocument; }#endif///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_CLIENTVIEW_H__BC1F0C70_61FC_4836_965C_FFE877A71E14__INCLUDED_) IMPLEMENT_DYNCREATE(CClientView, CListView)BEGIN_MESSAGE_MAP(CClientView, CListView) //{{AFX_MSG_MAP(CClientView) ON_WM_HSCROLL() ON_WM_VSCROLL() ON_WM_LBUTTONDOWN() ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit) ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw) //}}AFX_MSG_MAP // Standard printing commands //ON_NOTIFY (NM_CUSTOMDRAW,m_pListCtrl->, OnCustomdrawMyList ) ON_COMMAND(ID_FILE_PRINT, CListView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, CListView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, CListView::OnFilePrintPreview)END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CClientView construction/destructionCClientView::CClientView(){ // TODO: add construction code here m_bChanged=FALSE;}CClientView::~CClientView(){}BOOL CClientView::PreCreateWindow(CREATESTRUCT& cs){ // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.style |= LVS_REPORT|LVS_EDITLABELS| LVS_NOSORTHEADER; return CListView::PreCreateWindow(cs);}/////////////////////////////////////////////////////////////////////////////// CClientView drawingvoid CClientView::OnDraw(CDC* pDC){ CClientDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here}void CClientView::OnInitialUpdate(){ CListView::OnInitialUpdate();// CWnd* pWnd = ((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_wndSplitter.GetPane(0, 1);// LeftView = DYNAMIC_DOWNCAST(CLeftView, pWnd); m_pListCtrl=&GetListCtrl(); m_pListCtrl->SetExtendedStyle(m_pListCtrl->GetExtendedStyle()|LVS_EX_FLATSB|LVS_EX_SUBITEMIMAGES|LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT); // its list control through a call to GetListCtrl().}/////////////////////////////////////////////////////////////////////////////// CClientView printingBOOL CClientView::OnPreparePrinting(CPrintInfo* pInfo){ // default preparation return DoPreparePrinting(pInfo);}void CClientView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){ // TODO: add extra initialization before printing}void CClientView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/){ // TODO: add cleanup after printing}/////////////////////////////////////////////////////////////////////////////// CClientView diagnostics#ifdef _DEBUGvoid CClientView::AssertValid() const{ CListView::AssertValid();}void CClientView::Dump(CDumpContext& dc) const{ CListView::Dump(dc);}CClientDoc* CClientView::GetDocument() // non-debug version is inline{ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CClientDoc))); return (CClientDoc*)m_pDocument;}#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////// CClientView message handlersBOOL CClientView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { //如果在编辑状态下,则不允许用户托动列表视图的表头改变列宽 if(m_bEditing) { switch(((NMHDR*)lParam)->code) { case HDN_BEGINTRACKW: case HDN_BEGINTRACKA: *pResult=TRUE; //disable tracking return TRUE; } } return CListView::OnNotify(wParam, lParam, pResult);}/*=============================================================函数功能: 根据point的值(鼠标当前的坐标),判断point所在列表框行和列 返回行和列返回值: 返回行数,由nCol放回列数历史纪录: 2002/12/23/andy==============================================================*/int CClientView::HitTestEx(CPoint &point,int *nCol){ CListCtrl& ctlList=(CListCtrl&)GetListCtrl();//得到当前的控件 int nColumn=0; int nRow=ctlList.HitTest(point,NULL); if(nCol) *nCol=0; //确保列表视图是LVS_REPORT属性的 if((GetWindowLong(ctlList.m_hWnd,GWL_STYLE)&LVS_TYPEMASK)!=LVS_REPORT) return nRow; //获取当前视图中可以看见的项目的行数 nRow=ctlList.GetTopIndex(); int nBottom=nRow+ctlList.GetCountPerPage(); if(nBottom>ctlList.GetItemCount()) nBottom=ctlList.GetItemCount(); //获取列表视图中的列数 CHeaderCtrl* pHeader=(CHeaderCtrl*)ctlList.GetDlgItem(0); int nColumnCount=pHeader->GetItemCount(); //按行循环,确定鼠标点击的是那个列表框 for(;nRow<=nBottom;nRow++) { //确定鼠标光标点击的是那一行 CRect rtItem; ctlList.GetItemRect(nRow,&rtItem,LVIR_BOUNDS); if(rtItem.PtInRect(point)) { //确定鼠标光标点击的是那一列 for(nColumn=0;nColumn<=nColumnCount;nColumn++) { int nColWidth=ctlList.GetColumnWidth(nColumn); if(point.x>=rtItem.left&&point.x<=(rtItem.left+nColWidth)) { if(nCol) *nCol=nColumn; //CString str return nRow; } rtItem.left+=nColWidth; } } } //如果光标点击的不是任何一个列表项,则返回-1 if(nCol) *nCol=-1; return -1;}/*======================================================= 在工作线程中SendMessage直接有时候会直接返回,没进到消息函数中 求C#2008重复执行的代码 MSHFG怎样支持滚轮?? 关于重载的一个问题,请各位高手指教 看这个函数VIEW 求救~~~~~~~~~~(有难度) ※※※※※※※ 找旺正正唱的那首奥运歌曲《永恒依然》※※※※※※ 哪有SoftIce下载 VC如何做一个带有文档/视图的ActiveX控件?有思路就有分 三百分求购,请问有没有在VC下使用的数据库类库(详情请进) 今天看了下ATL所谓的“连接点”ConnectionPoint 如何注册COM组件程序?
By David Fleming An article showing how to drag and drop items between CListCtrls or reorder items within a CListCtrl http://www.codeproject.com/listctrl/dragtest.asp
http://www.codeguru.com/listview/edit_subitems.shtml
http://www.codeguru.com/listview/ListEditor1.shtml
//
/////////////////////////////////////////////////////////////////////////////#if !defined(AFX_CLIENTVIEW_H__BC1F0C70_61FC_4836_965C_FFE877A71E14__INCLUDED_)
#define AFX_CLIENTVIEW_H__BC1F0C70_61FC_4836_965C_FFE877A71E14__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "ListEdit.h"
class CClientDoc;
class CClientView : public CListView
{
protected: // create from serialization only
CClientView();
DECLARE_DYNCREATE(CClientView)// Attributes
public:
CClientDoc* GetDocument();
CEdit* EditSubLabel(int nItem,int nCol); //编辑第nItem,nCol列
int HitTestEx(CPoint &point,int *nCol); //计算鼠标点击的是那个列表项// Operations
public:
CStringArray m_arrColTypeName;
CDWordArray m_arrColDataType; BOOL m_bSetColumnWidth;
BOOL m_bViewInit;
BOOL m_bEditing; //用于标记是否处于编辑状态
CListEdit* m_pEdit; //自定义的编辑控件
CListCtrl* m_pListCtrl;
CString m_strOldText; //纪录listCtrl视图中正在编辑项的文本
BOOL m_bChanged; //文本是否更改
CUIntArray m_arrChangedLine;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CClientView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void OnInitialUpdate(); // called first time after construct
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
//}}AFX_VIRTUAL// Implementation
public:
virtual ~CClientView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endifprotected:// Generated message map functions
protected:
//{{AFX_MSG(CClientView)
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};#ifndef _DEBUG // debug version in ClientView.cpp
inline CClientDoc* CClientView::GetDocument()
{ return (CClientDoc*)m_pDocument; }
#endif///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_CLIENTVIEW_H__BC1F0C70_61FC_4836_965C_FFE877A71E14__INCLUDED_)
IMPLEMENT_DYNCREATE(CClientView, CListView)BEGIN_MESSAGE_MAP(CClientView, CListView)
//{{AFX_MSG_MAP(CClientView)
ON_WM_HSCROLL()
ON_WM_VSCROLL()
ON_WM_LBUTTONDOWN()
ON_NOTIFY_REFLECT(LVN_ENDLABELEDIT, OnEndlabeledit)
ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)
//}}AFX_MSG_MAP
// Standard printing commands
//ON_NOTIFY (NM_CUSTOMDRAW,m_pListCtrl->, OnCustomdrawMyList )
ON_COMMAND(ID_FILE_PRINT, CListView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CListView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CListView::OnFilePrintPreview)
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CClientView construction/destructionCClientView::CClientView()
{
// TODO: add construction code here
m_bChanged=FALSE;
}CClientView::~CClientView()
{
}BOOL CClientView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style |= LVS_REPORT|LVS_EDITLABELS| LVS_NOSORTHEADER;
return CListView::PreCreateWindow(cs);
}/////////////////////////////////////////////////////////////////////////////
// CClientView drawingvoid CClientView::OnDraw(CDC* pDC)
{
CClientDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}void CClientView::OnInitialUpdate()
{
CListView::OnInitialUpdate();// CWnd* pWnd = ((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_wndSplitter.GetPane(0, 1);
// LeftView = DYNAMIC_DOWNCAST(CLeftView, pWnd); m_pListCtrl=&GetListCtrl();
m_pListCtrl->SetExtendedStyle(m_pListCtrl->GetExtendedStyle()|LVS_EX_FLATSB|LVS_EX_SUBITEMIMAGES|LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT); // its list control through a call to GetListCtrl().
}/////////////////////////////////////////////////////////////////////////////
// CClientView printingBOOL CClientView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}void CClientView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}void CClientView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}/////////////////////////////////////////////////////////////////////////////
// CClientView diagnostics#ifdef _DEBUG
void CClientView::AssertValid() const
{
CListView::AssertValid();
}void CClientView::Dump(CDumpContext& dc) const
{
CListView::Dump(dc);
}CClientDoc* CClientView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CClientDoc)));
return (CClientDoc*)m_pDocument;
}
#endif //_DEBUG/////////////////////////////////////////////////////////////////////////////
// CClientView message handlers
BOOL CClientView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
//如果在编辑状态下,则不允许用户托动列表视图的表头改变列宽
if(m_bEditing)
{
switch(((NMHDR*)lParam)->code)
{
case HDN_BEGINTRACKW:
case HDN_BEGINTRACKA:
*pResult=TRUE; //disable tracking
return TRUE;
}
}
return CListView::OnNotify(wParam, lParam, pResult);
}/*=============================================================
函数功能:
根据point的值(鼠标当前的坐标),判断point所在列表框行和列
返回行和列
返回值:
返回行数,由nCol放回列数
历史纪录:
2002/12/23/andy
==============================================================*/
int CClientView::HitTestEx(CPoint &point,int *nCol)
{
CListCtrl& ctlList=(CListCtrl&)GetListCtrl();//得到当前的控件
int nColumn=0;
int nRow=ctlList.HitTest(point,NULL);
if(nCol) *nCol=0;
//确保列表视图是LVS_REPORT属性的
if((GetWindowLong(ctlList.m_hWnd,GWL_STYLE)&LVS_TYPEMASK)!=LVS_REPORT)
return nRow;
//获取当前视图中可以看见的项目的行数
nRow=ctlList.GetTopIndex();
int nBottom=nRow+ctlList.GetCountPerPage();
if(nBottom>ctlList.GetItemCount())
nBottom=ctlList.GetItemCount();
//获取列表视图中的列数
CHeaderCtrl* pHeader=(CHeaderCtrl*)ctlList.GetDlgItem(0);
int nColumnCount=pHeader->GetItemCount();
//按行循环,确定鼠标点击的是那个列表框
for(;nRow<=nBottom;nRow++)
{
//确定鼠标光标点击的是那一行
CRect rtItem;
ctlList.GetItemRect(nRow,&rtItem,LVIR_BOUNDS);
if(rtItem.PtInRect(point))
{
//确定鼠标光标点击的是那一列
for(nColumn=0;nColumn<=nColumnCount;nColumn++)
{
int nColWidth=ctlList.GetColumnWidth(nColumn);
if(point.x>=rtItem.left&&point.x<=(rtItem.left+nColWidth))
{
if(nCol) *nCol=nColumn;
//CString str
return nRow;
}
rtItem.left+=nColWidth;
}
}
}
//如果光标点击的不是任何一个列表项,则返回-1
if(nCol) *nCol=-1;
return -1;
}/*=======================================================