339 lines
12 KiB
C
339 lines
12 KiB
C
|
/***************************************************************************/
|
||
|
/** Microsoft Windows **/
|
||
|
/** Copyright(c) Microsoft Corp., 1993 **/
|
||
|
/***************************************************************************/
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
ICONLBOX.H
|
||
|
|
||
|
Header file for IconListBox class (hard tabs at 4)
|
||
|
|
||
|
May 93, JimH (combobox support added by VladS)
|
||
|
|
||
|
IconListBox is constructed by specifying the application's hInst and
|
||
|
the ID of the listbox control. All the properties of the listbox (font,
|
||
|
single or muliple selection, etc.) are defined in the .RC file. It must
|
||
|
include the LBS_OWNERDRAWFIXED style.
|
||
|
|
||
|
Icons are really bitmaps or parts of bitmaps. They must all be the same
|
||
|
size. If they are not 16 by 16 this size must be specified in the
|
||
|
constructor. By default, bright green (RGB(0,255,0)) is the transparent
|
||
|
color but this can be overridden for each individual icon.
|
||
|
|
||
|
Construction of the IconListBox object should occur when the dialog is
|
||
|
created. You cannot wait until WM_INITDIALOG time because you need to
|
||
|
handle the WM_MEASUREITEM message which comes first by passing to the
|
||
|
constructed IconListBox. Similarly, the IconListBox cannot be destructed
|
||
|
during OK or Cancel handling because you will have to handle subsequent
|
||
|
WM_DRAWITEM messages.
|
||
|
|
||
|
Follow these steps to use IconListBox (assumes 16 by 16 icons)
|
||
|
|
||
|
1. Construct IconListBox(hInst, IDC_MYLISTBOX);
|
||
|
|
||
|
2. Handle WM_MEASUREITEM by calling
|
||
|
|
||
|
mylistbox->SetHeight(hwndDlg, (MEASUREITESTRUCT FAR *)lParam);
|
||
|
|
||
|
You MUST do this step even if you are using the default height of 16
|
||
|
pixels.
|
||
|
|
||
|
3. During WM_INITDIALOG processing, register each possible icon by
|
||
|
specifying your internal identifier for this icon, a bitmap id, and
|
||
|
if necessary, the x and y offset in the bitmap of this icon.
|
||
|
Don't load the bitmap yourself. Just pass the .RC file id.
|
||
|
|
||
|
mylistbox->RegisterIcon(typeFission, IDB_MushroomCloud);
|
||
|
|
||
|
Note that you can register several icons from the same .RC file
|
||
|
bitmap. These may or may not have different x and y offsets but
|
||
|
they must all have the same transparent color. There is no
|
||
|
extra overhead associated with reusing bitmaps or parts of bitmaps.
|
||
|
|
||
|
4 Also during WM_INITDIALOG, add the listbox entries.
|
||
|
|
||
|
mylistbox->AddString(typeColdFusion, "Pons & Fleishman");
|
||
|
|
||
|
5. Handle the WM_DRAWITEM message by calling
|
||
|
|
||
|
if (wParam == IDC_MYLISTBOX)
|
||
|
mylistbox->DrawItem((DRAWITEMSTRUCT FAR *)lParam);
|
||
|
|
||
|
6. When handling OK, do whatever listbox stuff you have to do.
|
||
|
|
||
|
n = mylistbox->GetCurrentSelection();
|
||
|
mylistbox->GetString(n, pbuffer);
|
||
|
|
||
|
7. Destruct IconListBox
|
||
|
|
||
|
Inline wrappers for common listbox functions are at the end of this file.
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
#ifndef _ICONLBOX_H_
|
||
|
#define _ICONLBOX_H_
|
||
|
|
||
|
struct IconList {
|
||
|
int nID; // ID icon was registered with
|
||
|
int nResID; // .RC file resource ID
|
||
|
int x, y; // offset within specified icon
|
||
|
HBITMAP hbmSelected;
|
||
|
HBITMAP hbmUnselected;
|
||
|
};
|
||
|
|
||
|
const int MAXICONS = 10; // max number that can be registered
|
||
|
const int MAXTABS = 10; // max number of tabs in string
|
||
|
const int MAXSTRINGLEN = MAX_PATH; // AddString and InsertString limit
|
||
|
const int ICONSPACE = 3; // whitespace around Icons in listbox
|
||
|
|
||
|
class IconListBox {
|
||
|
|
||
|
public:
|
||
|
IconListBox(HINSTANCE hInst, int nID,
|
||
|
int iconWidth = 16, int iconHeight = 16);
|
||
|
~IconListBox();
|
||
|
|
||
|
int AddString(int nIcon, const char far *string);
|
||
|
void Clear();
|
||
|
void DeleteString(int nIndex);
|
||
|
virtual void DrawItem(LPDRAWITEMSTRUCT lpd);
|
||
|
int FindString(const char far *string, int nIndexStart = -1) const;
|
||
|
int FindStringExact(const char far *string, int nIndexStart = -1) const;
|
||
|
int GetCount();
|
||
|
int GetCurrentSelection(void) const;
|
||
|
int GetIconID(int nIndex) const;
|
||
|
BOOL GetSel(int nIndex);
|
||
|
int GetSelCount() const;
|
||
|
int GetSelItems(int cItems, int FAR *lpItems) const;
|
||
|
int GetString(int nIndex, char far *string) const;
|
||
|
int InsertString(int nIcon, const char far *string, int nIndex);
|
||
|
void RegisterIcon(int nIconID, int nResID, int x=0, int y=0,
|
||
|
COLORREF colTransparent = RGB(0, 255, 0));
|
||
|
int SelectString(int nIndex, const char far *string);
|
||
|
int SetCurrentSelection(int nIndex = -1) const;
|
||
|
void SetHeight(HWND hwndDlg, LPMEASUREITEMSTRUCT lpm, int height=16);
|
||
|
void SetRedraw(BOOL bRedraw = TRUE) const;
|
||
|
void SetSel(int nIndex, BOOL bSelected = TRUE) const;
|
||
|
void SetTabStops(int cTabs, const int *pTabs);
|
||
|
|
||
|
protected:
|
||
|
int SetItemData(int nIndex, int nIconID) const;
|
||
|
int UpdateHorizontalExtent(int nIconID,const char *string);
|
||
|
|
||
|
int _cIcons; // number of icons registered
|
||
|
IconList _aIcons[MAXICONS]; // registered icons
|
||
|
int _cTabs; // number of tabs registered
|
||
|
int _aTabs[MAXTABS]; // registered tabs
|
||
|
int _iconWidth, _iconHeight; // size of icons
|
||
|
int _iCurrentMaxHorzExt; // Currently maximum horizontal extent
|
||
|
|
||
|
COLORREF _colSel, _colSelText, _colUnsel, _colUnselText;
|
||
|
|
||
|
HINSTANCE _hInst; // application's hInst
|
||
|
int _nCtlID; // id of listbox control
|
||
|
int _nTextOffset; // vertical DrawText offset
|
||
|
|
||
|
BOOL _fCombo; // Dropdown combo box ?
|
||
|
|
||
|
HWND _hwndDialog;
|
||
|
HWND _hwndListBox;
|
||
|
|
||
|
HBRUSH _hbrSelected; // background colours
|
||
|
HBRUSH _hbrUnselected;
|
||
|
};
|
||
|
|
||
|
|
||
|
// AddString - returns index of new string, or LB_ERR or LB_ERRSPACE
|
||
|
|
||
|
inline int IconListBox::AddString(int nIcon, const char far *string)
|
||
|
{
|
||
|
int nIndex = (int) ::SendDlgItemMessage(_hwndDialog, _nCtlID,
|
||
|
_fCombo ? CB_ADDSTRING : LB_ADDSTRING,
|
||
|
0, (LPARAM) ((LPSTR) string));
|
||
|
SetItemData(nIndex, nIcon);
|
||
|
UpdateHorizontalExtent(nIcon,string);
|
||
|
|
||
|
return nIndex;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Clear - clears contents of listbox
|
||
|
|
||
|
inline void IconListBox::Clear()
|
||
|
{
|
||
|
::SendMessage(_hwndListBox,
|
||
|
_fCombo ? CB_RESETCONTENT : LB_RESETCONTENT, 0, 0);
|
||
|
|
||
|
_iCurrentMaxHorzExt = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
// DeleteString - removes a string specified by the index
|
||
|
|
||
|
inline void IconListBox::DeleteString(int nIndex)
|
||
|
{
|
||
|
::SendMessage(_hwndListBox,
|
||
|
_fCombo ? CB_DELETESTRING : LB_DELETESTRING, nIndex, 0);
|
||
|
|
||
|
// May be horizontal extent changed - recalculate again
|
||
|
UpdateHorizontalExtent(0,NULL);
|
||
|
|
||
|
}
|
||
|
|
||
|
// FindString & FindStringExact
|
||
|
//
|
||
|
// These functions find a listbox entry that begins with the characters
|
||
|
// specifed in string (FindString) or exactly matches string (FindStringExact)
|
||
|
// They return LB_ERR if the string is not found. Otherwise, you can call
|
||
|
// GetString on the returned index.
|
||
|
//
|
||
|
// nIndexStart defaults to -1 which means search from the beginning of the
|
||
|
// listbox or combobox.
|
||
|
|
||
|
inline int IconListBox::FindString(const char far *string, int nIndexStart) const
|
||
|
{
|
||
|
return (int) ::SendDlgItemMessage(_hwndDialog, _nCtlID,
|
||
|
_fCombo ? CB_FINDSTRING : LB_FINDSTRING, nIndexStart, (LPARAM)string);
|
||
|
}
|
||
|
inline int IconListBox::FindStringExact(const char far *string, int nIndexStart) const
|
||
|
{
|
||
|
return (int) ::SendDlgItemMessage(_hwndDialog, _nCtlID,
|
||
|
_fCombo ? CB_FINDSTRINGEXACT : LB_FINDSTRINGEXACT,
|
||
|
nIndexStart, (LPARAM)string);
|
||
|
}
|
||
|
|
||
|
// GetCount - returns the current number of listbox entries
|
||
|
|
||
|
inline int IconListBox::GetCount()
|
||
|
{
|
||
|
return (int) ::SendMessage(_hwndListBox,
|
||
|
_fCombo ? CB_GETCOUNT : LB_GETCOUNT, 0, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
// GetCurrentSelection - returns index or LB_ERR if no selection.
|
||
|
// This function is not useful for multi-select listboxen.
|
||
|
|
||
|
inline int IconListBox::GetCurrentSelection() const
|
||
|
{
|
||
|
return (int) ::SendMessage(_hwndListBox,
|
||
|
_fCombo ? CB_GETCURSEL : LB_GETCURSEL, 0, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
// GetItemData - retrieve ICON id
|
||
|
|
||
|
inline int IconListBox::GetIconID(int nIndex) const
|
||
|
{
|
||
|
return (int) ::SendMessage(_hwndListBox,
|
||
|
_fCombo ? CB_GETITEMDATA : LB_GETITEMDATA, nIndex, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
// GetSel - returns nonzero if nIndex is selected
|
||
|
|
||
|
inline BOOL IconListBox::GetSel(int nIndex)
|
||
|
{
|
||
|
return (BOOL) ::SendMessage(_hwndListBox, LB_GETSEL, nIndex, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
// GetSelCount - returns number of selected entries in multi-select listbox
|
||
|
|
||
|
inline int IconListBox::GetSelCount() const
|
||
|
{
|
||
|
return (int) ::SendMessage(_hwndListBox, LB_GETSELCOUNT, 0, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
// GetSelItems - places index of each selected item in array. Returns
|
||
|
// LB_ERR if not multi-select listbox, otherwise number of items in array.
|
||
|
|
||
|
inline int IconListBox::GetSelItems(int cItems, int FAR *lpItems) const
|
||
|
{
|
||
|
return (int)
|
||
|
::SendMessage(_hwndListBox, LB_GETSELITEMS, cItems, (LPARAM) lpItems);
|
||
|
}
|
||
|
|
||
|
|
||
|
// GetString - returns length of string returned or LB_ERR if nIndex invalid
|
||
|
|
||
|
inline int IconListBox::GetString(int nIndex, char far *string) const
|
||
|
{
|
||
|
return (int) ::SendDlgItemMessage(_hwndDialog, _nCtlID,
|
||
|
_fCombo ? CB_GETLBTEXT : LB_GETTEXT, nIndex,
|
||
|
(LPARAM) ((LPSTR) string));
|
||
|
}
|
||
|
|
||
|
|
||
|
// InsertString - same returns as AddString
|
||
|
|
||
|
inline int IconListBox::InsertString(int nIcon, const char far *string, int nIndex)
|
||
|
{
|
||
|
int nNewIndex = (int) ::SendDlgItemMessage(_hwndDialog, _nCtlID,
|
||
|
_fCombo ? CB_INSERTSTRING : LB_INSERTSTRING,
|
||
|
(WPARAM) nIndex, (LPARAM) ((LPSTR) string));
|
||
|
|
||
|
SetItemData(nNewIndex, nIcon);
|
||
|
UpdateHorizontalExtent(nIcon,string);
|
||
|
|
||
|
return(nNewIndex);
|
||
|
}
|
||
|
|
||
|
|
||
|
// SelectString
|
||
|
// nIndex specifies where to start searching (-1 means from top).
|
||
|
// string specifies the initial characters of the string to match.
|
||
|
// Function returns index or LB_ERR if string not found
|
||
|
|
||
|
inline int IconListBox::SelectString(int nIndex, const char far *string)
|
||
|
{
|
||
|
return (int) ::SendMessage(_hwndListBox,
|
||
|
_fCombo ? CB_SELECTSTRING : LB_SELECTSTRING,
|
||
|
nIndex,(LRESULT)string);
|
||
|
}
|
||
|
|
||
|
|
||
|
// SetCurrentSelection -
|
||
|
// This function sets the current selection in a single-select style
|
||
|
// listbox. It returns LB_ERR if an error occurs, or if nIndex is -1
|
||
|
// (the default) meaning no current selection.
|
||
|
|
||
|
inline int IconListBox::SetCurrentSelection(int nIndex) const
|
||
|
{
|
||
|
return (int) ::SendMessage(_hwndListBox,
|
||
|
_fCombo ? CB_SETCURSEL : LB_SETCURSEL, nIndex, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
// SetItemData - used to store icon id, returns LB_ERR if error occurs
|
||
|
// Use GetIconID to retrieve this id later.
|
||
|
|
||
|
inline int IconListBox::SetItemData(int nIndex, int nData) const
|
||
|
{
|
||
|
return (int) ::SendMessage(_hwndListBox,
|
||
|
_fCombo ? CB_SETITEMDATA : LB_SETITEMDATA,
|
||
|
nIndex, nData);
|
||
|
}
|
||
|
|
||
|
|
||
|
// SetRedraw - turn on (TRUE) or off (FALSE) visual updates
|
||
|
|
||
|
inline void IconListBox::SetRedraw(BOOL bRedraw) const
|
||
|
{
|
||
|
::SendMessage(_hwndListBox, WM_SETREDRAW, bRedraw, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
// SetSel - used in multiselect listboxen. TRUE selects, FALSE deselects.
|
||
|
// bSelected defaults to TRUE. nIndex == -1 means select all.
|
||
|
|
||
|
inline void IconListBox::SetSel(int nIndex, BOOL bSelected) const
|
||
|
{
|
||
|
::SendMessage(_hwndListBox, LB_SETSEL, bSelected, nIndex);
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif // _ICONLBOX_H_
|