Introduction
Under some circumstances, we needed a combobox to display a list of items for the user to select. These items are stored in a dictionary with an identity code. Especially if you are using a database, user reads the content in the dropdown list box with meaning; but it also needs to return a code for that item. This control simplifies the selection while you are using XML.
Implementation of Dictionary
I posted a XML DOM wrapper last time , in which, I wrapped a CXMLFile
class to parse and make it is easy for using XML. Here I wrote another wrapper to represent the dictionary using CXMLFile
. If you cannot find the base class of this example, you will find that class in the source code of the article "Wrapper class for DOM interface of windows SDK".
The dictionary has the following format.
="1.0" ="gb2312"
<dicts> <dictionary>card_type
<class_id>1</class_id> <dictitem> <code>0</code>
<itemname>normal</itemname> </dictitem> <dictitem>
<code>1</code> <itemname>abnormal</itemname> </dictitem>
<dictitem> <code>2</code> <itemname>another</itemname>
</dictitem> </dictionary> </dicts>
The dictionary contains items with a code . They will be displayed in the combobox. The combobox will automatically fill by itself. We derive a new class from CXMLFile
to solve the problem. The dictionary class includes the method for searching and other methods to maintain a dictionary by user. The following is the header for this class.
class CXMLDict : public CXMLFile
{
public:
BOOL GetDictItem ( IXMLDOMNode * node , int code , CString &item);
BOOL GetNumOfDicts(long &len);
BOOL GetNumOfItems( IXMLDOMNode * dict, long &num);
BOOL GetDictItem(IXMLDOMNode *dict,int i, long &code, CString & item);
BOOL GetDictClass( IXMLDOMNode * dict, long & id );
BOOL AddDictItem(IXMLDOMNode *dict, long id , const CString & name);
BOOL AddDictionary(const CString & name , const CString &cls,
IXMLDOMNode **dicts);
BOOL LoadStrDictionarys(const CString &xmlDicts);
BOOL LoadDictionarys( const CString & strPath);
BOOL FindDicts();
IXMLDOMNode * m_pDicts;
BOOL InitDicts();
BOOL GetDict(const CString &strDict, IXMLDOMNode **node);
CXMLDict();
virtual ~CXMLDict();
};
Producing the comboxbox
In order to using the dictionary construct from above , we derive a new combobox class from CComboBox
as base control. The Combobox is filled from given dictionary. The user can select the item by item code in dictionary. The new combobox will return the currently selected item's item code automatically. The following prototype definition explains the implementation of this class.
class CDictComboBox : public CComboBox
{
public:
CDictComboBox();
virtual ~CDictComboBox();
BOOL GetSelData(long &data);
long FindItemByData( long data);
BOOL SelectItemByData( long data);
BOOL LoadDict( const CString & name , CXMLDict *dict);
};
Under most circumstances, the combobox is used in a dialog or form . It is better to provide a Data Exchange function for this new combobox.
void PASCAL DDX_CBDictData( CDataExchange * pDX, int nIDC, long & data)
{
CDictComboBox * box = (CDictComboBox*) CWnd::FromHandle (
pDX->PrepareCtrl(nIDC));
if ( pDX->m_bSaveAndValidate )
{
data= CB_ERR;
box->GetSelData (data);
}
else
{
box->SelectItemByData (data);
}
}
Usage
To use this class is very simple. Create a new dialog template as usually. Declare a variable that will accept the return code . Add a line of DDX in DoDataExchange
for controlling the value. And fill the combobox using dictionary in the OnInitDialog
function. Hope this will help you. Thank you .