Using a Right Button in a ListBox

Introduction

Every list box has the select function implemented whenever you implement the left-button clicked handler. If you want to use the right-button handler to perform an operation on a list box item, you would have to select the item with the left button, then use the right button. This is not very convenient, so we will implement a right-button handler that first selects the item pointed to at the time of the right-button click, then forwards the message that the right button has been clicked. To create a listbox with right button selecting, use ClassExpert to create a new TListBox Class. Use the following settings in the Window Style dialog box.

Modification to Code Generated by ClassExpert

Most of the code for this window is created by ClassExpert either when you create the class or by the techniques in the following sections. One simple addition to the code is a second constructor. This is the standard

RightButtonListBox(TWindow* parent, int resourceId, TModule* module = 0);
constructor used by may applications. The code for this constructor is boiler plate. Just call on the TListBox constructor with the same parameters then copy the body of the other constructor (provided by ClassExpert) and insert into your new constructor. Here is a sample of such a constructor.

RButtonListBox::RButtonListBox (TWindow* parent, int resourceId, TModule* module)
	:TListBox(parent,resourceId,module)
{
	 // Override the default window style for TListBox.
	 Attr.Style |= WS_CHILD | WS_VISIBLE | WS_VSCROLL;
	 Attr.Style &= ~(WS_BORDER | WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);

	 // INSERT>> Your constructor code here.

}

Find The Selected Item From The Point at Click Time

To find out which item in the list box is selected given the point of selection, you must find out the index of the item at the top of the box (in case the scolling moves to a point where the first item is not visible). The function GetTopIndex tells which item is at the top of the listbox. The height of each listbox item is determined by calling GetItemHeight. We know that the y-coordinate of the top is 0, so we set pos to 0, then start adding the height of successive items to pos, until pos is larger than the y coordinate of the selected point (point.y). The index is now one larger than the one that should be selected, so decrement the index and use SetSelIndex to set the selection.

void RightButtonListBox::setSelectIndex(TPoint &point)
{
    //Must convert the coordinates to screen or local
     int index = GetTopIndex(); //the index at the top of the window
     int pos = 0; // y position of each index item
     while (pos < point.y) // current index is not the selected one
     {
        pos += GetItemHeight(index++); //get next list position
     }
     SetSelIndex(index-1); // found it so select it
}

Once the item is selected, we simply forward the message that the right button is down to the parent where all of the work is done.

void RightButtonListBox::EvRButtonDown (uint modKeys, TPoint& point)
{
    TListBox::EvRButtonDown(modKeys, point);

    // INSERT>> Your code here.    
     setSelectIndex(point);
     Parent->PostMessage(WM_RBUTTONDOWN);
}

A right-button listbox is useful in many problems, which is why we have implemented a DLL for it.

Using The RightButtonListBox

When you have an application that uses a TListBox, all you need to do to make it into a RightButtonListBox is substitute RightButtonListBox for TListBox whereever the ListBox is created. All constructors for TListBox correspond to constructors for RightButtonListBox. RightButtonListBox is a descendent of TListBox, so any pointer to a RightButtonListBox can be stored in a TListBox* variable.

Right-Button Listbox as a DLL

Click here to get a dll implementation of a right-botton listbox.