Click here to Skip to main content
15,887,477 members
Articles / Desktop Programming / MFC

A Multiple Substring Search Class: CIVStringSet

Rate me:
Please Sign up or sign in to vote.
4.69/5 (6 votes)
25 Apr 2010CPOL4 min read 152.9K   2.1K   37  
A string array class using MFC or STL that performs very fast multiple string searches
// StringSetSampleDlg.cpp : implementation file

#include "stdafx.h"
#include "StringSetSample.h"
#include "StringSetSampleDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__ ;
#endif

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//                          C A b o u t D l g
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class CAboutDlg : public CDialog
{
public:
    CAboutDlg() ;

// Dialog Data
    enum { IDD = IDD_ABOUTBOX } ;

protected:
    virtual void DoDataExchange( CDataExchange * pDX ) ;

// Implementation
protected:
    DECLARE_MESSAGE_MAP()
} ;

CAboutDlg::CAboutDlg() : CDialog( CAboutDlg::IDD )
{
}

void CAboutDlg::DoDataExchange( CDataExchange * pDX )
{
    CDialog::DoDataExchange( pDX ) ;
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//                  C S t r i n g S e t S a m p l e D l g
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CStringSetSampleDlg Constructor
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CStringSetSampleDlg::CStringSetSampleDlg( CWnd * pParent /*=NULL*/ )
    : CDialog( CStringSetSampleDlg::IDD, pParent )
{
    m_strSearch = _T("The quick red fox jumped over the lazy brown dog.  Now is the time for ")
                  _T("all good men to come\r\nto the aid of their country.  Ask not what your ")
                  _T("country can do for you, but what you can do\r\nfor your country.") ;
    m_hIcon = AfxGetApp()->LoadIcon( IDR_MAINFRAME ) ;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// DoDataExchange
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void CStringSetSampleDlg::DoDataExchange( CDataExchange * pDX )
{
    CDialog::DoDataExchange( pDX ) ;
    DDX_Control( pDX, IDC_SEARCH_STRING,   m_editSearch     ) ;
    DDX_Text(    pDX, IDC_SEARCH_STRING,   m_strSearch      ) ;
    DDX_Control( pDX, IDC_STRINGS_TO_SEEK, m_editSeekTokens ) ;
    DDX_Control( pDX, IDC_SEEK_TOKENS,     m_lbSeekTokens   ) ;
    DDX_Control( pDX, IDC_FOUND_TOKENS,    m_lbFoundTokens  ) ;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OnInitDialog
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BOOL CStringSetSampleDlg::OnInitDialog()
{
    CDialog::OnInitDialog() ;

    // Add "About..." menu item to system menu.
    // IDM_ABOUTBOX must be in the system command range.
    ASSERT(( IDM_ABOUTBOX & 0xFFF0 ) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu * pSysMenu = GetSystemMenu( FALSE ) ;
    if ( pSysMenu != NULL )
    {
        CString strAboutMenu ;
        strAboutMenu.LoadString( IDS_ABOUTBOX ) ;
        if ( !strAboutMenu.IsEmpty() )
        {
            pSysMenu->AppendMenu( MF_SEPARATOR ) ;
            pSysMenu->AppendMenu( MF_STRING, IDM_ABOUTBOX, strAboutMenu ) ;
        }
    }

    SetIcon( m_hIcon, TRUE ) ;         // Set big icon
    SetIcon( m_hIcon, FALSE ) ;        // Set small icon

    CRect rectListboxes ;
    m_lbSeekTokens.GetWindowRect( rectListboxes ) ;
    int nColWid = rectListboxes.Width() / 3 ;
    m_lbSeekTokens.SetColumnWidth( nColWid ) ;
    m_lbFoundTokens.SetColumnWidth( nColWid ) ;
    m_editSeekTokens.SetFocus() ;

    return false ;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Message Map
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BEGIN_MESSAGE_MAP(CStringSetSampleDlg, CDialog)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_EN_KILLFOCUS(IDC_STRINGS_TO_SEEK, OnKillFocusStringsToSeek)
    ON_BN_CLICKED( IDC_SEARCH, OnSearch )
END_MESSAGE_MAP()

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CStringSetSampleDlg message handlers
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OnKillFocusStringsToSeek
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void CStringSetSampleDlg::OnKillFocusStringsToSeek()
{
    m_lbSeekTokens.ResetContent() ;
    m_setStrings.clear() ;

    CString strTokens ;
    m_editSeekTokens.GetWindowText( strTokens ) ;
    int nCount = m_setStrings.Add( strTokens, _T(", |;") ) ;
    if ( nCount > 0 )
    {
        CIVStringSet::iterator it = m_setStrings.begin() ;
        while ( it != m_setStrings.end() )
        {
            _tstring str = *it++ ;
            m_lbSeekTokens.AddString( str.c_str() ) ;
        }
    }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OnSearch
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void CStringSetSampleDlg::OnSearch()
{
    m_lbFoundTokens.ResetContent() ;

    m_editSearch.GetWindowText( m_strSearch ) ;
    size_t nWord ;
    UINT nPos = m_setStrings.FindFirstIn( static_cast<LPCTSTR>(m_strSearch), nWord ) ;
    if ( nPos != MAXDWORD )
    {
        CString strWord ;
        do
        {
            strWord.Format( _T("%s (%u)"), m_setStrings[nWord].c_str(), nPos ) ;
            m_lbFoundTokens.AddString( strWord ) ;
            nPos = m_setStrings.FindNext( nWord ) ;
        } while ( nPos != MAXDWORD ) ;
    }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OnSysCommand
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void CStringSetSampleDlg::OnSysCommand( UINT nID, LPARAM lParam )
{
    if ( (nID & 0xFFF0) == IDM_ABOUTBOX )
    {
        CAboutDlg dlgAbout ;
        dlgAbout.DoModal() ;
    }
    else
    {
        CDialog::OnSysCommand( nID, lParam ) ;
    }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OnPaint
// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void CStringSetSampleDlg::OnPaint()
{
    if ( IsIconic() )
    {
        CPaintDC dc( this ) ; // device context for painting

        SendMessage( WM_ICONERASEBKGND, (WPARAM)dc.GetSafeHdc(), 0 ) ;

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics( SM_CXICON ) ;
        int cyIcon = GetSystemMetrics( SM_CYICON ) ;
        CRect rect ;
        GetClientRect( &rect ) ;
        int x = (rect.Width() - cxIcon + 1) / 2 ;
        int y = (rect.Height() - cyIcon + 1) / 2 ;

        // Draw the icon
        dc.DrawIcon( x, y, m_hIcon ) ;
    }
    else
    {
        CDialog::OnPaint() ;
    }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OnQueryDragIcon
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HCURSOR CStringSetSampleDlg::OnQueryDragIcon()
{
    return (HCURSOR)m_hIcon ;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Microsoft
United States United States
Scot is a Sr. Escalation Engineer for the Microsoft Developer Support VS & Languages team. He helps software developers who are Microsoft customers find bugs in their own, or Microsoft's, code.

Scot spends most of his time writing, reading, or thinking about C++ software, thereby classifying him as a geek.

Comments and Discussions