Solved

Using CListView

Posted on 1998-12-21
7
1,394 Views
Last Modified: 2013-11-20
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?
0
Comment
Question by:kabrit
  • 2
  • 2
  • 2
  • +1
7 Comments
 
LVL 6

Expert Comment

by:thresher_shark
Comment Utility
These samples that come with Visual C++ should help you:

CMNCTRLS
CTRLTEST
FIRE

I don't know if they come with 4.0, but they do come with 5.0.
0
 
LVL 6

Expert Comment

by:thresher_shark
Comment Utility
We don't have access to your email address either so if you wish us to send a sample to you, you will have to post your email :-)
0
 
LVL 8

Expert Comment

by:Answers2000
Comment Utility
There are some nice samples for CListView in the Prosise book. (this is worth getting anyway if you don't have it already, especially if you are quite new to MFC)

http://www.amazon.com/exec/obidos/ASIN/1572316950/answers2000limit
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:kabrit
Comment Utility
thank you for the information, I think that I could find some information from the CMNCTRLS program. However, I was looking more for how to use it when it is the object of a listview class.  I would like to create an win95 explorer kind of interface.
0
 
LVL 8

Expert Comment

by:Answers2000
Comment Utility
There's a sample in Prosise book which is kind of an Explorer type app
0
 

Author Comment

by:kabrit
Comment Utility
e-mail dharry@kancharla.net
0
 

Accepted Solution

by:
WallaceM earned 100 total points
Comment Utility
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.right<m_cxClient)
            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.left<rcItem.right-1)
            {
                  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<NumItems; 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<NumItems; 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;
} ;


0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now