Dec 082017
 
Hierarchical List Box for the Microsoft Foundation Classes (MFC) 2.0.
File HIERLIST.ZIP from The Programmer’s Corner in
Category C++ Source Code
Hierarchical List Box for the Microsoft Foundation Classes (MFC) 2.0.
File Name File Size Zip Size Zip Type
CLOSELEV.CPP 1084 467 deflated
CLOSELEV.H 677 362 deflated
CTL3D.DLL 20272 9507 deflated
CTL3D.H 1386 528 deflated
CTL3D.LIB 2560 531 deflated
DRAGDROP.CPP 634 323 deflated
DRAGDROP.H 719 367 deflated
HIERLB.CPP 13607 4021 deflated
HIERLB.H 2810 1129 deflated
HIERLDOC.CPP 1759 606 deflated
HIERLDOC.H 949 452 deflated
HIERLIST.APS 19335 6045 deflated
HIERLIST.CLW 3327 988 deflated
HIERLIST.CPP 4537 1684 deflated
HIERLIST.DEF 356 242 deflated
HIERLIST.H 857 433 deflated
HIERLIST.MAK 6134 1459 deflated
HIERLIST.RC 10878 2546 deflated
HIERLIST.VCW 312 182 deflated
HIERLIST.WSP 356 144 deflated
HIERLVW.CPP 4601 1594 deflated
HIERLVW.H 1549 660 deflated
LSTBOXEX.CPP 14398 4354 deflated
LSTBOXEX.H 4575 1432 deflated
MAINFRM.CPP 2640 947 deflated
MAINFRM.H 932 458 deflated
README.TXT 6434 2621 deflated
RES 0 0 stored
RESOURCE.H 1578 455 deflated
COPYSING.CUR 326 194 deflated
CUR914.CUR 326 131 deflated
DRAG_MUL.CUR 326 154 deflated
HIERICON.BMP 1126 293 deflated
HIERLDOC.ICO 768 183 deflated
HIERLIST.ICO 768 205 deflated
HIERLIST.RC2 1553 658 deflated
MOVE.CUR 326 177 deflated
MOVEMULT.CUR 326 137 deflated
MOVESING.CUR 326 115 deflated
NODROP.CUR 326 93 deflated
TOOLBAR.BMP 1200 355 deflated
SPLASH.CPP 1188 496 deflated
SPLASH.H 778 420 deflated
STDAFX.CPP 204 128 deflated
STDAFX.H 283 176 deflated
TESTHIER.CPP 4125 1646 deflated
TESTHIER.H 1311 551 deflated
TESTLIST.CPP 2959 1248 deflated
TESTLIST.H 1308 576 deflated

Download File HIERLIST.ZIP Here

Contents of the README.TXT file


This is my second attempt at the following enhancements to list boxes in MFC2.0
The interface has changed since my first attempt - but not that much.

As before we have:-
1) Owner draw list box items using transparent bitmaps
2) Drag and drop - not necessarily between listboxes.
3) Hierarchical listboxes with lines.

There are three main classes

1) CListBoxExResources

This class encapsulates the resources required for a CListBoxEx and prepares
a transparent bitmap into a memory device context for use in drawing the
list box items. (A bug has been fixed in this class. I was storing a temporary
pointer and the passing it to SelectObject on destruction of the object. )

See lstboxex.h for the definition.

The constructor takes resource ids for one bitmap and five cursors, a WORD value
which can be used to indicate the width of individual bitmaps within the larger
bitmap and two COLORREF items which describe the background colours of the bitmap.

The bitmap must be a two high bitmap as shown below:-

Single large bitmap made up of two identical rows of bitmaps which you are going to use
in your listboxes.
+---+---+---+---+---+
| | | | | | Background of this row is blue = RGB(0,0,255)
| | | | | |
+---+---+---+---+---+
| | | | | | Background of this row is magenta = RGB(255,0,255)
| | | | | |
+---+---+---+---+---+

CListBoxExResources copies this bitmap into a memory DC and transforms it
so that the bottom row has
the background colour COLOR_WINDOW and the top row colour COLOR_HIGHLIGHT.

A CListBoxExResources object should be declared in say your CMainFrame object
and passed to any CListBoxEx objects you declare.

The OnSysColorChange handler should be added to CMainFrame and
m_Resources.SysColorChanged() called from there.
This regenerates the bitmap with the correct background colours.


