Virtual Developer Workshop: Containerized Development with Docker
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 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).
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.
Returns TPW_BITMAPTYPE_RESOURCE or TPW_BITMAPTYPE_OBJECT 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.
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.
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.
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 selection.
Returns the index of the currently-selected item. If no item is currently selected, TPW_NONE is returned.
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.
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).
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.
- 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.
- 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()
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:
ON_CONTROL(notification_code, 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.