TXListBox - extended ListBox control
====================================

Keywords: LISTBOX,OWNERDRAW,DISABLE,HORIZONTAL,SCROLL,COLOR,LBS,MULTIPLESEL


Description
-----------

OWL 2 listbox control for dialogs (Win16 or Win32)

TXListBox is an owner-draw listbox derived from
TListBox. It provides the following features:

 1. Disabling of selected list items.
 2. Horizontal scrolling.
 3. Dynamic switching between single & multiple selection.
 4. Text colouring of items.

TXCheckedListBox is derived from TXListBox and
provides 'checkbox-style' selection.

TXButtonListBox is derived from TXListBox and
provides 'button-style' multiple selection.

The code illustrates:

1. How to create an owner-draw listbox.
2. One method of disabling items in a listbox.
3. How to implement horizontal scrolling.
4. How to make a multiple-selection list behave
	like a single-selection listbox.
5. How to color text items.
6. Alternative selection styles.

How to use TXListBox
--------------------

Compile and run the example application to see
what facilities are provided.

The controls are intended as drop-in replacements
for existing TListBoxes, eg:

	myList = new TXListBox(this, ID_LIST1, TRUE);

The final BOOL parameter indicates whether the
listbox is to have a horizontal scrollbar
(default: FALSE).

When creating the listbox resource (eg in Resource
Workshop), you must specify the 'Owner Draw Fixed'
and 'Has Strings' attributes.

Additionally, if you wish to be able to dynamically
switch between single & multiple selection mode, the
listbox resource must have the 'multiple select' flag
enabled.

To use TXListBox in your application, you need to
incorporate the following files in your project:

 xlb.cpp  (if using TXListBox)
 xclb.cpp (if using TXCheckedListBox)
 xblb.cpp (if using TXButtonListBox)

Remember to #include the appropriate header files
(xlb.h, xclb.h and xblb.h) where needed.

NB - the xlbapp.*, xlbdlg.* files are only used in the
example application and should not be included in your
project.

Alternatively, you may wish to build a DLL version using
the BUILDXLBDLL define.

Disabling items
---------------

To disable an item in the list use TXListBox::Enable()
like this:

  myList->Enable(0, FALSE);	// disables first item.

To enable all items use:

  myList->Enable(-1, TRUE);	// enables all items.

To determine if an item is disabled, use GetEnabled()
like this:

  if(!myList->GetEnabled(2))
	  {
	  // the third item is disabled.
	  ...
	  }

Switching between multiple & single selection mode
--------------------------------------------------

To change a multiple selection listbox into a single
selection list use:

  myList->MakeSingleSel(TRUE);

Change it back using:

  myList->MakeSingleSel(FALSE);

NB - The method used does _not_ convert the multiple
selection listbox into a native single selection listbox
(This _cannot_ be done by changing Window Style
attributes). It 'fools' the listbox into behaving like
a single selection list. Such a listbox is called a
Pseudo Single Selection list. You can query the mode of
a listbox using GetListBoxMode() which returns one of the
following enums

  SINGLE
	 - A native single selection listbox

  MULTIPLE
	 - A native multiple selection listbox

  PSEUDO_SINGLE
	 - A native multiple selection listbox which
		restricts the user to making single
		selections.

Because a Pseduo Single Selection listbox is _really_
a multiple selection listbox, the TListBox members
that allow you to set and get selections have been
modified as follows:

  - All methods that are designed for single selection
  lists only can also be used for pseudo single
  selection lists.

  - Some methods that are designed for multiple selection
  lists only can still be used for pseudo single
  selection lists but their behaviour may be modified,
  e.g. SetSelIndexes(...) enforces a single selection
  when used in a pseudo single selection listbox.

  - Some methods that are designed for multiple selection
  lists are not to be used for pseduo single selection
  listboxes.


Specifically, the following methods have been modified:

	SetSel(int index, BOOL select)
	 - Can be used with pseudo single selection listboxes
		and enforces single selection, i.e. if you use
		SetSel to select an item in a pseudo single
		selection listbox, any existing selection
		is removed.

		It is an error to select all items (using index == -1)
		in a pseudo single selection listbox.

	SetSelIndexes(int* indexes, int numSelections, BOOL shouldSet)
	 - Can be used with pseudo single selection listboxes
		only to deselect all items (any other operation
		returns LB_ERR).

	SetSelIndex(int index)
	 - Can be used with pseudo single selection listboxes.
		Enforces single selection, i.e. if you use
		SetSelIndex to select an item in a pseudo single
		selection listbox, any existing selection
		is removed.

	SetSelItemRange(BOOL select, int first, int last)
	 - Cannot be used for pseudo single selection listboxes.
		LB_ERR is returned in such cases.

	SetSelString(const char far* str, int searchIndex)
	 - Can be used with pseudo single selection listboxes.

	SetSelStrings(const char far** prefixes, int numSelections, bool shouldSet)
	 - Cannot be used with pseudo single selection listboxes.
		LB_ERR is returned in such cases.

	GetSelIndex()
	 - Can be used with pseudo single selection listboxes.

	GetSelIndexes(int far *indexes, int maxCount)
	 - Can be used with pseudo single selection listboxes.

(When researching the problem of dynamically switching the
selection mode of a listbox, I found this can also be
achieved by creating two listboxes; one single-selection,
the other multiple, and hiding the one that is not required.
                                    - APC)

Colouring items
---------------

Selected items may be coloured using the following
function:

	// make 3rd item white...
	myList->SetTextColor(2, TColor::White);

To change the color of all items at once use:

  myList->SetTextColor(-1, TColor::White);

To reset all item colors to the system default:

  myList->ResetTextColor(-1);


How TXListBox works
-------------------

TXListBox takes control of item drawing and can thus
make an item appear 'disabled'. TListBox::SetDataItem
and TListBox::GetDataItem are overridden so that a
boolean enabled/disabled flag can be stored for each
item. This does not interfere with normal use of these
functions to store other data.

Owner-drawing also allows TXListBox to color the items
in the list. The items' colors are stored in the same
data structure used to hold the boolean enable/disable
flags.

Horizontal scrolling is implemented by storing the
extent of strings added or inserted in the list in a
sorted array of integers.

A TXListBox multiple-selection list can be made to
behave like a single-selection listbox using
MakeSingleSel(). LBN_SELCHANGE is handled so that
whenever the listbox caret moves in a multiple selection
listbox TXListBox ensures that only one item is selected.
Note that LBN_SELCHANGE _is_ passed to the parent but
not as part of the default processing for the original
message.

Technical Support on TXListBox
------------------------------

Any comments, questions or fixes should be addressed
to Antony Corbett at Compuserve: 100277,330

Rights to TXListBox
-------------------

TXListBox is CharityWare. If you make use of the
code in a commercial application and would like
to contribute please send a donation to:

Antony Corbett
1 Ashfield Road
Kenilworth
Warks
CV8 2BE
UK

Compuserve	100277,330
Tel +44 (1926) 856131,  Fax +44 (1926) 856727


