选择项的问题
双击响应函数里的参数有一个是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
// ....
}
for this 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 derived class to handle this 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 check for 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_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#endif
/////////////////////////////////////////////////////////////////////////////
// MyHeader.cpp : implementation file
//
#include "stdafx.h"
#include "MyHeader.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char 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 is where we select the columns for which we want to disable dragging. It is assumed we have 5 columns, and we want to disable dragging for 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;
}