283 lines
6.4 KiB
C++
283 lines
6.4 KiB
C++
// gzListBox.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "sp.h"
|
|
#include "gzListBox.h"
|
|
#include <crtdbg.h>
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CgzListBox
|
|
|
|
CgzListBox::CgzListBox()
|
|
{
|
|
plist = new CStringList[2];//2 column string list
|
|
|
|
//default is multi select
|
|
//FUTURE: programatically determine if single or multi
|
|
m_bSingleSelect=false;
|
|
|
|
|
|
m_nSelectionCount=0;
|
|
//Color related code
|
|
m_clrText = RGB( 0, 0, 0 );
|
|
//get the background color so it will not
|
|
//look like an editable control and more like a
|
|
//chooser control
|
|
m_clrBkgnd = GetSysColor(COLOR_3DFACE);
|
|
m_brBkgnd.CreateSolidBrush( GetSysColor(COLOR_3DFACE) );
|
|
|
|
|
|
//font related code
|
|
::GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT),sizeof(m_lf),&m_lf);
|
|
m_lf.lfWeight = FW_SEMIBOLD ;//FW_MEDIUM,FW_SEMIBOLD,FW_BOLD,FW_BLACK
|
|
m_font.DeleteObject();
|
|
BOOL bCreated = m_font.CreateFontIndirect(&m_lf);
|
|
|
|
ASSERT(bCreated);
|
|
}
|
|
|
|
CgzListBox::~CgzListBox()
|
|
{
|
|
delete[] plist;
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CgzListBox, CListBox)
|
|
//{{AFX_MSG_MAP(CgzListBox)
|
|
ON_WM_CTLCOLOR_REFLECT()
|
|
ON_CONTROL_REFLECT(LBN_KILLFOCUS, OnKillfocus)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CgzListBox message handlers
|
|
//*********************** Add a row ******************
|
|
void CgzListBox::AddRow(CString text, CString ID)
|
|
{
|
|
SetFont(&m_font,FALSE);
|
|
//add the visible text part and use the return value
|
|
//to place the id number in the list of pointers
|
|
//since were using the ID number returned by the combo
|
|
//it's irrelevant whether the combo is in sort mode or not
|
|
int x=AddString(text);
|
|
|
|
if(x==0)
|
|
{
|
|
plist[0].AddHead(text);
|
|
plist[1].AddHead(ID);
|
|
}
|
|
else
|
|
if(x == (GetCount()-1))
|
|
{
|
|
plist[0].AddTail(text);
|
|
plist[1].AddTail(ID);
|
|
}
|
|
else
|
|
{
|
|
plist[0].InsertBefore(plist[0].FindIndex(x), text);
|
|
plist[1].InsertBefore(plist[1].FindIndex(x), ID);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//******************************************************
|
|
//clear the list box completely
|
|
//remove all strings
|
|
void CgzListBox::Clear()
|
|
{
|
|
ResetContent();
|
|
plist[0].RemoveAll();
|
|
plist[1].RemoveAll();
|
|
m_nSelectionCount=0;
|
|
|
|
|
|
}
|
|
|
|
HBRUSH CgzListBox::CtlColor(CDC* pDC, UINT nCtlColor)
|
|
{
|
|
pDC->SetTextColor( m_clrText ); // text
|
|
pDC->SetBkColor( m_clrBkgnd ); // text bkgnd
|
|
return m_brBkgnd;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
//**************************************************************
|
|
//return selected item in range of 0 to number of items selected
|
|
//passed integer is irrelevant on a single select
|
|
CString CgzListBox::GetSelectedItem(int nItem)
|
|
{
|
|
//return hidden value of item number nItem
|
|
//or zero if failed
|
|
if(!m_bIsSingleSelect)
|
|
return plist[1].GetAt(plist[1].FindIndex(aryListBoxSel.GetAt(nItem)));
|
|
|
|
//or if it's single select do this:
|
|
int x=GetCurSel();
|
|
if(x!=LB_ERR)
|
|
return plist[1].GetAt(plist[1].FindIndex(x));
|
|
//failing that return nothing
|
|
return "";
|
|
}
|
|
|
|
|
|
//return "visible" column item # nItem
|
|
CString CgzListBox::GetSelectedItemVisible(int nItem)
|
|
{
|
|
//return visible value of item number nItem
|
|
//or empty if failed
|
|
if(!m_bIsSingleSelect)
|
|
return plist[0].GetAt(plist[0].FindIndex(aryListBoxSel.GetAt(nItem)));
|
|
|
|
//or if it's single select do this:
|
|
int x=GetCurSel();
|
|
if(x!=LB_ERR)
|
|
return plist[0].GetAt(plist[0].FindIndex(x));
|
|
//failing that return nothing
|
|
return "";
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//user has tabbed off of the list box
|
|
//rebuild the index list
|
|
void CgzListBox::OnKillfocus()
|
|
{
|
|
|
|
RebuildIndex();
|
|
}
|
|
|
|
|
|
//returns the number of selected items in the list box
|
|
int CgzListBox::SelectionCount()
|
|
{
|
|
|
|
//Get the count of selected items in the list box
|
|
m_nSelectionCount=GetSelCount();
|
|
|
|
//single select modification:
|
|
if(m_nSelectionCount==LB_ERR)//means it's a single select
|
|
{
|
|
m_bIsSingleSelect=true;
|
|
m_nSelectionCount=GetCurSel();
|
|
|
|
//see if there is a selection
|
|
if(m_nSelectionCount==LB_ERR)//means none
|
|
m_nSelectionCount=0;
|
|
else
|
|
m_nSelectionCount=1;//one item selected
|
|
}
|
|
else
|
|
m_bIsSingleSelect=false;
|
|
return m_nSelectionCount;
|
|
}
|
|
|
|
|
|
//Select or de-select an item given it's hidden
|
|
//ID column - programatically.
|
|
bool CgzListBox::Select(CString ID, bool bSelect)
|
|
{
|
|
//finds row that matches ID and selects or deselects it
|
|
//There might be a simpler way but I could not find it
|
|
//because stringlist objects do not appear to have
|
|
// a function that returns an index of a given
|
|
// item. They do return POSITION types but according
|
|
// to the docs that is not to be considered an index
|
|
// value in any way.
|
|
|
|
|
|
|
|
//assert on an empty ID string if in debug mode
|
|
_ASSERTE(!ID.IsEmpty());
|
|
|
|
//handle an empty ID string in release mode
|
|
if(ID.IsEmpty())
|
|
return false;
|
|
|
|
int x;
|
|
POSITION pos;
|
|
//if the list is empty, return
|
|
if(plist[1].IsEmpty()==TRUE) return false;
|
|
|
|
//set x to the number of items in the list
|
|
x=plist[1].GetCount();
|
|
|
|
//bail if there is nothing in the list
|
|
if(x==0) return false;
|
|
|
|
//iterate through the list comparing the id
|
|
//string at each y index location to the passed ID value
|
|
//upon a match we know that y is the index value in the
|
|
//combo box that matches the ID value passed to this function
|
|
|
|
for(int y=0;y<x;y++)
|
|
{
|
|
|
|
//will assert if invalid id attempted
|
|
|
|
pos=plist[1].FindIndex(y);
|
|
|
|
_ASSERTE(pos!=NULL);
|
|
|
|
if(pos==NULL)
|
|
return false;
|
|
|
|
if(ID==plist[1].GetAt(pos))
|
|
{
|
|
if(m_bSingleSelect)
|
|
SetCurSel(y);
|
|
else
|
|
SetSel(y,bSelect ? TRUE:FALSE);//found a match, set the combo to it
|
|
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
//this is required to build the selection list
|
|
//either called by killfocus or called by the
|
|
//owner window after a double click to fill the list
|
|
//that way.
|
|
void CgzListBox::RebuildIndex()
|
|
{
|
|
//set the m_nSelectionCount variable
|
|
//and the m_bIsSingleSelect flag
|
|
SelectionCount();
|
|
|
|
//only proceed if it's a multiple select
|
|
//otherwise the index is irrelevant
|
|
if(m_bIsSingleSelect) return;
|
|
|
|
//clear out any previous values
|
|
aryListBoxSel.RemoveAll();
|
|
|
|
//bail if there is nothing to set
|
|
if(m_nSelectionCount==0)
|
|
return;
|
|
|
|
//size the array to the number of selected items
|
|
aryListBoxSel.SetSize(m_nSelectionCount);
|
|
|
|
GetSelItems(m_nSelectionCount, aryListBoxSel.GetData());
|
|
|
|
}
|
|
|
|
|