A generic Tree Property Sheet control
Posted
by Alexander Berthold
on July 25th, 1999

CTreePropertySheet
This class implements a generic tree property control (see picture above).Its features are:
- Supports variable width tree control
- Autosizing depending on the size of the dialogs contained
- As this version is now based upon the CPropertySheet/ CPropertyPage model, all features of these are available.
- Various styles(for example, like Netscape Communicator's property sheet)
- Extensibility: Allows to integrate user defined controls (like buttons or static text boxes) and easily position them.
- Now supports modeless property sheets as well.
How to implement a CTreePropertySheet in your application:
Step 1.-
Insert "TreePropertySheet.cpp" to your application.
-
Insert an
#include "TreePropertySheet.h"
in the class implementation file in which you want to use the CTreePropertySheet.
-
Define a function which invokes the property sheet, for example:
void CMyView::OnPropertySheet() { // TODO: ... }Step 4.
-
Create a CTreePropertySheet object in the handler and the property pages you
want to use with CTreePropertySheet:
... CTreePropertySheet tpsSheet; CGeneralPrefsPage cGeneralPrefs; COtherPrefsPage cOtherPrefs; // All dialogs contained in the property sheet must (now) be allocated from the stack.
Caution: To make it work, the dialogs you want to include must have the following
style:
- Style: 'Child'
- Border: None
- Caption: Yes
- Set the caption to the text you wish to appear when the page is selected.
- All other options must be unchecked.
-
Add the dialogs to the tree property sheet:
... tpsSheet.AddPage(tps_item_node,&cGeneralPrefs); tpsSheet.AddPage(tps_item_node,&cOtherPrefs);You have to specify the resource ID when adding the dialog. The text argument is the title shown up in the tree control, 'tps_item_node' tells that this is a simple node in the tree.
(See below for more information) Step 6.
-
Start the property sheet:
... int nRetCode=tpsSheet.DoModal(); ...Optionally, you can set a special pre-defined style before DoModal():
... tpsSheet.SetLikeNetscape(); int nRetCode=tpsSheet.DoModal(); ...
Remarks
To set up the tree structure, there are three different attributes for 'AddPage()':tps_item_branch | This item has sub-items. All following items are one level below this item, until a 'tps_item_endbranch' is found. |
tps_item_node | This item is a simple node in the tree. |
tps_item_endbranch | This item is the last item of the current sub-branch(which was initiated with an tps_item_branch). All following items are on the same level as the corresponding 'tps_item_branch' entry. |
To make it clearer, please take a look at the table below:
(code) | |
AddPage(tps_item_branch, &cMainPrefsPage); | |
AddPage(tps_item_node, &cDirectoriesPage); | |
AddPage(tps_item_node, &cUserPage); | |
AddPage(tps_item_endbranch, &cPluginPage); | |
AddPage(tps_item_node, &cSecurityPage); |
If you want to enhance the CTreePropertySheet by own controls or buttons, this can be done using InsertExtraControl() / InsertExtraSpace().
For more information about these functions, please take a look into the HTML help file(see below) and into the example project.
Downloads
Download source - 14 KB
These files can also be downloaded at
http://members.xoom.com/softserv/tps_index.html
Comments
SelChanged vs. SelChanging
Posted by Legacy on 05/17/2000 12:00amOriginally posted by: Kent Murray
It has been my experience that as written this class fails to operate correctly when a category selection fails due to data validation problems during the dialog data exchange that is triggered by the page change. This might not be obvious normally, but I modified the tree control creation to include the always show selection flag.
When the validation fails the page is not changed, but the tree control still indicates the selection to be the that of the page which you tried to select. To correct this behavior I handle the selection _changing_ message rather than the selection _changed_ message. In the selection changing message handler I set the result value (second argument) to be the negation of the value returned from SetActivePage(). This will keep the tree control selection from changing when the active page does not change.
For example:
BEGIN_MESSAGE_MAP(CTreePropertySheet, CPropertySheet)
ON_NOTIFY(TVN_SELCHANGING,ID_TREECTRL,OnSelChanging)
END_MESSAGE_MAP()
void CTreePropertySheet::OnSelChanging(
NMHDR* pNotifyStruct,
RESULT* pResult)
{
NMTREEVIEW *pNotify=(NMTREEVIEW*)pNotifyStruct;
DWORD dwPage = m_cTreeCtrl.GetItemData(pNotify->itemNew.hItem);
LockWindowUpdate();
(*pResult) = !SetActivePage(dwPage);
UnlockWindowUpdate();
// Prevent losing the focus when invoked by keyboard
if(!(*pResult) && pNotify->action==TVC_BYKEYBOARD) {
m_cTreeCtrl.SetFocus();
}
InvalidateRect(&m;_rcCaptionBar,FALSE);
}
[Note: I downloaded the class source directly from the author's homepage, and I have not compared it against the source available on CodeGuru.]
CTreePropertySheet fix for NT 5
Posted by Legacy on 09/10/1999 12:00amOriginally posted by: Mario Contestabile
Add
BEGIN_MESSAGE_MAP(CTreePropertySheet, CPropertySheet)
ON_NOTIFY(TVN_SELCHANGEDW,ID_TREECTRL,OnSelChanged)
...
END_MESSAGE_MAP()
in treepropertysheet.cpp
page change error solved
Posted by Legacy on 08/11/1999 12:00amOriginally posted by: Andr� Gleichner
The error occurs because the treeview control is in UNICODE mode (somebody knows why?) although it's an ANSI build and therefore sends its WM_NOTIFY codes also as UNICODE messages. Here it sends a TVN_SELCHANGEDW instead of TVN_SELCHANGEDA. It seems to be a very common problem as it shows up in several newsgroups with some variations (with ListCtrls, sends only ANSI codes in UNICODE builds, etc). Most people recommend to handle both the ANSI and the UNICODE code (which works here) but that makes it more complicated than necessary (all codes have to be doubled as well as some strings received from treectrl are useless/have to be converted).
Simply add the following lines within the CTreePropertySheet::AddTreeView() function right after the CreateEx() call. This will switch the treectrl to the right mode.
BOOL tIsUnicode;
#ifdef UNICODE
tIsUnicode = TreeView_SetUnicodeFormat(m_cTreeCtrl.m_hWnd, 1);
#else
tIsUnicode = TreeView_SetUnicodeFormat(m_cTreeCtrl.m_hWnd, 0);
#endif // UNICODE
I somewhere read that the call to InitCommonControls() has something to do with that odd behavior. Anybody there who knows details?
Best regards
Andr� Gleichner
Same problem as Peter: dialogs doesn't update ...
Posted by Legacy on 08/06/1999 12:00amOriginally posted by: Raymond Pols
Hoi,
I have the same problem on an NT workstation. The dialog pages doesn't change when selecting them from the treeview.
Any idea yet?
Thanks.
By the way: great work though!
ReplyPropertysheet doesn't work
Posted by Legacy on 07/28/1999 12:00amOriginally posted by: Peter Hartmann
Hello Alexander,
I've compiled your Demo and testet it. The dialogs doesn't change. Nothing happens.
Environment : NT 4.0 SP 4
VS 6.0 SP 3
Please have a look...
Greetinx
ReplyPeter :-)
Comments
Posted by Legacy on 07/02/1999 12:00amOriginally posted by: Alexander Berthold
I am sorry, but i had almost no time to review and update this page. I appreciate your comments, and i know the design of the tree property sheet control had many disadvantages. I'd been in some time pressure ... you know that, don't you ;)
Now i have updated the whole thing a lot.
I've completely redesigned the control, derived it from
CPropertySheet and using the property sheet / property page design. It is now 100% compatible to windows property sheets and almost all of the methods are compatible to the old version.
I've sent the update to codeguru today.
To access the sources directly, click the link in the
CTreePropertySheet page to my homepage.
URL:
http://members.xoom.com/softserv/tps_index.html
Again, thanks for your time reviewing the code.
ReplyIs there a way to use API-style dialogs?
Posted by Legacy on 05/19/1999 12:00amOriginally posted by: Ken Krakman
The parameter to the Tree Property Sheet only uses a
CDialog. I have an application that has 40 API-style
dialog boxes that have code associated with them all
(the dialog procs that handle messages). Is there a way to
use this class and still re-use all that code?
Thanks!
ReplyTABbing problem with edit-style combo boxes
Posted by Legacy on 02/02/1999 12:00amOriginally posted by: Robert Clark
Really great work!!
I have been playing with the control and I have discovered a problem with edit-style combo-box control in a prop sheet when tabbing. When using the TAB key (TAB or Shift-TAB) from an edit-style combo-box the software freezes up. My guess is a problem with the child edit window, but I have not isolated it yet.
Anyone have any ideas or experience with this problem?
ReplyTABbing problem with edit-style combo boxes - Solved
Posted by Legacy on 02/02/1999 12:00amOriginally posted by: Robert Clark
Update all pages on Ok, rather than just the currently active one.
Posted by Legacy on 01/05/1999 12:00amOriginally posted by: Steve Kemp