1 /********************************************************************
3 * Copyright (c) 2002 Sven Wiegand <mail@sven-wiegand.de>
5 * You can use this and modify this in any way you want,
6 * BUT LEAVE THIS HEADER INTACT.
8 * Redistribution is appreciated.
18 *********************************************************************/
22 #include "TreePropSheet.h"
23 #include "PropPageFrameDefault.h"
24 #include "HighColorTab.hpp"
29 static char THIS_FILE
[] = __FILE__
;
34 namespace TreePropSheet
37 //-------------------------------------------------------------------
38 // class CTreePropSheet
39 //-------------------------------------------------------------------
41 BEGIN_MESSAGE_MAP(CTreePropSheet
, CPropertySheet
)
42 //{{AFX_MSG_MAP(CTreePropSheet)
45 ON_MESSAGE(PSM_ADDPAGE
, OnAddPage
)
46 ON_MESSAGE(PSM_REMOVEPAGE
, OnRemovePage
)
47 ON_MESSAGE(PSM_SETCURSEL
, OnSetCurSel
)
48 ON_MESSAGE(PSM_SETCURSELID
, OnSetCurSelId
)
49 ON_MESSAGE(PSM_ISDIALOGMESSAGE
, OnIsDialogMessage
)
51 ON_NOTIFY(TVN_SELCHANGINGA
, s_unPageTreeId
, OnPageTreeSelChanging
)
52 ON_NOTIFY(TVN_SELCHANGINGW
, s_unPageTreeId
, OnPageTreeSelChanging
)
53 ON_NOTIFY(TVN_SELCHANGEDA
, s_unPageTreeId
, OnPageTreeSelChanged
)
54 ON_NOTIFY(TVN_SELCHANGEDW
, s_unPageTreeId
, OnPageTreeSelChanged
)
57 IMPLEMENT_DYNAMIC(CTreePropSheet
, CPropertySheet
)
59 const UINT
CTreePropSheet::s_unPageTreeId
= 0x7EEE;
61 CTreePropSheet::CTreePropSheet()
63 m_bPageTreeSelChangedActive(FALSE
),
64 m_bTreeViewMode(TRUE
),
65 m_bPageCaption(FALSE
),
67 m_nPageTreeWidth(150),
73 CTreePropSheet::CTreePropSheet(UINT nIDCaption
, CWnd
* pParentWnd
, UINT iSelectPage
)
74 : CPropertySheet(nIDCaption
, pParentWnd
, iSelectPage
),
75 m_bPageTreeSelChangedActive(FALSE
),
76 m_bTreeViewMode(TRUE
),
77 m_bPageCaption(FALSE
),
79 m_nPageTreeWidth(150),
86 CTreePropSheet::CTreePropSheet(LPCTSTR pszCaption
, CWnd
* pParentWnd
, UINT iSelectPage
)
87 : CPropertySheet(pszCaption
, pParentWnd
, iSelectPage
),
88 m_bPageTreeSelChangedActive(FALSE
),
89 m_bTreeViewMode(TRUE
),
90 m_bPageCaption(FALSE
),
92 m_nPageTreeWidth(150),
99 CTreePropSheet::~CTreePropSheet()
104 /////////////////////////////////////////////////////////////////////
107 BOOL
CTreePropSheet::SetTreeViewMode(BOOL bTreeViewMode
/* = TRUE */, BOOL bPageCaption
/* = FALSE */, BOOL bTreeImages
/* = FALSE */)
109 if (IsWindow(m_hWnd
))
111 // needs to becalled, before the window has been created
116 m_bTreeViewMode
= bTreeViewMode
;
119 m_bPageCaption
= bPageCaption
;
120 m_bTreeImages
= bTreeImages
;
127 BOOL
CTreePropSheet::SetTreeWidth(int nWidth
)
129 if (IsWindow(m_hWnd
))
131 // needs to be called, before the window is created.
136 m_nPageTreeWidth
= nWidth
;
142 void CTreePropSheet::SetEmptyPageText(LPCTSTR lpszEmptyPageText
)
144 m_strEmptyPageMessage
= lpszEmptyPageText
;
148 DWORD
CTreePropSheet::SetEmptyPageTextFormat(DWORD dwFormat
)
150 DWORD dwPrevFormat
= m_pFrame
->GetMsgFormat();
151 m_pFrame
->SetMsgFormat(dwFormat
);
156 BOOL
CTreePropSheet::SetTreeDefaultImages(CImageList
*pImages
)
158 if (pImages
->GetImageCount() != 2)
164 if (m_DefaultImages
.GetSafeHandle())
165 m_DefaultImages
.DeleteImageList();
166 m_DefaultImages
.Create(pImages
);
168 // update, if necessary
169 if (IsWindow(m_hWnd
))
176 BOOL
CTreePropSheet::SetTreeDefaultImages(UINT unBitmapID
, int cx
, COLORREF crMask
)
178 if (m_DefaultImages
.GetSafeHandle())
179 m_DefaultImages
.DeleteImageList();
180 if (!m_DefaultImages
.Create(unBitmapID
, cx
, 0, crMask
))
183 if (m_DefaultImages
.GetImageCount() != 2)
185 m_DefaultImages
.DeleteImageList();
193 CTreeCtrl
* CTreePropSheet::GetPageTreeControl()
195 return m_pwndPageTree
;
199 /////////////////////////////////////////////////////////////////////
202 BOOL
CTreePropSheet::SetPageIcon(CPropertyPage
*pPage
, HICON hIcon
)
204 pPage
->m_psp
.dwFlags
|= PSP_USEHICON
;
205 pPage
->m_psp
.hIcon
= hIcon
;
210 BOOL
CTreePropSheet::SetPageIcon(CPropertyPage
*pPage
, UINT unIconId
)
212 HICON hIcon
= AfxGetApp()->LoadIcon(unIconId
);
216 return SetPageIcon(pPage
, hIcon
);
220 BOOL
CTreePropSheet::SetPageIcon(CPropertyPage
*pPage
, CImageList
&Images
, int nImage
)
222 HICON hIcon
= Images
.ExtractIcon(nImage
);
226 return SetPageIcon(pPage
, hIcon
);
230 BOOL
CTreePropSheet::DestroyPageIcon(CPropertyPage
*pPage
)
232 if (!pPage
|| !(pPage
->m_psp
.dwFlags
&PSP_USEHICON
) || !pPage
->m_psp
.hIcon
)
235 DestroyIcon(pPage
->m_psp
.hIcon
);
236 pPage
->m_psp
.dwFlags
&= ~PSP_USEHICON
;
237 pPage
->m_psp
.hIcon
= NULL
;
243 /////////////////////////////////////////////////////////////////////
244 // Overridable implementation helpers
246 CString
CTreePropSheet::GenerateEmptyPageMessage(LPCTSTR lpszEmptyPageMessage
, LPCTSTR lpszCaption
)
249 strMsg
.Format(lpszEmptyPageMessage
, lpszCaption
);
254 CTreeCtrl
* CTreePropSheet::CreatePageTreeObject()
256 return new CTreeCtrl
;
260 CPropPageFrame
* CTreePropSheet::CreatePageFrame()
262 return new CPropPageFrameDefault
;
266 /////////////////////////////////////////////////////////////////////
267 // Implementation helpers
269 void CTreePropSheet::MoveChildWindows(int nDx
, int nDy
)
271 CWnd
*pWnd
= GetWindow(GW_CHILD
);
275 pWnd
->GetWindowRect(rect
);
276 rect
.OffsetRect(nDx
, nDy
);
277 ScreenToClient(rect
);
278 pWnd
->MoveWindow(rect
);
280 pWnd
= pWnd
->GetNextWindow();
285 void CTreePropSheet::RefillPageTree()
287 if (!IsWindow(m_hWnd
))
290 m_pwndPageTree
->DeleteAllItems();
292 CTabCtrl
*pTabCtrl
= GetTabControl();
293 if (!IsWindow(pTabCtrl
->GetSafeHwnd()))
299 const int nPageCount
= pTabCtrl
->GetItemCount();
301 // rebuild image list
304 for (int i
= m_Images
.GetImageCount()-1; i
>= 0; --i
)
308 CImageList
*pPageImages
= pTabCtrl
->GetImageList();
311 for (int nImage
= 0; nImage
< pPageImages
->GetImageCount(); ++nImage
)
313 HICON hIcon
= pPageImages
->ExtractIcon(nImage
);
319 // add default images
320 if (m_DefaultImages
.GetSafeHandle())
324 // add default images
325 hIcon
= m_DefaultImages
.ExtractIcon(0);
331 hIcon
= m_DefaultImages
.ExtractIcon(1);
340 for (int nPage
= 0; nPage
< nPageCount
; ++nPage
)
342 // Get title and image of the page
346 SecureZeroMemory(&ti
, sizeof(ti
));
347 ti
.mask
= TCIF_TEXT
|TCIF_IMAGE
;
348 ti
.cchTextMax
= MAX_PATH
;
349 ti
.pszText
= strPagePath
.GetBuffer(ti
.cchTextMax
);
354 pTabCtrl
->GetItem(nPage
, &ti
);
355 strPagePath
.ReleaseBuffer();
357 // Create an item in the tree for the page
358 HTREEITEM hItem
= CreatePageTreeItem(ti
.pszText
);
362 m_pwndPageTree
->SetItemData(hItem
, nPage
);
367 int nImage
= ti
.iImage
;
368 if (nImage
< 0 || nImage
>= m_Images
.GetImageCount())
369 nImage
= m_DefaultImages
.GetSafeHandle()? m_Images
.GetImageCount()-1 : -1;
371 m_pwndPageTree
->SetItemImage(hItem
, nImage
, nImage
);
373 m_pwndPageTree
->Expand(m_pwndPageTree
->GetParentItem(hItem
), TVE_EXPAND
);
379 HTREEITEM
CTreePropSheet::CreatePageTreeItem(LPCTSTR lpszPath
, HTREEITEM hParent
/* = TVI_ROOT */)
381 CString
strPath(lpszPath
);
382 CString
strTopMostItem(SplitPageTreePath(strPath
));
384 // Check if an item with the given text does already exist
385 HTREEITEM hItem
= NULL
;
386 HTREEITEM hChild
= m_pwndPageTree
->GetChildItem(hParent
);
389 if (m_pwndPageTree
->GetItemText(hChild
) == strTopMostItem
)
394 hChild
= m_pwndPageTree
->GetNextItem(hChild
, TVGN_NEXT
);
397 // If item with that text does not already exist, create a new one
400 hItem
= m_pwndPageTree
->InsertItem(strTopMostItem
, hParent
);
401 m_pwndPageTree
->SetItemData(hItem
, (DWORD_PTR
)-1);
402 if (!strPath
.IsEmpty() && m_bTreeImages
&& m_DefaultImages
.GetSafeHandle())
404 m_pwndPageTree
->SetItemImage(hItem
, m_Images
.GetImageCount()-2, m_Images
.GetImageCount()-2);
412 if (strPath
.IsEmpty())
415 return CreatePageTreeItem(strPath
, hItem
);
419 CString
CTreePropSheet::SplitPageTreePath(CString
&strRest
)
421 int nSeperatorPos
= 0;
422 #pragma warning(push)
423 #pragma warning(disable: 4127) // conditional expression constant
426 nSeperatorPos
= strRest
.Find(_T("::"), nSeperatorPos
);
427 if (nSeperatorPos
== -1)
429 CString
strItem(strRest
);
433 else if (nSeperatorPos
>0)
435 // if there is an odd number of backslashes infront of the
436 // seperator, than do not interpret it as separator
437 int nBackslashCount
= 0;
438 for (int nPos
= nSeperatorPos
-1; nPos
>= 0 && strRest
[nPos
]==_T('\\'); --nPos
, ++nBackslashCount
);
439 if (nBackslashCount
%2 == 0)
447 CString
strItem(strRest
.Left(nSeperatorPos
));
448 strItem
.Replace(_T("\\::"), _T("::"));
449 strItem
.Replace(_T("\\\\"), _T("\\"));
450 strRest
= strRest
.Mid(nSeperatorPos
+2);
455 BOOL
CTreePropSheet::KillActiveCurrentPage()
457 HWND hCurrentPage
= PropSheet_GetCurrentPageHwnd(m_hWnd
);
458 if (!IsWindow(hCurrentPage
))
464 // Check if the current page is really active (if page is invisible
465 // an virtual empty page is the active one.
466 if (!::IsWindowVisible(hCurrentPage
))
469 // Try to deactivate current page
471 pshn
.hdr
.code
= PSN_KILLACTIVE
;
472 pshn
.hdr
.hwndFrom
= m_hWnd
;
473 pshn
.hdr
.idFrom
= GetDlgCtrlID();
475 if (::SendMessage(hCurrentPage
, WM_NOTIFY
, pshn
.hdr
.idFrom
, (LPARAM
)&pshn
))
476 // current page does not allow page change
480 ::ShowWindow(hCurrentPage
, SW_HIDE
);
486 HTREEITEM
CTreePropSheet::GetPageTreeItem(int nPage
, HTREEITEM hRoot
/* = TVI_ROOT */)
488 // Special handling for root case
489 if (hRoot
== TVI_ROOT
)
490 hRoot
= m_pwndPageTree
->GetNextItem(NULL
, TVGN_ROOT
);
493 if (nPage
< 0 || nPage
>= GetPageCount())
505 // we are performing a simple linear search here, because we are
506 // expecting only little data
507 HTREEITEM hItem
= hRoot
;
510 if ((signed)m_pwndPageTree
->GetItemData(hItem
) == nPage
)
512 if (m_pwndPageTree
->ItemHasChildren(hItem
))
514 HTREEITEM hResult
= GetPageTreeItem(nPage
, m_pwndPageTree
->GetNextItem(hItem
, TVGN_CHILD
));
519 hItem
= m_pwndPageTree
->GetNextItem(hItem
, TVGN_NEXT
);
522 // we've found nothing, if we arrive here
527 BOOL
CTreePropSheet::SelectPageTreeItem(int nPage
)
529 HTREEITEM hItem
= GetPageTreeItem(nPage
);
533 return m_pwndPageTree
->SelectItem(hItem
);
537 BOOL
CTreePropSheet::SelectCurrentPageTreeItem()
539 CTabCtrl
*pTab
= GetTabControl();
540 if (!IsWindow(pTab
->GetSafeHwnd()))
543 return SelectPageTreeItem(pTab
->GetCurSel());
547 void CTreePropSheet::UpdateCaption()
549 HWND hPage
= PropSheet_GetCurrentPageHwnd(GetSafeHwnd());
550 BOOL bRealPage
= IsWindow(hPage
) && ::IsWindowVisible(hPage
);
551 HTREEITEM hItem
= m_pwndPageTree
->GetSelectedItem();
555 CString strCaption
= m_pwndPageTree
->GetItemText(hItem
);
557 // if empty page, then update empty page message
559 m_pFrame
->SetMsgText(GenerateEmptyPageMessage(m_strEmptyPageMessage
, strCaption
));
561 // if no captions are displayed, cancel here
562 if (!m_pFrame
->GetShowCaption())
565 // get tab control, to the the images from
566 CTabCtrl
*pTabCtrl
= GetTabControl();
567 if (!IsWindow(pTabCtrl
->GetSafeHwnd()))
575 // get image from tree
577 m_pwndPageTree
->GetItemImage(hItem
, nImage
, nImage
);
578 HICON hIcon
= m_Images
.ExtractIcon(nImage
);
579 m_pFrame
->SetCaption(strCaption
, hIcon
);
585 // get image from hidden (original) tab provided by the original
587 CImageList
*pImages
= pTabCtrl
->GetImageList();
591 SecureZeroMemory(&ti
, sizeof(ti
));
592 ti
.mask
= TCIF_IMAGE
;
595 if (pTabCtrl
->GetItem((int)m_pwndPageTree
->GetItemData(hItem
), &ti
))
596 hIcon
= pImages
->ExtractIcon(ti
.iImage
);
598 m_pFrame
->SetCaption(strCaption
, hIcon
);
603 m_pFrame
->SetCaption(strCaption
);
606 m_pFrame
->SetCaption(strCaption
);
610 void CTreePropSheet::ActivatePreviousPage()
612 if (!IsWindow(m_hWnd
))
615 if (!IsWindow(m_pwndPageTree
->GetSafeHwnd()))
617 // normal tab property sheet. Simply use page index
618 int nPageIndex
= GetActiveIndex();
619 if (nPageIndex
<0 || nPageIndex
>=GetPageCount())
622 int nPrevIndex
= (nPageIndex
==0)? GetPageCount()-1 : nPageIndex
-1;
623 SetActivePage(nPrevIndex
);
627 // property sheet with page tree.
628 // we need a more sophisticated handling here, than simply using
629 // the page index, because we won't skip empty pages.
630 // so we have to walk the page tree
631 HTREEITEM hItem
= m_pwndPageTree
->GetSelectedItem();
636 HTREEITEM hPrevItem
= NULL
;
637 if ((hPrevItem
=m_pwndPageTree
->GetPrevSiblingItem(hItem
))!=0)
639 while (m_pwndPageTree
->ItemHasChildren(hPrevItem
))
641 hPrevItem
= m_pwndPageTree
->GetChildItem(hPrevItem
);
642 while (m_pwndPageTree
->GetNextSiblingItem(hPrevItem
))
643 hPrevItem
= m_pwndPageTree
->GetNextSiblingItem(hPrevItem
);
647 hPrevItem
=m_pwndPageTree
->GetParentItem(hItem
);
651 // no prev item, so cycle to the last item
652 hPrevItem
= m_pwndPageTree
->GetRootItem();
654 #pragma warning(push)
655 #pragma warning(disable: 4127) // conditional expression constant
658 while (m_pwndPageTree
->GetNextSiblingItem(hPrevItem
))
659 hPrevItem
= m_pwndPageTree
->GetNextSiblingItem(hPrevItem
);
661 if (m_pwndPageTree
->ItemHasChildren(hPrevItem
))
662 hPrevItem
= m_pwndPageTree
->GetChildItem(hPrevItem
);
670 m_pwndPageTree
->SelectItem(hPrevItem
);
675 void CTreePropSheet::ActivateNextPage()
677 if (!IsWindow(m_hWnd
))
680 if (!IsWindow(m_pwndPageTree
->GetSafeHwnd()))
682 // normal tab property sheet. Simply use page index
683 int nPageIndex
= GetActiveIndex();
684 if (nPageIndex
<0 || nPageIndex
>=GetPageCount())
687 int nNextIndex
= (nPageIndex
==GetPageCount()-1)? 0 : nPageIndex
+1;
688 SetActivePage(nNextIndex
);
692 // property sheet with page tree.
693 // we need a more sophisticated handling here, than simply using
694 // the page index, because we won't skip empty pages.
695 // so we have to walk the page tree
696 HTREEITEM hItem
= m_pwndPageTree
->GetSelectedItem();
701 HTREEITEM hNextItem
= NULL
;
702 if ((hNextItem
=m_pwndPageTree
->GetChildItem(hItem
))!=0)
704 else if ((hNextItem
=m_pwndPageTree
->GetNextSiblingItem(hItem
))!=0)
706 else if (m_pwndPageTree
->GetParentItem(hItem
))
710 hItem
= m_pwndPageTree
->GetParentItem(hItem
);
714 hNextItem
= m_pwndPageTree
->GetNextSiblingItem(hItem
);
719 // no next item -- so cycle to the first item
720 hNextItem
= m_pwndPageTree
->GetRootItem();
723 m_pwndPageTree
->SelectItem(hNextItem
);
728 /////////////////////////////////////////////////////////////////////
731 BOOL
CTreePropSheet::OnInitDialog()
735 // be sure, there are no stacked tabs, because otherwise the
736 // page caption will be to large in tree view mode
737 EnableStackedTabs(FALSE
);
739 // Initialize image list.
740 if (m_DefaultImages
.GetSafeHandle())
743 m_DefaultImages
.GetImageInfo(0, &ii
);
744 if (ii
.hbmImage
) DeleteObject(ii
.hbmImage
);
745 if (ii
.hbmMask
) DeleteObject(ii
.hbmMask
);
746 m_Images
.Create(ii
.rcImage
.right
-ii
.rcImage
.left
, ii
.rcImage
.bottom
-ii
.rcImage
.top
, ILC_COLOR32
|ILC_MASK
, 0, 1);
749 m_Images
.Create(16, 16, ILC_COLOR32
|ILC_MASK
, 0, 1);
752 // perform default implementation
753 BOOL bResult
= CPropertySheet::OnInitDialog();
754 HighColorTab::UpdateImageList(*this);
756 if (!m_bTreeViewMode
)
757 // stop here, if we would like to use tabs
760 // Get tab control...
761 CTabCtrl
*pTab
= GetTabControl();
762 if (!IsWindow(pTab
->GetSafeHwnd()))
769 pTab
->ShowWindow(SW_HIDE
);
770 pTab
->EnableWindow(FALSE
);
772 // Place another (empty) tab ctrl, to get a frame instead
774 pTab
->GetWindowRect(rectFrame
);
775 ScreenToClient(rectFrame
);
777 m_pFrame
= CreatePageFrame();
781 AfxThrowMemoryException();
783 m_pFrame
->Create(WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
, rectFrame
, this, 0xFFFF);
784 m_pFrame
->ShowCaption(m_bPageCaption
);
786 // Lets make place for the tree ctrl
787 const int nTreeWidth
= m_nPageTreeWidth
;
788 const int nTreeSpace
= 5;
791 GetWindowRect(rectSheet
);
792 rectSheet
.right
+= nTreeWidth
;
793 SetWindowPos(NULL
, -1, -1, rectSheet
.Width(), rectSheet
.Height(), SWP_NOZORDER
|SWP_NOMOVE
);
796 MoveChildWindows(nTreeWidth
, 0);
798 // Lets calculate the rectangle for the tree ctrl
799 CRect
rectTree(rectFrame
);
800 rectTree
.right
= rectTree
.left
+ nTreeWidth
- nTreeSpace
;
802 // calculate caption height
804 wndTabCtrl
.Create(WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
, rectFrame
, this, 0x1234);
805 wndTabCtrl
.InsertItem(0, _T(""));
806 CRect rectFrameCaption
;
807 wndTabCtrl
.GetItemRect(0, rectFrameCaption
);
808 wndTabCtrl
.DestroyWindow();
809 m_pFrame
->SetCaptionHeight(rectFrameCaption
.Height());
811 // if no caption should be displayed, make the window smaller in
815 // make frame smaller
816 m_pFrame
->GetWnd()->GetWindowRect(rectFrame
);
817 ScreenToClient(rectFrame
);
818 rectFrame
.top
+= rectFrameCaption
.Height();
819 m_pFrame
->GetWnd()->MoveWindow(rectFrame
);
821 // move all child windows up
822 MoveChildWindows(0, -rectFrameCaption
.Height());
824 // modify rectangle for the tree ctrl
825 rectTree
.bottom
-= rectFrameCaption
.Height();
830 rect
.top
+= rectFrameCaption
.Height()/2;
831 rect
.bottom
-= rectFrameCaption
.Height()-rectFrameCaption
.Height()/2;
833 GetParent()->ScreenToClient(rect
);
837 // finally create the tree control
838 const DWORD dwTreeStyle
= TVS_SHOWSELALWAYS
|TVS_TRACKSELECT
|TVS_HASLINES
|TVS_LINESATROOT
|TVS_HASBUTTONS
;
839 m_pwndPageTree
= CreatePageTreeObject();
843 AfxThrowMemoryException();
846 // MFC7-support here (Thanks to Rainer Wollgarten)
847 // YT: Cast tree control to CWnd and calls CWnd::CreateEx in all cases (VC 6 and7).
848 ((CWnd
*)m_pwndPageTree
)->CreateEx(
849 WS_EX_CLIENTEDGE
|WS_EX_NOPARENTNOTIFY
|TVS_EX_DOUBLEBUFFER
,
850 _T("SysTreeView32"), _T("PageTree"),
851 WS_TABSTOP
|WS_CHILD
|WS_VISIBLE
|dwTreeStyle
,
852 rectTree
, this, s_unPageTreeId
);
856 m_pwndPageTree
->SetImageList(&m_Images
, TVSIL_NORMAL
);
857 m_pwndPageTree
->SetImageList(&m_Images
, TVSIL_STATE
);
859 SetWindowTheme(m_pwndPageTree
->GetSafeHwnd(), L
"Explorer", NULL
);
861 // Fill the tree ctrl
864 // Select item for the current page
865 if (pTab
->GetCurSel() > -1)
866 SelectPageTreeItem(pTab
->GetCurSel());
872 void CTreePropSheet::OnDestroy()
874 CPropertySheet::OnDestroy();
876 if (m_Images
.GetSafeHandle())
877 m_Images
.DeleteImageList();
879 delete m_pwndPageTree
;
880 m_pwndPageTree
= NULL
;
887 LRESULT
CTreePropSheet::OnAddPage(WPARAM wParam
, LPARAM lParam
)
889 LRESULT lResult
= DefWindowProc(PSM_ADDPAGE
, wParam
, lParam
);
890 if (!m_bTreeViewMode
)
894 SelectCurrentPageTreeItem();
900 LRESULT
CTreePropSheet::OnRemovePage(WPARAM wParam
, LPARAM lParam
)
902 LRESULT lResult
= DefWindowProc(PSM_REMOVEPAGE
, wParam
, lParam
);
903 if (!m_bTreeViewMode
)
907 SelectCurrentPageTreeItem();
913 LRESULT
CTreePropSheet::OnSetCurSel(WPARAM wParam
, LPARAM lParam
)
915 LRESULT lResult
= DefWindowProc(PSM_SETCURSEL
, wParam
, lParam
);
916 if (!m_bTreeViewMode
)
919 SelectCurrentPageTreeItem();
924 LRESULT
CTreePropSheet::OnSetCurSelId(WPARAM wParam
, LPARAM lParam
)
926 return OnSetCurSel(wParam
, lParam
);
930 void CTreePropSheet::OnPageTreeSelChanging(NMHDR
*pNotifyStruct
, LRESULT
*plResult
)
933 if (m_bPageTreeSelChangedActive
)
936 m_bPageTreeSelChangedActive
= TRUE
;
938 NMTREEVIEW
*pTvn
= reinterpret_cast<NMTREEVIEW
*>(pNotifyStruct
);
939 int nPage
= (int)m_pwndPageTree
->GetItemData(pTvn
->itemNew
.hItem
);
942 HTREEITEM nextItem
= m_pwndPageTree
->GetChildItem(pTvn
->itemNew
.hItem
);
943 nPage
= (int)m_pwndPageTree
->GetItemData(nextItem
);
946 if (nPage
>= (int)m_pwndPageTree
->GetCount())
947 bResult
= KillActiveCurrentPage();
949 bResult
= SetActivePage((int)nPage
);
952 // prevent selection to change
955 // Set focus to tree ctrl (I guess that's what the user expects)
956 m_pwndPageTree
->SetFocus();
958 m_bPageTreeSelChangedActive
= FALSE
;
964 void CTreePropSheet::OnPageTreeSelChanged(NMHDR
* /*pNotifyStruct*/, LRESULT
*plResult
)
974 LRESULT
CTreePropSheet::OnIsDialogMessage(WPARAM wParam
, LPARAM lParam
)
976 MSG
*pMsg
= reinterpret_cast<MSG
*>(lParam
);
977 if (pMsg
->message
==WM_KEYDOWN
&& pMsg
->wParam
==VK_TAB
&& GetKeyState(VK_CONTROL
)&0x8000)
979 if (GetKeyState(VK_SHIFT
)&0x8000)
980 ActivatePreviousPage();
987 return CPropertySheet::DefWindowProc(PSM_ISDIALOGMESSAGE
, wParam
, lParam
);
990 } //namespace TreePropSheet