2) CListBoxEx

Create a CListBoxEx with LBS_OWNERDRAWVARIABLE.

This is an abstract base class - you must derive from it and override the virtual function

void CListBoxEx::DrawItemEx( const CListBoxExDrawStruct& )

where the class CListBoxExDrawStruct is as follows.

class CListBoxExDrawStruct
{
public:
const CListBoxExResources* m_pResources;
CDC* m_pDC;
CRect m_Rect;
BOOL m_Sel;
DWORD m_ItemData;
};

Use this to draw your list box item or override DrawItem(DRAWITEMSTRUCT) and do it all
yourself.

The function CListBox::DrawItem( DRAWITEMSTRUCT ) has been overridden and calls
DrawItemEx after preparing various things.

These functions can be overridden to provide drag and drop functionality

virtual void DroppedItemsOnWindowAt( CWnd*, const CPoint&, BOOL bCopy=FALSE ){}
virtual BOOL CanDrop( CWnd*, const CPoint&, BOOL bCopy=FALSE ) { return FALSE; }

This function has been added since version 1.
I have added it in case a derived class wishes to customize the
cursors used during drag/drop operations for each individual listbox.
If the function returns NULL (as the default case does) then the cursors
from the attached CListBoxExResource object are used.

virtual HCURSOR GetCursor( eLbExCursor ) const { return HCURSOR(NULL); }

If you call CListBoxEx::EnableDragDrop(TRUE) then you can drag items from the CListBoxEx
object. As the mouse moves the function CanDrop is called with a pointer to the
targer CWnd, the mouse point in client co-ords and the drag operation copy or move.

When the mouse is release over a drag client then the function DroppedItemsOnWindowAt is
called with the same pararameters. It is up to the user to provide these functions. See
CTestListEx for an example.

Items are added to a CListBoxEx using AddString( (LPCSTR)item ) etc.

3) CHierListBox

This is derived from CListBoxEx and inherits all of it's functionality. It adds
the ability to display items hierarchically like file mananger.

This interface to this class has changed substantially.

This is an abstract base class - derive and override these functions

void CListBoxEx::DrawItemEx( CListBoxExDrawStruct& ds );
The ds.m_Rect has been adjusted for indentation so just BitBlt a bitmap and
draw some text.

This is now const ---------------------+
BOOL CHierListBox::OpenNode( const CHierListNode*, int& nodeIndex )
This is called when the used double clicks on a closed node.
The derived class should open the node if possible by inserting
new items using InsertNode( DWORD item, const CHierListNode* parentNode, int index )
and on return indicate TRUE/FALSE for ability to open node.
If items have been inserted then the return value of InsertNode for the last child item should be
returned in nodeIndex.

These are used to request the opening or closing of particular nodes.
BOOL CloseToLevel(unsigned int=0);
BOOL CloseAll();
BOOL CloseNode(int);
BOOL DeleteNode(int);
BOOL OpenNode(int);
OpenNode(int) will in turn call OpenNode( const HeirListNode*, int& ) but will ensure
that the lines are drawn correctly.

This can be used to insert indivual items. This still needs some work.
int InsertNode(DWORD, const CHierListNode*, int index=-1);

Use these to enable disable the lines
void EnableLines(BOOL);
BOOL LinesEnabled() const { return m_bLines; }

It is possible that CHierListBox could support sorting of items but this is more
difficult than usual so it's up to you if you want this feature.

If you override CHierListBox::DeleteItem for CHierListBox then make sure you delete
your data first and then call the parent class version.

Test app
--------
The test application demonstrates all of the capabilities of the list boxes.
Try dragging from the right list box to the left. You might get assert failures
but these can be ignored for demonstration purposes.

The about box demonstrates subclassing the listboxes. Items can be dragged
from the about box to another instance of the app.

Outstanding problems
--------------------
If items are dragged from the right hand listbox in the about box to the
right hand listbox of another instance of the app then an AfxMessageBox appears.
I call ReleaseCapture before sending the WM_DROP message but the mouse cursor is
lost - hitting Escape sorts things out. Any help with this would be appreciated.

CHierListBox::InsertNode needs more work .

Comments to:-

Philip Lee 100065,3244


 December 8, 2017  Add comments

Leave a Reply