|
Question : Using CListView
|
|
If anyone has an example of how to use the CListView, could you sent me a sample that will work in VC4 so that I can study it?
|
|
Answer : Using CListView
|
|
The simplest use of the CListView class is to display a report style list. The following is all the code necessary to implement your own CListView:
First, the CListView files:
// StatsListView.h : header file // //This class manage's DMDS_Pro's Statistics View display. // //5\7\1998 Mark Wallace Added m_cslHeads and m_cslCols // to store the views data in the // case where the view is not // displayed i.e. it doesn't have // a window. This was done when // it was discovered that when // the app was loaded as an OLE // Automation object it didn't // create a window. This fact // was discovered while developing // DMDS_StatsViewer.exe, a simple // SDI app used to view the StatsMngr.smd // data file created by the profiler // object. ///////////////////////////////////////////////////////////////////////////// // CStatsListView view
#ifndef StatsListViewDefined #define StatsListViewDefined
#include "listvwex.h" #include "ReportStyleListControl.h" #include "StatsMngr.h"
#define MAX_STATS_COLS 2 class CStatsListView : public CListViewEx { public: CReportStyleListControl *m_pReportLstCtrl ; //UINT m_PlaStartIndex ;
//Column Headers CStringList m_cslHeads ;
//Column data CStringList m_cslCols [MAX_STATS_COLS];
void AddColumn (int ColumnNumber, int ColumnWidth, char ColumnTitle []) ; void AddItem (int ItemNumber, int SubItemNumber, char Text []) ;
void CStatsListView::IntlzDisplay () ; void UpdateDisplay (CStatsMngr *pStatsMngr) ;
protected: CStatsListView(); // protected constructor used by dynamic creation DECLARE_DYNCREATE(CStatsListView)
// Attributes public:
// Operations public:
// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CStatsListView) public: virtual void OnInitialUpdate(); protected: virtual void OnDraw(CDC* pDC); // overridden to draw this view //}}AFX_VIRTUAL
// Implementation protected: virtual ~CStatsListView(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif
// Generated message map functions protected: afx_msg void OnContextMenu(CWnd*, CPoint point); //{{AFX_MSG(CStatsListView) afx_msg void OnEditCopy(); //}}AFX_MSG DECLARE_MESSAGE_MAP() };
///////////////////////////////////////////////////////////////////////////// #endif
// StatsListView.cpp : implementation file //
#include "stdafx.h" #include "MDI_DMDS.h" #include "StatsListView.h" #include "resource.h"
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
///////////////////////////////////////////////////////////////////////////// // CStatsListView
IMPLEMENT_DYNCREATE(CStatsListView, CListViewEx)
CStatsListView::CStatsListView() { #ifdef MESSAGE_BOX_TRACE_VIEW AfxMessageBox ("::CStatsListView()") ; #endif
m_pReportLstCtrl = NULL ; //m_PlaStartIndex = 0 ;
//Initialize display buffers IntlzDisplay () ; }
CStatsListView::~CStatsListView() { if (m_pReportLstCtrl) { delete m_pReportLstCtrl ; m_pReportLstCtrl = NULL ; } ;
} //////////////////////////////////////////////////////// // void CStatsListView::AddColumn (int ColumnNumber, int ColumnWidth, char ColumnTitle []) { m_cslHeads.AddTail (ColumnTitle) ;
if (m_pReportLstCtrl) { m_pReportLstCtrl->AddColumn (ColumnNumber, ColumnWidth, ColumnTitle) ; } ;
} ; //////////////////////////////////////////////////////// // void CStatsListView::AddItem (int ItemNumber, int SubItemNumber, char Text []) { if (SubItemNumber + 1 > MAX_STATS_COLS) { ASSERT (FALSE) ; return ; } ;
CString cst ; if (ItemNumber + 1 > m_cslCols[SubItemNumber].GetCount()) { //Fill the list with dummies till we have enough //values i.e. fill with blank place holder strings.
int iCur = m_cslCols[SubItemNumber].GetCount() ; while (m_cslCols[SubItemNumber].GetCount() < ItemNumber + 1) { m_cslCols[SubItemNumber].AddTail(cst) ; } ; } ;
//Now find the position specified by the index passed in //and put the data into it. POSITION pos = m_cslCols[SubItemNumber].FindIndex (ItemNumber) ; m_cslCols[SubItemNumber].SetAt(pos, Text) ;
if (m_pReportLstCtrl) { m_pReportLstCtrl->AddItem (ItemNumber, SubItemNumber, Text) ; } ; } ; //////////////////////////////////////////////////////// // void CStatsListView::IntlzDisplay () { AddColumn (0, 300, "Statistic") ; AddColumn (1, 85, "Value") ;
/*Do the following every time updated: //temporary index UINT x ;
x = 0 ; AddItem (x, 0, "Counters zeroed at") ; AddItem (x, 1, "0") ;
x++ ; AddItem (x, 0, "Number of Messages Processed:") ;
x++ ; AddItem (x, 0, " From Disk") ; AddItem (x, 1, "0") ;
x++ ; AddItem (x, 0, " From Inbox") ; AddItem (x, 1, "0") ;
x++ ; AddItem (x, 0, " Reassembled Sectioned Messages") ; AddItem (x, 1, "0") ;
x++ ; AddItem (x, 0, " Total") ; AddItem (x, 1, "0") ;
x++ ; AddItem (x, 0, "Number of:") ;
x++ ; AddItem (x, 0, " Messages Disseminated") ; AddItem (x, 1, "0") ;
x++ ; AddItem (x, 0, " Messages Not Disseminated") ; AddItem (x, 1, "0") ;
x++ ; AddItem (x, 0, " Sections Staged") ; AddItem (x, 1, "0") ;
x++ ; AddItem (x, 0, " Total") ; AddItem (x, 1, "0") ;
x++ ; AddItem (x, 0, "") ;
x++ ; AddItem (x, 0, "Dissemination breakdown by Profile Set Name:") ;
x++ ; AddItem (x, 0, "") ;
//TODO: List all the recipients and the //number of message. Might want //to implement a splitter window with //these. x++ ; m_PlaStartIndex = x ; */ } ;
BEGIN_MESSAGE_MAP(CStatsListView, CListViewEx) ON_WM_CONTEXTMENU() //{{AFX_MSG_MAP(CStatsListView) ON_COMMAND(ID_EDIT_COPY, OnEditCopy) //}}AFX_MSG_MAP END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CStatsListView drawing
void CStatsListView::OnDraw(CDC* pDC) { CDocument* pDoc = GetDocument(); // TODO: add draw code here }
///////////////////////////////////////////////////////////////////////////// // CStatsListView diagnostics
#ifdef _DEBUG void CStatsListView::AssertValid() const { CListViewEx::AssertValid(); }
void CStatsListView::Dump(CDumpContext& dc) const { CListViewEx::Dump(dc); } #endif //_DEBUG
///////////////////////////////////////////////////////////////////////////// // CStatsListView message handlers
void CStatsListView::OnInitialUpdate() { #ifdef MESSAGE_BOX_TRACE_VIEW AfxMessageBox ("View::OnInitialUpdate()") ; #endif
CListViewEx::OnInitialUpdate(); // TODO: Add your specialized code here and/or call the base class //Make a an object to manage this display //in report style. CReportStyleListControl *pListView = new CReportStyleListControl ((class CView *)this); pListView->InitListControl() ; m_pReportLstCtrl = pListView ; ASSERT (m_pReportLstCtrl) ;
//Initialize how the list control looks. i.e. //put the appropriate column headers. IntlzDisplay () ; } ///////////////////////////////////////////////////////////// // void CStatsListView::UpdateDisplay (CStatsMngr *pStatsMngr) { ASSERT (pStatsMngr) ; if (!pStatsMngr) return ;
//Read the current stats for display. CStatsMngrData csd ; pStatsMngr->GetCurrentStats (&csd) ;
UINT uiTotalFromInputPaths = 0 ; CString csTmp ; UINT x ;
x = 0 ; AddItem (x, 0, "Counters zeroed at") ; csTmp = csd.m_Time.Format ("%j %H:%M:%S") ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; AddItem (x, 0, "Number of Messages Processed:") ;
POSITION InCountPos = csd.m_cslInputPathCounts.GetHeadPosition() ; POSITION InPos = csd.m_InputPaths.GetHeadPosition() ; while (InPos) { x++ ; csTmp.Format (" From %s", csd.m_InputPaths.GetNext(InPos)->m_csPath) ; AddItem (x, 0, csTmp.GetBuffer(0)) ;
CString csInCount = csd.m_cslInputPathCounts.GetNext (InCountPos) ; AddItem (x, 1, csInCount.GetBuffer(0)) ;
//Update the count for the total uiTotalFromInputPaths += atoi (csInCount) ; } ; x++ ; AddItem (x, 0, " Reassembled Sectioned Messages") ; csTmp.Format("%d", csd.m_ulNumFromReassembledSections) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; AddItem (x, 0, " Total") ; csTmp.Format ("%d", uiTotalFromInputPaths + csd.m_ulNumFromReassembledSections) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; AddItem (x, 0, "Number of:") ;
x++ ; AddItem (x, 0, " Messages Disseminated") ; csTmp.Format ("%d", csd.m_ulNumRouted) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; AddItem (x, 0, " Messages Not Disseminated") ; csTmp.Format ("%d", csd.m_ulNumNotRouted) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; AddItem (x, 0, " Sections Staged") ; csTmp.Format ("%d", csd.m_ulNumSectionsStaged) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; AddItem (x, 0, " Total") ; csTmp.Format ("%d", csd.m_ulNumRouted + csd.m_ulNumNotRouted + csd.m_ulNumSectionsStaged) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; AddItem (x, 0, "") ;
x++ ; AddItem (x, 0, "Dissemination breakdown by Profile Set Name:") ;
x++ ; AddItem (x, 0, "") ;
x++ ;
CString csName ; CString csCount ; UINT uIndex ; POSITION CountPos ; POSITION pos ;
//Update the individual PLA\Recipient breakdown //display.
uIndex = 0 ; CStringList *pcslReceiverCounts = &csd.m_cslReceiverCounts ; CStringList *pcslReceiverNames = &csd.m_cslReceiverNames ; ASSERT (pcslReceiverNames) ; pos = pcslReceiverNames->GetHeadPosition() ; while (pos) { csName = pcslReceiverNames->GetNext (pos) ;
//Get the string representing the count //in the adjoining list. CountPos = pcslReceiverCounts->FindIndex (uIndex) ; csCount = pcslReceiverCounts->GetAt (CountPos) ;
//Add this to the display AddItem (x + uIndex, 0, csName.GetBuffer(0)) ; AddItem (x + uIndex, 1, csCount.GetBuffer(0)) ;
uIndex++ ; } ;
/* CString csTmp ; UINT x ;
//Update the system startup time x = 0 ; csTmp = csd.m_Time.Format ("%j %H:%M:%S") ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
//Update the all around stats. x += 2 ; csTmp.Format("%d", csd.m_ulNumFromDisk) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; csTmp.Format("%d", csd.m_ulNumFromInbox) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; csTmp.Format("%d", csd.m_ulNumFromReassembledSections) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; csTmp.Format ("%d", csd.m_ulNumFromDisk + csd.m_ulNumFromInbox + csd.m_ulNumFromReassembledSections) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x += 2 ; csTmp.Format ("%d", csd.m_ulNumRouted) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; csTmp.Format ("%d", csd.m_ulNumNotRouted) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; csTmp.Format ("%d", csd.m_ulNumSectionsStaged) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
x++ ; csTmp.Format ("%d", csd.m_ulNumRouted + csd.m_ulNumNotRouted + csd.m_ulNumSectionsStaged) ; AddItem (x, 1, csTmp.GetBuffer(0)) ;
CString csName ; CString csCount ; UINT uIndex ; POSITION CountPos ; POSITION pos ;
//Update the individual PLA\Recipient breakdown //display.
uIndex = 0 ; CStringList *pcslReceiverCounts = &csd.m_cslReceiverCounts ; CStringList *pcslReceiverNames = &csd.m_cslReceiverNames ; ASSERT (pcslReceiverNames) ; pos = pcslReceiverNames->GetHeadPosition() ; while (pos) { csName = pcslReceiverNames->GetNext (pos) ;
//Get the string representing the count //in the adjoining list. CountPos = pcslReceiverCounts->FindIndex (uIndex) ; csCount = pcslReceiverCounts->GetAt (CountPos) ;
//Add this to the display AddItem (m_PlaStartIndex + uIndex, 0, csName.GetBuffer(0)) ; AddItem (m_PlaStartIndex + uIndex, 1, csCount.GetBuffer(0)) ;
uIndex++ ; } ; */ } ;
void CStatsListView::OnContextMenu(CWnd*, CPoint point) {
// CG: This block was added by the Pop-up Menu component { if (point.x == -1 && point.y == -1){ //keystroke invocation CRect rect; GetClientRect(rect); ClientToScreen(rect);
point = rect.TopLeft(); point.Offset(5, 5); }
CMenu menu; VERIFY(menu.LoadMenu(CG_IDR_POPUP_LOG_VIEW));
CMenu* pPopup = menu.GetSubMenu(0); //ASSERT(pPopup != NULL); if (!pPopup) return ;
CWnd* pWndPopupOwner = this;
while (pWndPopupOwner->GetStyle() & WS_CHILD) pWndPopupOwner = pWndPopupOwner->GetParent();
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, pWndPopupOwner); } }
void CStatsListView::OnEditCopy() { if (!m_pReportLstCtrl) return ;
//Copy all selected list control items to the //Clip board. m_pReportLstCtrl->CopyAllSelectedToClip () ; }
////END StatsListView.cpp
// ListVwEx.h : interface of the CListViewEx class // // This class provedes a full row selection mode for the report // mode list view control. // // This is a part of the Microsoft Foundation Classes C++ library. // Copyright (C) 1992-1997 Microsoft Corporation // All rights reserved. // // This source code is only intended as a supplement to the // Microsoft Foundation Classes Reference and related // electronic documentation provided with the library. // See these sources for detailed information regarding the // Microsoft Foundation Classes product. #ifndef CListViewExDefined #define CListViewExDefined
class CListViewEx : public CListView { DECLARE_DYNCREATE(CListViewEx)
// Construction public: //Set this to change the text color of certain specified //words. BOOL m_bHighLightFlagWords ; CListViewEx();
// Attributes protected: BOOL m_bFullRowSel;
public: BOOL SetFullRowSel(BOOL bFillRowSel); BOOL GetFullRowSel();
BOOL m_bClientWidthSel;
// Overrides protected: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
// ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CListViewEx) public: virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: //}}AFX_VIRTUAL
// Implementation public: virtual ~CListViewEx(); #ifdef _DEBUG virtual void Dump(CDumpContext& dc) const; #endif
protected: static LPCTSTR MakeShortString(CDC* pDC, LPCTSTR lpszLong, int nColumnLen, int nOffset); void RepaintSelectedItems();
// Implementation - client area width int m_cxClient;
// Implementation - state icon width int m_cxStateImageOffset; afx_msg LRESULT OnSetImageList(WPARAM wParam, LPARAM lParam);
// Implementation - list view colors COLORREF m_clrText; COLORREF m_clrTextBk; COLORREF m_clrBkgnd; afx_msg LRESULT OnSetTextColor(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnSetTextBkColor(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnSetBkColor(WPARAM wParam, LPARAM lParam);
// Generated message map functions protected: //{{AFX_MSG(CListViewEx) afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg void OnPaint(); afx_msg void OnSetFocus(CWnd* pOldWnd); afx_msg void OnKillFocus(CWnd* pNewWnd); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; #endif
/////////////////////////////////////////////////////////////////////////////
// ListVwEx.cpp : implementation of the CListViewEx class // // This is a part of the Microsoft Foundation Classes C++ library. // Copyright (C) 1992-1997 Microsoft Corporation // All rights reserved. // // This source code is only intended as a supplement to the // Microsoft Foundation Classes Reference and related // electronic documentation provided with the library. // See these sources for detailed information regarding the // Microsoft Foundation Classes product.
#include "stdafx.h" #include "ListVwEx.h"
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
///////////////////////////////////////////////////////////////////////////// // CListViewEx
IMPLEMENT_DYNCREATE(CListViewEx, CListView)
BEGIN_MESSAGE_MAP(CListViewEx, CListView) //{{AFX_MSG_MAP(CListViewEx) ON_WM_SIZE() ON_WM_PAINT() ON_WM_SETFOCUS() ON_WM_KILLFOCUS() //}}AFX_MSG_MAP ON_MESSAGE(LVM_SETIMAGELIST, OnSetImageList) ON_MESSAGE(LVM_SETTEXTCOLOR, OnSetTextColor) ON_MESSAGE(LVM_SETTEXTBKCOLOR, OnSetTextBkColor) ON_MESSAGE(LVM_SETBKCOLOR, OnSetBkColor) END_MESSAGE_MAP()
///////////////////////////////////////////////////////////////////////////// // CListViewEx construction/destruction
CListViewEx::CListViewEx() { m_bHighLightFlagWords = FALSE ; m_bFullRowSel = FALSE; m_bClientWidthSel = TRUE;
m_cxClient = 0; m_cxStateImageOffset = 0;
m_clrText = ::GetSysColor(COLOR_WINDOWTEXT); m_clrTextBk = ::GetSysColor(COLOR_WINDOW); m_clrBkgnd = ::GetSysColor(COLOR_WINDOW); }
CListViewEx::~CListViewEx() { }
BOOL CListViewEx::PreCreateWindow(CREATESTRUCT& cs) { // default is report view and full row selection cs.style &= ~LVS_TYPEMASK; cs.style |= LVS_REPORT | LVS_OWNERDRAWFIXED; m_bFullRowSel = TRUE;
return(CListView::PreCreateWindow(cs)); }
BOOL CListViewEx::SetFullRowSel(BOOL bFullRowSel) { // no painting during change LockWindowUpdate();
m_bFullRowSel = bFullRowSel;
BOOL bRet;
if (m_bFullRowSel) bRet = ModifyStyle(0L, LVS_OWNERDRAWFIXED); else bRet = ModifyStyle(LVS_OWNERDRAWFIXED, 0L);
// repaint window if we are not changing view type if (bRet && (GetStyle() & LVS_TYPEMASK) == LVS_REPORT) Invalidate();
// repaint changes UnlockWindowUpdate();
return(bRet); }
BOOL CListViewEx::GetFullRowSel() { return(m_bFullRowSel); }
///////////////////////////////////////////////////////////////////////////// // CListViewEx drawing
const COLORREF RED = RGB(255,0,0); //red const COLORREF BLUE = RGB(0,0,255); //blue const COLORREF GREEN = RGB(0,255,0); //green
// offsets for first and other columns #define OFFSET_FIRST 2 #define OFFSET_OTHER 6
void CListViewEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { CListCtrl& ListCtrl=GetListCtrl(); CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); CRect rcItem(lpDrawItemStruct->rcItem); UINT uiFlags = ILD_TRANSPARENT; CImageList* pImageList; int nItem = lpDrawItemStruct->itemID; BOOL bFocus = (GetFocus() == this); COLORREF clrTextSave, clrBkSave; COLORREF clrImage = m_clrBkgnd; static _TCHAR szBuff[MAX_PATH]; LPCTSTR pszText;
// get item data
LV_ITEM lvi; lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; lvi.iItem = nItem; lvi.iSubItem = 0; lvi.pszText = szBuff; lvi.cchTextMax = sizeof(szBuff); lvi.stateMask = 0xFFFF; // get all state flags ListCtrl.GetItem(&lvi);
BOOL bSelected = (bFocus || (GetStyle() & LVS_SHOWSELALWAYS)) && lvi.state & LVIS_SELECTED; bSelected = bSelected || (lvi.state & LVIS_DROPHILITED);
// set colors if item is selected
CRect rcAllLabels; ListCtrl.GetItemRect(nItem, rcAllLabels, LVIR_BOUNDS);
CRect rcLabel; ListCtrl.GetItemRect(nItem, rcLabel, LVIR_LABEL);
rcAllLabels.left = rcLabel.left; if (m_bClientWidthSel && rcAllLabels.rightnt) rcAllLabels.right = m_cxClient;
if (bSelected) { clrTextSave = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT)); clrBkSave = pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
pDC->FillRect(rcAllLabels, &CBrush(::GetSysColor(COLOR_HIGHLIGHT))); } else pDC->FillRect(rcAllLabels, &CBrush(m_clrTextBk));
// set color and mask for the icon
if (lvi.state & LVIS_CUT) { clrImage = m_clrBkgnd; uiFlags |= ILD_BLEND50; } else if (bSelected) { clrImage = ::GetSysColor(COLOR_HIGHLIGHT); uiFlags |= ILD_BLEND50; }
// draw state icon
UINT nStateImageMask = lvi.state & LVIS_STATEIMAGEMASK; if (nStateImageMask) { int nImage = (nStateImageMask>>12) - 1; pImageList = ListCtrl.GetImageList(LVSIL_STATE); if (pImageList) { pImageList->Draw(pDC, nImage, CPoint(rcItem.left, rcItem.top), ILD_TRANSPARENT); } }
// draw normal and overlay icon
CRect rcIcon; ListCtrl.GetItemRect(nItem, rcIcon, LVIR_ICON);
pImageList = ListCtrl.GetImageList(LVSIL_SMALL); if (pImageList) { UINT nOvlImageMask=lvi.state & LVIS_OVERLAYMASK; if (rcItem.left1) { ImageList_DrawEx(pImageList->m_hImageList, lvi.iImage, pDC->m_hDC,rcIcon.left,rcIcon.top, 16, 16, m_clrBkgnd, clrImage, uiFlags | nOvlImageMask); } }
// draw item label
ListCtrl.GetItemRect(nItem, rcItem, LVIR_LABEL); rcItem.right -= m_cxStateImageOffset;
pszText = MakeShortString(pDC, szBuff, rcItem.right-rcItem.left, 2*OFFSET_FIRST);
rcLabel = rcItem; rcLabel.left += OFFSET_FIRST; rcLabel.right -= OFFSET_FIRST;
pDC->DrawText(pszText,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
// draw labels for extra columns
LV_COLUMN lvc; lvc.mask = LVCF_FMT | LVCF_WIDTH; for(int nColumn = 1; ListCtrl.GetColumn(nColumn, &lvc); nColumn++) { rcItem.left = rcItem.right; rcItem.right += lvc.cx;
int nRetLen = ListCtrl.GetItemText(nItem, nColumn, szBuff, sizeof(szBuff)); if (nRetLen == 0) continue;
pszText = MakeShortString(pDC, szBuff, rcItem.right - rcItem.left, 2*OFFSET_OTHER);
UINT nJustify = DT_LEFT;
if(pszText == szBuff) { switch(lvc.fmt & LVCFMT_JUSTIFYMASK) { case LVCFMT_RIGHT: nJustify = DT_RIGHT; break; case LVCFMT_CENTER: nJustify = DT_CENTER; break; default: break; } }
rcLabel = rcItem; rcLabel.left += OFFSET_OTHER; rcLabel.right -= OFFSET_OTHER;
COLORREF HoldColor = pDC->GetTextColor() ; if (m_bHighLightFlagWords) { //See if this field contains text we //should highlight. CString csTmp = pszText ; csTmp.TrimRight (" ") ; if (csTmp=="ERR") { pDC->SetTextColor (RED) ; } else if (csTmp=="ACC") { pDC->SetTextColor (GREEN) ; } else if (csTmp=="ACT") { pDC->SetTextColor (BLUE) ; } ;
} ;
pDC->DrawText(pszText, -1, rcLabel, nJustify | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP | DT_VCENTER);
//Put original color back. pDC->SetTextColor (HoldColor) ;
}
// draw focus rectangle if item has focus
if (lvi.state & LVIS_FOCUSED && bFocus) pDC->DrawFocusRect(rcAllLabels);
// set original colors if item was selected
if (m_bHighLightFlagWords) { } ;
if (bSelected) { pDC->SetTextColor(clrTextSave); pDC->SetBkColor(clrBkSave); } }
LPCTSTR CListViewEx::MakeShortString(CDC* pDC, LPCTSTR lpszLong, int nColumnLen, int nOffset) { static const _TCHAR szThreeDots[] = _T("...");
int nStringLen = lstrlen(lpszLong);
if(nStringLen == 0 || (pDC->GetTextExtent(lpszLong, nStringLen).cx + nOffset) <= nColumnLen) { return(lpszLong); }
static _TCHAR szShort[MAX_PATH];
lstrcpy(szShort,lpszLong); int nAddLen = pDC->GetTextExtent(szThreeDots,sizeof(szThreeDots)).cx;
for(int i = nStringLen-1; i > 0; i--) { szShort[i] = 0; if((pDC->GetTextExtent(szShort, i).cx + nOffset + nAddLen) <= nColumnLen) { break; } }
lstrcat(szShort, szThreeDots); return(szShort); }
void CListViewEx::RepaintSelectedItems() { CListCtrl& ListCtrl = GetListCtrl(); CRect rcItem, rcLabel;
// invalidate focused item so it can repaint properly
int nItem = ListCtrl.GetNextItem(-1, LVNI_FOCUSED);
if(nItem != -1) { ListCtrl.GetItemRect(nItem, rcItem, LVIR_BOUNDS); ListCtrl.GetItemRect(nItem, rcLabel, LVIR_LABEL); rcItem.left = rcLabel.left;
InvalidateRect(rcItem, FALSE); }
// if selected items should not be preserved, invalidate them
if(!(GetStyle() & LVS_SHOWSELALWAYS)) { for(nItem = ListCtrl.GetNextItem(-1, LVNI_SELECTED); nItem != -1; nItem = ListCtrl.GetNextItem(nItem, LVNI_SELECTED)) { ListCtrl.GetItemRect(nItem, rcItem, LVIR_BOUNDS); ListCtrl.GetItemRect(nItem, rcLabel, LVIR_LABEL); rcItem.left = rcLabel.left;
InvalidateRect(rcItem, FALSE); } }
// update changes
UpdateWindow(); }
///////////////////////////////////////////////////////////////////////////// // CListViewEx diagnostics
#ifdef _DEBUG
void CListViewEx::Dump(CDumpContext& dc) const { CListView::Dump(dc);
dc << "m_bFullRowSel = " << (UINT)m_bFullRowSel; dc << "\n"; dc << "m_cxStateImageOffset = " << m_cxStateImageOffset; dc << "\n"; }
#endif //_DEBUG
///////////////////////////////////////////////////////////////////////////// // CListViewEx message handlers
LRESULT CListViewEx::OnSetImageList(WPARAM wParam, LPARAM lParam) { if( (int) wParam == LVSIL_STATE) { int cx, cy;
if(::ImageList_GetIconSize((HIMAGELIST)lParam, &cx, &cy)) m_cxStateImageOffset = cx; else m_cxStateImageOffset = 0; }
return(Default()); }
LRESULT CListViewEx::OnSetTextColor(WPARAM wParam, LPARAM lParam) { m_clrText = (COLORREF)lParam; return(Default()); }
LRESULT CListViewEx::OnSetTextBkColor(WPARAM wParam, LPARAM lParam) { m_clrTextBk = (COLORREF)lParam; return(Default()); }
LRESULT CListViewEx::OnSetBkColor(WPARAM wParam, LPARAM lParam) { m_clrBkgnd = (COLORREF)lParam; return(Default()); }
void CListViewEx::OnSize(UINT nType, int cx, int cy) { m_cxClient = cx; CListView::OnSize(nType, cx, cy); }
void CListViewEx::OnPaint() { // in full row select mode, we need to extend the clipping region // so we can paint a selection all the way to the right if (m_bClientWidthSel && (GetStyle() & LVS_TYPEMASK) == LVS_REPORT && GetFullRowSel()) { CRect rcAllLabels; GetListCtrl().GetItemRect(0, rcAllLabels, LVIR_BOUNDS);
if(rcAllLabels.right < m_cxClient) { // need to call BeginPaint (in CPaintDC c-tor) // to get correct clipping rect CPaintDC dc(this);
CRect rcClip; dc.GetClipBox(rcClip);
rcClip.left = min(rcAllLabels.right-1, rcClip.left); rcClip.right = m_cxClient;
InvalidateRect(rcClip, FALSE); // EndPaint will be called in CPaintDC d-tor } }
CListView::OnPaint(); }
void CListViewEx::OnSetFocus(CWnd* pOldWnd) { CListView::OnSetFocus(pOldWnd);
// check if we are getting focus from label edit box if(pOldWnd!=NULL && pOldWnd->GetParent()==this) return;
// repaint items that should change appearance if(m_bFullRowSel && (GetStyle() & LVS_TYPEMASK)==LVS_REPORT) RepaintSelectedItems(); }
void CListViewEx::OnKillFocus(CWnd* pNewWnd) { CListView::OnKillFocus(pNewWnd);
// check if we are losing focus to label edit box if(pNewWnd != NULL && pNewWnd->GetParent() == this) return;
// repaint items that should change appearance if(m_bFullRowSel && (GetStyle() & LVS_TYPEMASK) == LVS_REPORT) RepaintSelectedItems(); }
//ReportStyleListControl.h // //Object to wrap managing a List Control //resource on a dialog surface. // //Example using: // // /* //Make a list control object CReportStyleListControl *l ; l = new CReportStyleListControl (IDC_LIST3, this) ; m_ListCtrl = (void *)l ; l->InitListControl() ;
//Set the columns we want l->AddColumn (0, 100, "Sender") ; l->AddColumn (1, 100, "Subject") ;
//Add some items to the columns
//item 1 l->AddItem (0, 0, "Test Sender 1") ; l->AddItem (0, 1, "Test Subject 1") ;
//item 2 l->AddItem (1, 0, "Test Sender 2") ; l->AddItem (1, 1, "Test Subject 2") ;
//item 3, etc.... l->AddItem (2, 0, "Test Sender 3") ; l->AddItem (2, 1, "Test Subject 3") ;
*/
#ifndef CReportStyleListControlDefined #define CReportStyleListControlDefined
#include "afxcoll.h"
#define MAXLOGS 1000
class CReportStyleListControl { public: //constructor, needs a pointer to //the main CListView. CReportStyleListControl (CView *ViewPtr, int CtrlId = 0) ; CReportStyleListControl (CListCtrl *pListCtrl) ;
CListCtrl *pGetListCtrl () ;
//Find the zero based index of the first //matching log line. int FindNext (CString SearchStr, DWORD Flags) ;
//Rebuild the contents of the list control based //on the filter bRebuildListControlFromFilter ( CString csFilter, DWORD dFlags ) ;
void InitListControl () ;
//Call this once for each column of the //list control. void AddColumn (int ColumnNumber, int ColumnWidth, char ColumnTitle []) ;
void RemoveItem (int ItemNumber) ; void AddItem (int ItemNumber, int SubItemNumber, char Text []) ;
BOOL DeleteItem( int nItem );
BOOL DeleteAllItems();
BOOL EnsureVisible( int nItem, BOOL bPartialOK );
void GetSelectedItemList (CUIntArray &uiaSelectedIndices) ; int GetSelectedItem () ; int SetSelectedItem (int index) ;
//Routine to retrieve a specified item and subitem. BOOL bGetItemStrVal ( int iItem, int iSubItem, CString &csItemStrVal ) ;
BOOL bGetAllItemStrVal ( int iItem, CString &csItemStrVal ) ;
void CopyAllSelectedToClip () ;
private: CListCtrl *m_pProvidedListCtrl ; int m_ListCtrlId ; CView *m_View ; int m_NumSubItems ;
CListCtrl *m_ListCtrl ;
void SetViewState () ;
BOOL bStrMatches (CString StrChecking, CString SearchStr, ULONG Flags ) ;
BOOL bItemMatches ( int iIndex, CString csSearchStr, DWORD dFlags ) ;
} ;
#endif
//ReportStyleListControl.cpp
#include "stdafx.h" #include "AfxCView.h" #include "ReportStyleListControl.h" #include "Filter.h"
//////////////////////////////////////////////// //constructor for the list control logger. // //Construct with a control id of a list control //and a pointer to the view were its at. // CReportStyleListControl::CReportStyleListControl (CView *ViewPtr, int CtrlId ) { m_ListCtrlId = CtrlId; m_View = ViewPtr; m_NumSubItems = 0 ; m_pProvidedListCtrl = NULL ; InitListControl() ; } ; /////////////////////////////////////////////////// //Construct with a list control object. // CReportStyleListControl::CReportStyleListControl (CListCtrl *pListCtrl) { m_ListCtrlId = 0; m_View = NULL; m_NumSubItems = 0 ; m_pProvidedListCtrl = pListCtrl ; InitListControl() ; } ; /////////////////////////////////////////////////// // CListCtrl *CReportStyleListControl::pGetListCtrl () { if (m_pProvidedListCtrl) return m_pProvidedListCtrl ;
ASSERT (m_View) ; if (!m_View) return NULL;
if (m_ListCtrlId) { return (CListCtrl *)m_View->GetDlgItem (m_ListCtrlId) ; } else { //Assume we are operating on a list control view. CListView *pLstView = (CListView *)m_View; CListCtrl *pLstCtrl ; CListCtrl &LstCtrl = pLstView->GetListCtrl() ; pLstCtrl = &LstCtrl ; return pLstCtrl ; } ;
return NULL ; } ; ////////////////////////////////////////////////// // BOOL CReportStyleListControl::DeleteAllItems() { m_ListCtrl = pGetListCtrl () ; return m_ListCtrl->DeleteAllItems() ; } ; ////////////////////////////////////////////////// // BOOL CReportStyleListControl::DeleteItem( int nItem ) { m_ListCtrl = pGetListCtrl () ; return m_ListCtrl->DeleteItem (nItem) ; } ; ////////////////////////////////////////////////// // BOOL CReportStyleListControl::EnsureVisible( int nItem, BOOL bPartialOK ) { m_ListCtrl = pGetListCtrl () ;
return m_ListCtrl->EnsureVisible(nItem, bPartialOK) ; } ; ////////////////////////////////////////////////// //Set View state. Specifically, make sure //the list control is in the LVS_REPORT state. // // void CReportStyleListControl::SetViewState () { m_ListCtrl = pGetListCtrl () ;
//Ensure that the view has the LVS_REPORT //bit on.
// SetView - sets a list view's window style to change the view. // hwndLV - handle of the list view control // dwView - value specifying a view style
// Get the current window style. DWORD dwStyle = GetWindowLong (*m_ListCtrl, GWL_STYLE); // Only set the window style if the view bits have changed. if ((dwStyle & LVS_TYPEMASK) != LVS_REPORT) SetWindowLong(*m_ListCtrl, GWL_STYLE, (dwStyle & ~LVS_TYPEMASK) | LVS_REPORT);
} ; ////////////////////////////////////////////////// //Add a column. void CReportStyleListControl::AddColumn (int ColumnNumber, int ColumnWidth, char ColumnTitle []) {
m_ListCtrl = pGetListCtrl () ;
LV_COLUMN lvc;
// Initialize the LV_COLUMN structure. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvc.fmt = LVCFMT_LEFT; lvc.cx = ColumnWidth ;
//Set the title/caption of the column lvc.pszText = ColumnTitle; //Make 1 column lvc.iSubItem = ColumnNumber ;
m_ListCtrl->InsertColumn (ColumnNumber, &lvc) ;
} ; ////////////////////////////////////////////////// //Initialize List control. // //This routine is used to initialize the //columns to be used by our list control. // void CReportStyleListControl::InitListControl () { m_ListCtrl = pGetListCtrl () ;
//Make sure the list control is in //the LVS_REPORT state. SetViewState () ;
} ; ////////////////////////////////////////////////// //Fill a provided integer array with all the //selected indices. // void CReportStyleListControl::GetSelectedItemList (CUIntArray &uiaSelectedIndices) { uiaSelectedIndices.RemoveAll() ; m_ListCtrl = pGetListCtrl () ;
int NumItems = m_ListCtrl->GetItemCount() ; int x ; UINT state ;
for (x=0; x { //See if the item is selected state = m_ListCtrl->GetItemState (x, LVIS_SELECTED) ;
if ((state & LVIS_SELECTED) != 0) { uiaSelectedIndices.Add (x) ; } ; } ; return; } ; ////////////////////////////////////////////////// //return the 0 based index of the first //selected item. // //return -1 if none selected. // int CReportStyleListControl::GetSelectedItem () {
m_ListCtrl = pGetListCtrl () ;
int NumItems = m_ListCtrl->GetItemCount() ; int x ; UINT state ;
for (x=0; x { //See if the item is selected state = m_ListCtrl->GetItemState (x, LVIS_SELECTED) ;
if ((state & LVIS_SELECTED) != 0) { return x ; } ; } ;
return -1 ; } ; ////////////////////////////////////////////////// //Select the specified list control item. // int CReportStyleListControl::SetSelectedItem (int index) { m_ListCtrl = pGetListCtrl () ;
int CurrentSelected = GetSelectedItem() ;
int NumItems = m_ListCtrl->GetItemCount() ;
//BOOL GetItem( LV_ITEM* pItem ) const;
if (CurrentSelected >= 0) { //BOOL SetItemState( int nItem, UINT nState, UINT nMask ); m_ListCtrl->SetItemState (CurrentSelected, (UINT)~LVIS_SELECTED, (UINT)LVIS_SELECTED) ;
} ;
//Set the item specified as being selected BOOL result ; /* result = m_ListCtrl->SetItemState (index, (UINT)LVIS_SELECTED, (UINT)LVIS_SELECTED) ; */
LV_ITEM i ; i.mask = LVIF_STATE ; i.iItem = index ; i.iSubItem = 0 ; i.state = LVIS_SELECTED ; i.stateMask = LVIS_SELECTED ; i.pszText = NULL ; i.cchTextMax = 0 ; i.iImage = NULL ; i.lParam = 0 ; result = m_ListCtrl->SetItem (&i) ;
/*You can't make a subitem highlighted!!!! I guess??? i.mask = LVIF_STATE ; i.iItem = index ; i.iSubItem = 1 ; i.state = LVIS_SELECTED ; i.stateMask = LVIS_SELECTED | LVIS_DROPHILITED; i.pszText = NULL ; i.cchTextMax = 0 ; i.iImage = NULL ; i.lParam = 0 ; result = m_ListCtrl->SetItem (&i) ; */
return ((int)result) ; } ;
////////////////////////////////////////////////// // void CReportStyleListControl::RemoveItem (int ItemNumber) { m_ListCtrl = pGetListCtrl () ; m_ListCtrl->DeleteItem (ItemNumber) ; } ; ////////////////////////////////////////////////// //Add item to list control entree. // void CReportStyleListControl::AddItem (int ItemNumber, int SubItemNumber, char Text []) { m_ListCtrl = pGetListCtrl () ;
LV_ITEM lvItem; lvItem.mask = LVIF_TEXT; lvItem.iItem = ItemNumber ; lvItem.iSubItem = SubItemNumber;
//Keep tract of the number of subitems. if (SubItemNumber > m_NumSubItems) { m_NumSubItems = SubItemNumber ; } ;
lvItem.pszText = (LPTSTR)Text;
//if (SubItemNumber == 0) if (SubItemNumber == 0 && ItemNumber > (m_ListCtrl->GetItemCount() - 1) ) { //This is the first item of the entree m_ListCtrl->InsertItem(&lvItem); m_ListCtrl->EnsureVisible (lvItem.iItem, TRUE) ; } else { //This is an additionl subitem. m_ListCtrl->SetItem(&lvItem); } ;
} ; ////////////////////////////////////////////////// // BOOL CReportStyleListControl::bStrMatches (CString StrChecking, CString SearchStr, ULONG Flags ) { CFilter TextFilter ; CString csFilter ;
if ((Flags & FR_WHOLEWORD) != 0) { csFilter.Format ("'%s' IS FOUND", SearchStr.GetBuffer(0)) ; } else { //Just find any occurance of the text //string csFilter.Format ("\"%s\" IS FOUND", SearchStr.GetBuffer(0)) ; } ;
if ((Flags & FR_MATCHCASE) == 0) { csFilter.MakeUpper() ; StrChecking.MakeUpper() ; } ;
return TextFilter.StrMatchesFilter ( csFilter, StrChecking, Flags & FR_MATCHCASE) ; } ; /////////////////////////////////////////////////// //Routine to retrieve the string value that //is present at a specifed index and subindes. // BOOL CReportStyleListControl::bGetItemStrVal ( int iItem, int iSubItem, CString &csItemStrVal ) { m_ListCtrl = pGetListCtrl () ; CString csTmp ;
CHAR cRcvBuf [500] ;
if (iItem + 1 > m_ListCtrl->GetItemCount()) { //Item requested is out of range return FALSE ; } ;
if (iSubItem > m_NumSubItems) { //SubItem is out of range. return FALSE ; } ;
//Set up a structure to read the string control item LV_ITEM i ; i.iItem = iItem ; i.iSubItem = iSubItem ; i.mask = LVIF_TEXT ; i.pszText = cRcvBuf ; i.cchTextMax = sizeof(cRcvBuf) ;
//Read it. if (!m_ListCtrl->GetItem (&i)) { return FALSE ; } ;
//Save the value return in the //caller's CString object. csItemStrVal = i.pszText ;
return TRUE ; } ; ////////////////////////////////////////////////// //Method to fill a provided CString object //with text from all columns of the specfied //row. // BOOL CReportStyleListControl::bGetAllItemStrVal ( int iItem, CString &csItemStrVal ) { csItemStrVal = "" ; CString csTmp ;
for (int x=0; x<=m_NumSubItems; x++) { if (!bGetItemStrVal ( iItem, x, csTmp )) { return FALSE ; } ;
csItemStrVal += csTmp ; csItemStrVal += " " ; } ;
return TRUE ; } ; ////////////////////////////////////////////////// // void CReportStyleListControl::CopyAllSelectedToClip () { //Copy all selected list control items to the //Clip board. CListCtrl *pListCtrl = pGetListCtrl() ; ASSERT (pListCtrl) ; int iNumItemsSelected = pListCtrl->GetSelectedCount() ; if (iNumItemsSelected <= 0) return ;
CString csSelectedText ; CString csTmp ; int iNumAdded = 0 ;
int iItemIndex = pListCtrl->GetNextItem (-1, LVNI_SELECTED) ; while (iItemIndex != -1) { bGetAllItemStrVal (iItemIndex, csTmp) ; iNumAdded++ ;
if (iNumAdded > 1) { csSelectedText += "\r\n" ; } ; csSelectedText += csTmp ;
//Get the next item, if any. iItemIndex = pListCtrl->GetNextItem (iItemIndex, LVNI_SELECTED) ;
} ;
//Copy the text to the clipboard. if ( !pListCtrl->OpenClipboard() ) { AfxMessageBox( "Cannot open the Clipboard" ); return; } // Remove the current Clipboard contents EmptyClipboard() ;
// ... // Get the currently selected data // ... // For the appropriate data formats... CString csItemText = csSelectedText ;
ULONG ulDataSize = csItemText.GetLength() + 1 ; HANDLE hData = GlobalAlloc ( GMEM_MOVEABLE & GMEM_DDESHARE, ulDataSize) ; LPSTR lpszTmp = (LPSTR)GlobalLock (hData) ; strcpy ( lpszTmp, csItemText.GetBuffer(0)) ; GlobalUnlock (hData) ;
if ( ::SetClipboardData ( CF_TEXT, hData ) == NULL ) { AfxMessageBox( "Unable to set Clipboard data" ); CloseClipboard(); return; }
// ... CloseClipboard();
} ; ////////////////////////////////////////////////// //See if the indexed item matches the specified //search criteria. // BOOL CReportStyleListControl::bItemMatches ( int iIndex, CString csSearchStr, DWORD dFlags ) { m_ListCtrl = pGetListCtrl () ; CString csTmp ;
CHAR cRcvBuf [500] ;
LV_ITEM i ; i.iItem = iIndex ; i.mask = LVIF_TEXT ; i.pszText = cRcvBuf ; i.cchTextMax = sizeof(cRcvBuf) ;
//Search the items for a match i.iSubItem = -1 ; while (1) { i.iSubItem++ ; if (i.iSubItem > m_NumSubItems) { return FALSE ; } ;
if (!m_ListCtrl->GetItem (&i)) { return FALSE ; } ;
//See if this field matches the search csTmp = i.pszText ; if (bStrMatches (csTmp, csSearchStr, dFlags)) { return TRUE ; } ;
};//while searching items
return FALSE; } ; ////////////////////////////////////////////////// //Find the first log in the list that matches //the search criteria passed in. //If a match is found, return the 0 based index of //the item, it NOT, return -1. // //In addition, make the item found visible and //selected. // int CReportStyleListControl::FindNext (CString SearchStr, DWORD Flags) { int iresult = -1 ; m_ListCtrl = pGetListCtrl () ; int iStartIndex ;
if (m_ListCtrl->GetItemCount() <= 0) { //No elements in list, get out return iresult ; } ;
if (m_ListCtrl->GetSelectedCount() <= 0) { //No items selected, start at the top iStartIndex = 0 ; } else { //Find the first selected item. iStartIndex = GetSelectedItem () ;
//Start on the next element for the //search. if (iStartIndex + 1 == m_ListCtrl->GetItemCount()) { iStartIndex = 0 ; } else { iStartIndex++ ; } ;
} ;
//better not be -1 when get here ASSERT (iStartIndex != -1) ;
//Now, starting the next item down, loop through //the list looking for a match until we completely //loop or a match is found. // //Watch out for if 1 item in list. int NumItems = m_ListCtrl->GetItemCount() ;
//Mark the starting index, starting 1 down //from the selected item. int x = iStartIndex;
while (1) { //Check this item and see if it matches. if (bItemMatches ( x, SearchStr, Flags ) ) { //found a match iresult = x ; break ; } ; //Look at the next element if ( x == NumItems - 1 ) { x = 0 ; } else { x++ ; } ;
if (x == iStartIndex) { //search went all the way around without //a match, get out. break ; } ; };//while looking for match
if (iresult != -1) { //selected the item. SetSelectedItem (iresult) ; m_ListCtrl->EnsureVisible (iresult, TRUE) ; } ; return iresult ; } ; //////////////////////////////////////////////////////////////////// //Rebuild the list control, only including those lines that //match a specified criteria passed in. // BOOL CReportStyleListControl::bRebuildListControlFromFilter ( CString csFilter, DWORD dFlags ) { m_ListCtrl = pGetListCtrl () ;
if (m_ListCtrl->GetItemCount() <= 0) { //No elements in list, get out return TRUE ; } ;
//Start at the top of the list and pluck out any //entry that doesn't match the filter. int x = 0; while (1) { //Check this item and see if it matches. if (bItemMatches ( x, csFilter, dFlags ) == FALSE) { //line doesn't match, delete from list RemoveItem (x) ; } else { x++ ; } ; if (x >= m_ListCtrl->GetItemCount()) { //done looking, get out break ; } ; };//while looking for match
return TRUE; } ;
|
|
|
|