Files

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());
}