http://vcer.net/1047290896039.html
// 初始化
CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST_XXX);
pList->ModifyStyle(0, LVS_REPORT| LVS_SHOWSELALWAYS | LVS_SINGLESEL); //
pList->SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES | LVS_EX_HEADERDRAGDROP);
pList->InsertColumn(0, _T(" "), LVCFMT_LEFT, 30);
pList->InsertColumn(1, _T("XXXX"), LVCFMT_LEFT, 100);
pList->InsertColumn(2, _T("XXXXX"), LVCFMT_LEFT, 100);
// 选中某一行
pList->SetItemState(n, LVIS_SELECTED, LVIS_SELECTED);
// 获得选中行
CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST_XXX);
POSITION pos = pList->GetFirstSelectedItemPosition();
if(pos == NULL)
{
return;
}
int nItem = pList->GetNextSelectedItem(pos);
pList->DeleteItem(nItem);
双击响应函数里的参数有一个是NM_LISTVIEW *
msdn查NMLISTVIEW(把中间那个_去掉)能看到这个结构中有一个成员变量是iItem
0表示第一行,表示第二行;还有一个iSubItem表示列,表示双击在第一列
CListCtrl大小图标转换
先要添加控制按纽(大图标,小图标,列表,详细)
void OnBig()
{
LONG lStyle;
lStyle = GetWindowLong(m_ListCtrl.m_hWnd,GWL_STYLE);//获取当前窗口句并
lStyle&=~ LVS_TYPEMASK;//清除显示方式所在的比特为
lStyle |= LVS_ICON;//设置显示方式
SetWindowLong(m_listCtrl.m_hWnd, GWL_STYLE,lStyle);//设置窗口类型
}
在另外的三个消息处理函数中只需把这里的LVS_ICON改为LVS_SMALLICON,
LVS_LIST(列表),LVS_REPORT(详细)即可。
以下代码演示如何获得所选项行数
// This code prints out the indices of selected items to debug win
int i = GetNextItem( -1, LVNI_ALL | LVNI_SELECTED);
while( i != -1 )
{
TRACE("%d/n", i );
i = GetNextItem( i, LVNI_ALL | LVNI_SELECTED);
}
以下代码演示如何获得所选项列数
// HitTestEx - Determine the row index and column index for a point
// Returns - the row index or -1 if point is not over a row
// point - point to be tested.
// col - to hold the column index
int CMyListCtrl::HitTestEx(CPoint &point,int *col) const
{
int colnum = 0;
int row = HitTest( point, NULL );
if( col ) *col = 0;
// Make sure that the ListView is in LVS_REPORT
if( (GetWindowLong(m_hWnd, GWL_STYLE) & LVS_TYPEMASK) != LVS_REPORT )
return row;
// Get the top and bottom row visible
row = GetTopIndex();
int bottom = row + GetCountPerPage();
if( bottom > GetItemCount() )
bottom = GetItemCount();
// Get the number of columns
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
int nColumnCount = pHeader->GetItemCount();
// Loop through the visible rows
for( ;row <=bottom;row++)
{
// Get bounding rect of item and check whether point falls in it
CRect rect;
GetItemRect( row, &rect, LVIR_BOUNDS );
if( rect.PtInRect(point) )
{
// Now find the column
for( colnum = 0; colnum < nColumnCount; colnum++ )
{
int colwidth = GetColumnWidth(colnum);
if( point.x >= rect.left
&& point.x <= (rect.left + colwidth ) )
{
if( col ) *col = colnum;
return row;
}
rect.left += colwidth;
}
}
}
return -1;
}
用GetItemText获取相应项的内容。
返回选中的行
// This code prints out the indices of selected items to debug win
int i = GetNextItem( -1, LVNI_ALL | LVNI_SELECTED);
while( i != -1 )
{
TRACE("%d/n", i );
i = GetNextItem( i, LVNI_ALL | LVNI_SELECTED);
}
void CHisView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
SetWindowText("检测历史");
CListCtrl& ctrl=GetListCtrl();
DWORD dwStyle=GetWindowLong(ctrl.GetSafeHwnd(),GWL_STYLE);
if((dwStyle&LVS_TYPEMASK)!=LVS_REPORT)
SetWindowLong(ctrl.GetSafeHwnd(),GWL_STYLE,(dwStyle&~LVS_TYPEMAS
K)|LVS_REPORT);
ctrl.InsertColumn(0,"序 号",LVCFMT_LEFT,100,0);
ctrl.InsertColumn(1,"",LVCFMT_LEFT,100,1);
ctrl.InsertColumn(2",LVCFMT_RIGHT,100,2);
ctrl.InsertColumn(3,"",LVCFMT_RIGHT,100,3);
ctrl.InsertColumn(4,"",LVCFMT_RIGHT,100,4);
ctrl.InsertColumn(5,"",LVCFMT_RIGHT,100,5);
ctrl.InsertColumn(6,"检测次数",LVCFMT_RIGHT,100,6);
//打开数据库,并加入数据
CDiagApp* app=(CDiagApp*)AfxGetApp();
/* CResView disp;
if(disp.bFilter>0)
{
m_pSet->m_strFilter=app->xh;
}
*/
CDatabase* pdb;
pdb=new CDatabase;
pdb->Open(_T("diag"),FALSE,FALSE);
CDiagSet* m_pSet=new CDiagSet(pdb);
if(m_pSet->IsOpen())
m_pSet->Close();
bop=m_pSet->Open();
if(bop)
TRACE("OPENED OK/n");
else
TRACE("not open/n");
m_pSet->MoveFirst();
int index=0;
int iIndex=0;
while(!m_pSet->IsEOF())
// int nCount=m_pSet->GetRecordCount();
// for (int i=0;i<nCount;i++)
{
LV_ITEM item;
memset(&item,0,sizeof(item));
CListCtrl& ctrl=GetListCtrl();
CString str;
dl=m_pSet->m_DIANLIU;
dy=m_pSet->m_DIANYA;
gl=m_pSet->m_GONGLV;
zc=m_pSet->m_ZHUANGCHA;
name=m_pSet->m_NAME;
iIndex++;
str.Format("%d",iIndex);
index=ctrl.InsertItem(iIndex,str);
str.Format(name);
ctrl.SetItemText(index,1,str);
str.Format("%d",dy);
ctrl.SetItemText(index,2,str);
str.Format("%d",dl);
ctrl.SetItemText(index,3,str);
str.Format("%d",gl);
ctrl.SetItemText(index,4,str);
str.Format("%d",zc);
ctrl.SetItemText(index,5,str);
m_pSet->MoveNext();
}
}
如何确定item是否被check
How to get notification when an item is checked / unchecked:
void DemoDlg::OnItemchangedLinksList(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
*pResult = 0;
if (pNMListView->uOldState == 0 && pNMListView->uNewState == 0)
return;// No change
BOOL bPrevState = (BOOL)(((pNMListView->uOldState &
LVIS_STATEIMAGEMASK)>>12)-1); // Old check box state
if (bPrevState < 0)// On startup there's no previous state
bPrevState = 0;// so assign as false (unchecked)
// New check box state
BOOL bChecked=(BOOL)(((pNMListView->uNewState & LVIS_STATEIMAGEMASK)>>12)-1);
if (bChecked < 0)// On non-checkbox notifications assume false
bChecked = 0;
if (bPrevState == bChecked)// No change in check box
return;
// Now bChecked holds the new check box state
// ....
}
forthis to work, you must map the following message:
ON_NOTIFY(LVN_ITEMCHANGED, IDC_MYLIST, OnItemchangedLinksList)
Setting the check box state of an item:
Try the following piece of code
void SetLVCheck (WPARAM ItemIndex, BOOL bCheck)
{
ListView_SetItemState (m_lvTestList.m_hWnd, ItemIndex,
UINT((int(bCheck) + 1) << 12), LVIS_STATEIMAGEMASK);
}
阻止column大小被改变-一
The header control in the ListView control sends notification to the parent window (e.i. the ListView) before it begins resizing a column. We can override the OnNotify() function in the CListCtrl derivedclass to handlethis notification. The code below prevents resizing of all columns. Note that the resize cursor still shows up.
BOOL CMyListCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
switch (((NMHDR*)lParam)->code)
{
case HDN_BEGINTRACKW:
case HDN_BEGINTRACKA:
case (HDN_DIVIDERDBLCLICKA):
case (HDN_DIVIDERDBLCLICKW):
{
*pResult = TRUE; // disable tracking
return TRUE; // Processed message
}
}
return CListCtrl::OnNotify(wParam, lParam, pResult);
return CListCtrl::OnNotify(wParam, lParam, pResult);
}
If you want to prevent resizing of only one column, you should checkfor the value in iItem field of the HD_NOTIFY structure. The code below stops only the first column from being resized.
BOOL CMyListCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
HD_NOTIFY *pHDN = (HD_NOTIFY*)lParam;
if((pHDN->hdr.code == HDN_BEGINTRACKW || pHDN->hdr.code == HDN_BEGINTRACKA)
&& pHDN->iItem == 0) // Prevent only first (col# 0) from resizing
{
*pResult = TRUE; // disable tracking
return TRUE; // Processed message
}
return CListCtrl::OnNotify(wParam, lParam, pResult);
}
阻止column大小被改变--二
查看源代码拷贝至剪贴板打印代码
// MyHeader.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CMyHeader window
#ifndef __MYHEADER_H__
#define __MYHEADER_H__
class CMyHeader :public CHeaderCtrl
{
// Construction
public:
CMyHeader();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMyHeader)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMyHeader();
// Generated message map functions
protected:
//{{AFX_MSG(CMyHeader)
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msgvoid OnLButtonDblClk(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif
/////////////////////////////////////////////////////////////////////////////
// MyHeader.cpp : implementation file
//
#include"stdafx.h"
#include"MyHeader.h"
#ifdef _DEBUG
#definenew DEBUG_NEW
#undef THIS_FILE
staticchar THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMyHeader
CMyHeader::CMyHeader()
{
}
CMyHeader::~CMyHeader()
{
}
BEGIN_MESSAGE_MAP(CMyHeader, CHeaderCtrl)
//{{AFX_MSG_MAP(CMyHeader)
ON_WM_SETCURSOR()
ON_WM_LBUTTONDBLCLK()
ON_WM_NCHITTEST()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
////////////////////////////////////////////////////////////////////
// Disabling this message callback prevents the cursor from
// changing when the cursor is over the column separator line
// in the header. We enable this callback only if the cursor lies
// on a separator for which resizing has been allowed.
//
BOOL CMyHeader::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (m_bAllowDrag)
return CHeaderCtrl::OnSetCursor(pWnd, nHitTest, message);
else
return TRUE;
}
/////////////////////////////////////////////////////////////////
// Disabling this message callback prevents the feature that headers
// have of resizing a column when a double click is done on the column
// separator line. We enable this callback only if the cursor lies
// on a separator for which resizing has been allowed.
//
void CMyHeader::OnLButtonDblClk(UINT nFlags, CPoint point)
{
if (IsDragAllowed( point ))
CHeaderCtrl::OnLButtonDblClk(nFlags, point);
}
///////////////////////////////////////////////////////////////
// Everytime there is a cursor movement whithin the header, this
// function is invoked. It has the feature that it is invoked
// before OnSetCursor(), which means we can decide in advance
// whether we want the tracking cursor to appear. (An aside:
// OnMouseMove() will also track mouse movement, but it is
// invoked after OnSetCursor())
//
UINT CMyHeader::OnNcHitTest(CPoint point)
{
// This 'point' is in screen coordinates. We need to
// transform it to client coords before we test which
// column it is in.
POINT clientPoint = point;
ScreenToClient( &clientPoint );
m_bAllowDrag = IsDragAllowed( clientPoint );
return CHeaderCtrl::OnNcHitTest(point);
}
The following function iswhere we select the columnsfor which we want to disable dragging. It is assumed we have 5 columns, and we want to disable draggingfor columns 0, 2, and 3.
/////////////////////////////////////////////////////////////
// This is the function which determines which column
// the cursor is in, and we decide whether we want to
// allow resizing of that column.
//
BOOL CMyHeader::IsDragAllowed( CPoint point )
{
// We will extract information about the header
// using this structure
HD_ITEM hi;
hi.mask = HDI_WIDTH; // We want the column width.
// We keep a running sum of the horizontal location
// of each column's divider.
int dividerLocations = 0;
// The amount of space around the dividor inside of which one
// can begin the dragging operation is equal to the width of
// the cursor, centered at the dividor. So we need to trap
// the cursor a distance of half the cursor width to each
// side of the dividor.
int dragWidth = GetSystemMetrics( SM_CXCURSOR );
// Since we have no need to apply this test for columns for which
// we want to enable dragging, we do not need to go beyond the last
// column for which we want to disable dragging in our 'for loop'.
BOOL allowDrag = TRUE;
for (int i = 0; i < 4; ++i) {
GetItem(i, &hi);
// hi.cxy contains the width of the i'th column.
dividerLocations += hi.cxy;
// Here is where we place the indexes for the columns
// for which we want to disable dragging.
if (i == 0 ||
i == 2 ||
i == 3)
if (point.x > dividerLocations - dragWidth/2 &&
point.x < dividerLocations + dragWidth/2)
allowDrag = FALSE;
}
return allowDrag;
}