By Damien LEFEVRE: Sunday 10 January 2010, 15:41
Icons on CMFCPropertySheet missing.
When recently trying to use the CMFCPropertySheet class with CMFCPropertySheet::PropSheetLook_Tree, I ran into the problem that the class does not give any options to customize the look the the tree control on the left side.
With CMFCPropertySheet, it is possible to set a list of icons or an empty list. In both cases there is no options to have the buttons (+ or - square) or the line in the tree.
Here is one way to fix this problem.
As well spotted a fellow on MSDN forum, the CTreeCtrl is created in CMFCPropertySheet::InitNavigationControl() method. Here is the extract:
[cpp]
//...
if (m_look == PropSheetLook_Tree)
{
CRect rectDummy(0, 0, 0, 0);
const DWORD dwTreeStyle = WS_CHILD | WS_VISIBLE;
m_wndTree.Create(dwTreeStyle, rectDummy, this, (UINT) idTree);
m_wndTree.ModifyStyleEx(0, WS_EX_CLIENTEDGE);
if (m_Icons.GetSafeHandle() != NULL)
{
m_wndTree.SetImageList(&m_Icons, TVSIL_NORMAL);
m_wndTree.SetImageList(&m_Icons, TVSIL_STATE);
}
// Add categories:
for (POSITION pos = m_lstTreeCategories.GetHeadPosition(); pos != NULL;)
{
AddCategoryToTree(m_lstTreeCategories.GetNext(pos));
}
// Add pages:
for (int nTab = 0; nTab < pTab->GetItemCount(); nTab++)
{
InternalAddPage(nTab);
}
return &m_wndTree;
}
// ...
The way to get the + and lines is to set the TVS_HASBUTTONS and TVS_HASLINES styles to the CTreeCtrl. We do it like this:
[cpp]
if (m_look == PropSheetLook_Tree)
{
CRect rectDummy(0, 0, 0, 0);
const DWORD dwTreeStyle = WS_CHILD | WS_VISIBLE;
m_wndTree.Create(dwTreeStyle, rectDummy, this, (UINT) idTree);
m_wndTree.ModifyStyle(0, TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS);
m_wndTree.ModifyStyleEx(0, WS_EX_CLIENTEDGE);
//...
}
To add a little bit more flexibility and still be actually able to set a different style for the tree and still being able to set a different icons list I came up with the following class. I added the method
[cpp] void ModifyTreeStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0);
to be able to set the style parameters of the list. Then CMFCPropertySheet::InitNavigationControl() is overwritten to do something else than the original implmentation if we use the PropSheetLook_Tree look and want to modify the list style.
MyMFCPropertySheet.h
[cpp]
#ifndef _CMyMFCPropertySheet_H_
#define _CMyMFCPropertySheet_H_
// CMyMFCPropertySheet
/** Fixes the CMFCPropertySheet lacking the ability to have lines and buttons
* when using PropSheetLook_Tree.
* @author Damien LEFEVRE, http://www.lfdm.net
* @version 1.0
* @date 2010-01-10
*/
class CMyMFCPropertySheet : public CMFCPropertySheet
{
DECLARE_DYNAMIC(CMyMFCPropertySheet)
public:
/** Default constructors
*/
CMyMFCPropertySheet();
CMyMFCPropertySheet(UINT nIDCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
CMyMFCPropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd = NULL, UINT iSelectPage = 0);
virtual ~CMyMFCPropertySheet();
/** Must be overwritten to be able to call m_wndTree.ModifyStyle(...) to change
* the tree control style*/
virtual CWnd* InitNavigationControl(void);
/** Caches the m_wndTree.ModifyStyle parameters into class variables which will
* be set in the InitNavigationControl(void) method when create the CTreeCtrl.
* For the parameters description, please refer to CWnd::ModifyStyle
*/
void ModifyTreeStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags = 0);
protected:
BOOL m_bModifyTreeStyle;
DWORD m_dwRemove;
DWORD m_dwAdd;
UINT m_nFlags;
DECLARE_MESSAGE_MAP()
};
#endif
MyMFCPropertySheet.cpp
[cpp]
// MyMFCPropertySheet.cpp : implementation file
//
#include "stdafx.h"
#include "MyMFCPropertySheet.h"
const int idTree = 101;
// CMyMFCPropertySheet
IMPLEMENT_DYNAMIC(CMyMFCPropertySheet, CMFCPropertySheet)
CMyMFCPropertySheet::CMyMFCPropertySheet()
: CMFCPropertySheet()
, m_bModifyTreeStyle(FALSE)
{
}
CMyMFCPropertySheet::CMyMFCPropertySheet(UINT nIDCaption, CWnd* pParentWnd, UINT iSelectPage)
: CMFCPropertySheet(nIDCaption, pParentWnd, iSelectPage)
, m_bModifyTreeStyle(FALSE)
{
}
CMyMFCPropertySheet::CMyMFCPropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd, UINT iSelectPage)
: CMFCPropertySheet(pszCaption, pParentWnd, iSelectPage)
, m_bModifyTreeStyle(FALSE)
{
}
CMyMFCPropertySheet::~CMyMFCPropertySheet()
{
}
BEGIN_MESSAGE_MAP(CMyMFCPropertySheet, CMFCPropertySheet)
END_MESSAGE_MAP()
void CMyMFCPropertySheet::ModifyTreeStyle(DWORD _dwRemove, DWORD _dwAdd, UINT _nFlags)
{
m_dwRemove = _dwRemove;
m_dwAdd = _dwAdd;
m_nFlags = _nFlags;
m_bModifyTreeStyle = TRUE;
}
CWnd* CMyMFCPropertySheet::InitNavigationControl(void)
{
if((m_look == PropSheetLook_Tree) && (m_bModifyTreeStyle == TRUE))
{
ASSERT_VALID(this);
CTabCtrl* pTab = GetTabControl();
ASSERT_VALID(pTab);
if (m_look == PropSheetLook_Tree)
{
CRect rectDummy(0, 0, 0, 0);
const DWORD dwTreeStyle = WS_CHILD | WS_VISIBLE;
m_wndTree.Create(dwTreeStyle, rectDummy, this, (UINT) idTree);
m_wndTree.ModifyStyle(m_dwRemove, m_dwAdd, m_nFlags);
m_wndTree.ModifyStyleEx(0, WS_EX_CLIENTEDGE);
if (m_Icons.GetSafeHandle() != NULL)
{
m_wndTree.SetImageList(&m_Icons, TVSIL_NORMAL);
m_wndTree.SetImageList(&m_Icons, TVSIL_STATE);
}
// Add categories:
for (POSITION pos = m_lstTreeCategories.GetHeadPosition(); pos != NULL;)
{
AddCategoryToTree(m_lstTreeCategories.GetNext(pos));
}
// Add pages:
for (int nTab = 0; nTab < pTab->GetItemCount(); nTab++)
{
InternalAddPage(nTab);
}
return &m_wndTree;
}
}
else
{
return CMFCPropertySheet::InitNavigationControl();
}
}
// CMyMFCPropertySheet message handlers
This class might need to be developed further, but it is enough for my use at this stage.



Comments
No comment for the moment.
Add a comment
Les commentaires pour ce billet sont fermés.