现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

CListCtrl 常用的一些代码

2012-09-08 09:39 工业·编程 ⁄ 共 12117字 ⁄ 字号 暂无评论

选择项的问题

双击响应函数里的参数有一个是NM_LISTVIEW *

msdnNMLISTVIEW(把中间那个_去掉)能看到这个结构中有一个成员变量是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; 

} 

 

给我留言

留言无头像?