A Listbox-like bitmap browser

Description Of Class CTitledPicsWnd

CTitledPicsWnd provides a large-icon-list-view-style
window class with scrolling capabilities, but instead of just
icons it can display bitmaps with titles below. The size of the
‘section’ that each bitmap occupies can be set specifically, or
can be left to find the best fit. ‘Best fit’ means that the
largest bitmap’s width will be used to decide how wide each
section is, and the window will fit as many sections as it can
fit completely across its width. The pictures are then set out on
as many rows as required. If the stretch option is selected, any
smaller bitmaps will be stretched to fit the space of the largest
bitmap. Also, if the section size is set specifically and is
smaller than the largest bitmap, the bitmaps will be stretched or
squashed as necessary. (Note: if the section size is too
small, and the largest bitmap does not fit and stretching is not
selected, the results will be unpredictable – best fit is the
default, and is recommended).

The class supports several methods similar to a CObArray
for adding to, removing from or getting the size of the array of
bitmaps and titles. The bitmaps and titles are handled
simultaneously as if it was one big array.

The class also supports a subset of CListBox / CComboBox
behaviour; you can set the current selection or retrieve it, you
can select items with the left or right mouse buttons, and the
window sends notifications (similar to BN_CLICKED
left-clicking, right-clicking, double-clicking or selection
changing to its parent. The only drawback to the notification
system is that handlers have to be added manually, as detailed

The class accepts either resource IDs of bitmaps (these must
be valid), or pointers to CBitmap objects (these must have
already been loaded – from file, for example). You can mix these
types within the same window. Note that bitmap pointers you add
must not be deleted while the window is showing; they must remain
valid. When the window is destroyed, then you are responsible for
deleting them (the window does not).

Supported Methods:

int Add(CBitmap *pBmp, CString strTitle)
Adds a bitmap pointer and its corresponding title to the array of
bitmaps. The index of the added item is returned.

int Add(UINT uBmpID, CString strTitle)
Adds a bitmap resource ID and its corresponding title to the
array of bitmaps. The index of the added item is returned.

UINT GetSelectedBitmapType(void)
depending on the type of the bitmap that was added at the index
of the currently-selected item. If no item is currently selected,
0 is returned.

UINT GetSelectedBitmapID(void)
Returns the resource ID of the bitmap that was added at the index
of the currently-selected item. If no item is currently selected,
or the bitmap at the selected index was a pointer, 0 is returned.

CBitmap *GetSelectedBitmapPointer(void)
Returns the pointer of the bitmap that was added at the index of
the currently-selected item. If no item is currently selected, or
the bitmap at the selected index was a resource ID, NULL is returned.

CString GetSelectedTitle(void)
Returns the title of the bitmap added at the index of the
currently-selected item. If no item is currently selected, an
empty string is returned.

void SetSel(int iIndex)
Sets the currently-selected item. This can be TPW_NONE to remove the current

int GetSel(void)
Returns the index of the currently-selected item. If no item is
currently selected, TPW_NONE is

void StretchBitmaps(BOOL bStretch = TRUE)
Use this to dictate whether bitmaps are stretched (or shrunk, if
necessary) to fit the allocated section size. The default is FALSE.

void SetSpacing(UINT uSpacing)
Each section has a small amount of space around the outside (this
space is included in the section size). The default is two pixels
either side, top and bottom. Use this method to change this
default. The section size does not change because of this.

UINT GetSize(void)
Returns the number of bitmaps in the window’s array.

void SetSize(UINT uNewSize)
Similar to a CObArray, this sets a size for the array of
bitmaps and titles and is useful if you have a fair number to add
and want to avoid the overhead of the array growing automatically
– you can set the array to be big enough to hold all the items
you will be adding right from the start. Be aware that if you set
the size smaller than the current size, the extra data will be
lost (as with a normal array).

void RemoveAll(void)
Removes all items from the array. Any bitmap pointers which have
been added are NOT deleted – you are responsible for doing that.

void RemoveAt(UINT uIndex, UINT uCount = 1)
Similar to a CObArray, this removes one or more items from
the array, starting at the specified index.

void SetSectionSize(int cx, int cy)
By default, the sections are calculated on a best-fit basis (the
recommended option). Use this method to specifically set the size
of the section. Be aware that if you do not have the stretch
option on and you make the sections too small, the results will
be unpredictable. Note that the spacing is included in the
section size, so you must make allowances for this.

Using CTitledPicsWnd:

  1. In the parent class, embed a member variable which is a pointer
    to a CTitledPicsWnd object. It is important that
    you use a pointer, because CViews (the base class
    of CTitledPicsWnd) delete their wrapper objects
    automatically when the Windows component (the HWND) is destroyed; so, if you
    embed an actual object, you will get an assertion.
  2. In the parent class’ initialisation routine (OnInitDialog() for CDialog-derived,
    OnInitialUpdate() for CViewWM_CREATE) for other CWnd-derived),
    construct the -derived, or OnCreate()
    (generated by adding a handler for CTitledPicsWndfollows:
    object and call its Create()
    method, as

    m_pWndPicList = new CTitledPicsWnd ;
    m_pWndPicList->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
    rctWindow, this, window ID);

The Create() function is the
standard CWnd method; it is left like this in case you
want to supply your own window class, although it is recommended
that you use the default.

To get the rectangle for the window size, it is recommended
that you place a picture control (CStatic) on the dialogue
resource template and use its position and dimensions to create
the rectangle for the CTitledPicsWnd.

Now you can call any other methods you want to set the window
up, and then you can add your bitmaps and their titles. Do not
forget that any resource IDs you pass in must be valid bitmap
resources, and any CBitmap pointers must have been
initialised with a valid bitmap.

CTitledPicsWnd can be used in a dialogue box or in any
other window type.

Handling Notifications From CTitledPicsWnd:

The only drawback with this class and its notification codes
is that you have to add the handlers manually to its parent. Here
is how:

1) In the parent class’ message map (code file), add a line:

window_id, member_function_name)

The notification codes are TPWN_SELCHANGE,
TPWN_CLICK, TPWN_RCLICK and TPWN_DBLCLK, for a change of selection,
a left-click, a right-click and a double-click.

In the parent class’ header file, in the message-map-generated
section, add a line:

afx_msg void member_function_name(void);

Finally, define the function in the parent class’ code file
(without the afx_msg).

Note that the selection change notification occurs both when
the selection is changed using SetSel() and when the mouse is
clicked over a section (either mouse button) – but only if the
new selection is different from the previous selection. Click
notifications occur when the mouse is clicked over a section, no
matter which section was last clicked. The selection always
follows the mouse click (either button).

Using The Demo

When the program is run, select ‘Show’ from the Dialogue Box
menu. As you click each picture (or its associated title, with
either button) the selection change is shown below the window, as
is the type of mouse event. This demonstrates the use of the
notification messages.


Download demo project – 98 Kb

Download source – 5 Kb

More by Author

Must Read