⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 treepropsheetbase.cpp

📁 人事管理系统
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
bool CTreePropSheetBase::IsItemExpanded(HTREEITEM hItem) const
{
	if( NULL == m_pwndPageTree || NULL == hItem )
    return false;

  return ( TVIS_EXPANDED | TVIS_EXPANDPARTIAL) &
         m_pwndPageTree->GetItemState( hItem, TVIS_EXPANDED | TVIS_EXPANDPARTIAL )?true:false;
}

//////////////////////////////////////////////////////////////////////
//
bool CTreePropSheetBase::IsTreeItemDisplayable(const HTREEITEM hItem) const
{
  // Determine if the provided hItem has a property page associated with it.
  bool bHasValidPropertyPageAssociated = HasValidPropertyPageAssociated( hItem );
	
  bool bDisplayEmpty = bHasValidPropertyPageAssociated || m_bSkipEmptyPages ;
  bool bDisplayDisabled = !bHasValidPropertyPageAssociated || IsAssociatedPropertyPageEnabled( hItem ) || !m_bSkipDisabledPages;
  return bDisplayEmpty && bDisplayDisabled;
}

//////////////////////////////////////////////////////////////////////
//
void CTreePropSheetBase::Init()
{
	m_bTreeViewMode = FALSE;
	m_bPageCaption = FALSE;
	m_bTreeImages = FALSE;
	m_nPageTreeWidth = 150;
  m_nSeparatorWidth = 5;
	m_pwndPageTree = NULL;
	m_pFrame = NULL;
  m_nRefillingPageTreeContent = 0;
  m_bAutoExpandTree = false;
  m_bSkipDisabledPages = true;
  m_bSkipEmptyPages = false;
}

//////////////////////////////////////////////////////////////////////
//
void CTreePropSheetBase::SetSkipEmptyPages(const bool bSkipEmptyPages)
{
	m_bSkipEmptyPages = bSkipEmptyPages;
}

//////////////////////////////////////////////////////////////////////
//
bool CTreePropSheetBase::IsSkippingEmptyPages() const
{
	return m_bSkipEmptyPages;
}

/////////////////////////////////////////////////////////////////////
// Overridings
/////////////////////////////////////////////////////////////////////

BOOL CTreePropSheetBase::OnInitDialog() 
{
	if (m_bTreeViewMode && !IsWizardMode() )
	{
	  // Fix suggested by Przemek Miszczuk 
	  // http://www.codeproject.com/property/TreePropSheetEx.asp?msg=1024928#xx1024928xx
    TreePropSheet::CIncrementScope RefillingPageTreeContentGuard(m_nRefillingPageTreeContent );

		// be sure, there are no stacked tabs, because otherwise the
		// page caption will be to large in tree view mode
		EnableStackedTabs(FALSE);

		// Initialize image list.
		if (m_DefaultImages.GetSafeHandle())
		{
			IMAGEINFO	ii;
			m_DefaultImages.GetImageInfo(0, &ii);
			if (ii.hbmImage) DeleteObject(ii.hbmImage);
			if (ii.hbmMask) DeleteObject(ii.hbmMask);
			m_Images.Create(ii.rcImage.right-ii.rcImage.left, ii.rcImage.bottom-ii.rcImage.top, ILC_COLOR32|ILC_MASK, 0, 1);
		}
		else
			m_Images.Create(16, 16, ILC_COLOR32|ILC_MASK, 0, 1);
	}

	// perform default implementation
	BOOL bResult = CPropertySheet::OnInitDialog();

  // If in wizard mode, stop here.
  if( IsWizardMode() )
    return bResult;

	// Get tab control...
	CTabCtrl	*pTab = GetTabControl();
	if (!IsWindow(pTab->GetSafeHwnd()))
	{
		ASSERT(FALSE);
		return bResult;
	}

  // HighColorTab::UpdateImageList to change the internal image list to 24 bits colors)
  HighColorTab::UpdateImageList( *this );

	// If not in tree mode, stop here.
  if (!m_bTreeViewMode)
		// stop here, if we would like to use tabs
		return bResult;

	// ... and hide it
	pTab->ShowWindow(SW_HIDE);
	pTab->EnableWindow(FALSE);

	// Place another (empty) tab ctrl, to get a frame instead
	CRect	rectFrame;
	pTab->GetWindowRect(rectFrame);
	ScreenToClient(rectFrame);

	m_pFrame = CreatePageFrame();
	if (!m_pFrame)
	{
		ASSERT(FALSE);
		AfxThrowMemoryException();
	}
	m_pFrame->Create(WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS, rectFrame, this, 0xFFFF);
	m_pFrame->ShowCaption(m_bPageCaption);

	// Lets make place for the tree ctrl
	const int	nTreeWidth = m_nPageTreeWidth;

	CRect	rectSheet;
	GetWindowRect(rectSheet);
	rectSheet.right+= nTreeWidth;
	SetWindowPos(NULL, -1, -1, rectSheet.Width(), rectSheet.Height(), SWP_NOZORDER|SWP_NOMOVE);
	CenterWindow();

	MoveChildWindows(nTreeWidth, 0);

	// Lets calculate the rectangle for the tree ctrl
	CRect	rectTree(rectFrame);
	rectTree.right = rectTree.left + nTreeWidth - m_nSeparatorWidth;

	// calculate caption height
	CTabCtrl	wndTabCtrl;
	wndTabCtrl.Create(WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS, rectFrame, this, 0x1234);
	wndTabCtrl.InsertItem(0, _T(""));
	CRect	rectFrameCaption;
	wndTabCtrl.GetItemRect(0, rectFrameCaption);
	wndTabCtrl.DestroyWindow();
	m_pFrame->SetCaptionHeight(rectFrameCaption.Height());

	// if no caption should be displayed, make the window smaller in
	// height
	if (!m_bPageCaption)
	{
		// make frame smaller
		m_pFrame->GetWnd()->GetWindowRect(rectFrame);
		ScreenToClient(rectFrame);
		rectFrame.top+= rectFrameCaption.Height();
		m_pFrame->GetWnd()->MoveWindow(rectFrame);

		// move all child windows up
		MoveChildWindows(0, -rectFrameCaption.Height());

		// modify rectangle for the tree ctrl
		rectTree.bottom-= rectFrameCaption.Height();

		// make us smaller
		CRect	rect;
		GetWindowRect(rect);
		rect.top+= rectFrameCaption.Height()/2;
		rect.bottom-= rectFrameCaption.Height()-rectFrameCaption.Height()/2;
		if (GetParent())
			GetParent()->ScreenToClient(rect);
		MoveWindow(rect);
    CenterWindow();
	}

	// finally create the tree control
	const DWORD	dwTreeStyle = TVS_SHOWSELALWAYS|TVS_TRACKSELECT|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS;
	m_pwndPageTree = CreatePageTreeObject();
	if (!m_pwndPageTree)
	{
		ASSERT(FALSE);
		AfxThrowMemoryException();
	}
	
	// MFC7-support here (Thanks to Rainer Wollgarten)
  // YT: Cast tree control to CWnd and calls CWnd::CreateEx in all cases (VC 6 and7).
  ((CWnd*)m_pwndPageTree)->CreateEx(
    WS_EX_CLIENTEDGE|WS_EX_NOPARENTNOTIFY, 
    _T("SysTreeView32"), _T("PageTree"), 
    WS_TABSTOP|WS_CHILD|WS_VISIBLE|dwTreeStyle, 
    rectTree, this, s_unPageTreeId);
	
	if (m_bTreeImages)
	{
		m_pwndPageTree->SetImageList(&m_Images, TVSIL_NORMAL);
		m_pwndPageTree->SetImageList(&m_Images, TVSIL_STATE);
	}

  // TreePropSheetEx: Fix refresh problem.
	// Fill the tree ctrl
  {
    TreePropSheet::CWindowRedrawScope WindowRedrawScope( m_pwndPageTree, true );
    // Populate the tree control.
    RefillPageTree();
    // Expand the tree if necessary.
    if( IsAutoExpandTree() )
    {
      ExpandTreeItem( m_pwndPageTree, m_pwndPageTree->GetRootItem(), TVE_EXPAND );
    }
    // Select item for the current page
	  if (pTab->GetCurSel() > -1)
		  SelectPageTreeItem(pTab->GetCurSel());
  }
	return bResult;
}

/////////////////////////////////////////////////////////////////////
//
void CTreePropSheetBase::OnDestroy() 
{
	CPropertySheet::OnDestroy();
	
	// Fix for TN017
  if( m_pwndPageTree && m_pwndPageTree->m_hWnd )
    m_pwndPageTree->DestroyWindow();
  if( m_pFrame && m_pFrame->GetWnd()->m_hWnd )
    m_pFrame->GetWnd()->DestroyWindow();	

  if (m_Images.GetSafeHandle())
		m_Images.DeleteImageList();

	delete m_pwndPageTree;
	m_pwndPageTree = NULL;

	delete m_pFrame;
	m_pFrame = NULL;
}

/////////////////////////////////////////////////////////////////////
//
LRESULT CTreePropSheetBase::OnAddPage(WPARAM wParam, LPARAM lParam)
{
	LRESULT	lResult = DefWindowProc(PSM_ADDPAGE, wParam, lParam);
	if (!m_bTreeViewMode)
		return lResult;

  // TreePropSheetEx: Fix refresh problem.
  {
    TreePropSheet::CWindowRedrawScope WindowRedrawScope( m_pwndPageTree, true );
    RefillPageTree();
	  SelectCurrentPageTreeItem();
  }

	return lResult;
}

/////////////////////////////////////////////////////////////////////
//
LRESULT CTreePropSheetBase::OnRemovePage(WPARAM wParam, LPARAM lParam)
{
	LRESULT	lResult = DefWindowProc(PSM_REMOVEPAGE, wParam, lParam);
	if (!m_bTreeViewMode)
		return lResult;

  // TreePropSheetEx: Fix refresh problem.
  {
    TreePropSheet::CWindowRedrawScope WindowRedrawScope( m_pwndPageTree, true );
    RefillPageTree();
	  SelectCurrentPageTreeItem();
  }

	return lResult;
}

/////////////////////////////////////////////////////////////////////
//
LRESULT CTreePropSheetBase::OnSetCurSel(WPARAM wParam, LPARAM lParam)
{
	LRESULT	lResult = DefWindowProc(PSM_SETCURSEL, wParam, lParam);
	if (!m_bTreeViewMode)
		return lResult;

	SelectCurrentPageTreeItem();
	UpdateCaption();
	return lResult;
}

/////////////////////////////////////////////////////////////////////
//
LRESULT CTreePropSheetBase::OnSetCurSelId(WPARAM wParam, LPARAM lParam)
{
	LRESULT	lResult = DefWindowProc(PSM_SETCURSEL, wParam, lParam);
	if (!m_bTreeViewMode)
		return lResult;

	SelectCurrentPageTreeItem();
	UpdateCaption();
	return lResult;
}

/////////////////////////////////////////////////////////////////////
//
void CTreePropSheetBase::OnPageTreeSelChanging(NMHDR *pNotifyStruct, LRESULT *plResult)
{
  if( m_nRefillingPageTreeContent ) 
    return;

	*plResult = 0;

	NMTREEVIEW	*pTvn = reinterpret_cast<NMTREEVIEW*>(pNotifyStruct);
	int					nPage = m_pwndPageTree->GetItemData(pTvn->itemNew.hItem);
	BOOL				bResult;
  // Is the data item pointing to a valid page?
	if (nPage<0 || (unsigned)nPage>=m_pwndPageTree->GetCount())
	{
    // No, see if we are skipping empty page.
    if( IsTreeItemDisplayable( pTvn->itemNew.hItem ) ) 
    {
      // Skipping empty page, get the next valid page.
      HTREEITEM hNewItem = GetNextValidPageTreeItem( pTvn->itemNew.hItem );
      if( hNewItem )
        m_pwndPageTree->SelectItem( hNewItem );
      bResult = false;
    }
    else
    {
      // Not skipping empty pages, kill the current page so that we can display 
      // the generic message.
      bResult = KillActiveCurrentPage();
    }
  }
	else
  {
    if( IsTreeItemDisplayable( pTvn->itemNew.hItem ) )
    {
      // OK, set the new active page.
      TreePropSheet::CIncrementScope RefillingPageTreeContentGuard( m_nRefillingPageTreeContent );
      bResult = SetActivePage(nPage);
    }
    else
    {
      HTREEITEM hNewItem = GetNextValidPageTreeItem( pTvn->itemNew.hItem );
      if( hNewItem )
        m_pwndPageTree->SelectItem( hNewItem );
      bResult = false;
    }
  }

	if (!bResult)
		// prevent selection to change
		*plResult = TRUE;

	// Set focus to tree control (I guess that's what the user expects)
	m_pwndPageTree->SetFocus();

	return;
}

/////////////////////////////////////////////////////////////////////
//
void CTreePropSheetBase::OnPageTreeSelChanged(NMHDR *pNotifyStruct, LRESULT *plResult)
{
  UNREFERENCED_PARAMETER(pNotifyStruct);

  // Refilling the tree control, ignore selection change.
  if( m_nRefillingPageTreeContent ) 
    return;

  *plResult = 0;

	UpdateCaption();

	return;
}

/////////////////////////////////////////////////////////////////////
//
LRESULT CTreePropSheetBase::OnEnablePage(WPARAM wParam, LPARAM lParam)
{
  // Convert parameters
  CPropertyPage* pPage = reinterpret_cast<CPropertyPage*>( wParam );
  bool bEnable = lParam?true:false;

  // Make sure that this page is inside this sheet.

  // Enable/Disable the page.
  EnablePage( pPage, bEnable );
  return 1L;
}

/////////////////////////////////////////////////////////////////////
//
LRESULT CTreePropSheetBase::OnIsDialogMessage(WPARAM wParam, LPARAM lParam)
{
  MSG *pMsg = reinterpret_cast<MSG*>(lParam);
  ASSERT( pMsg );

  if (pMsg->message==WM_KEYDOWN && GetKeyState(VK_CONTROL)&0x8000)
  {
    if( pMsg->wParam==VK_TAB )
    {
      if (GetKeyState(VK_SHIFT)&0x8000)
      {
        ActivatePreviousPage(); 
      }
      else    
      {
        ActivateNextPage(); 
      }
    }
    else
    {
      if( pMsg->wParam==VK_PRIOR )      /*PageUp*/
      {
        ActivatePreviousPage();
      }
      else
      {
        if( pMsg->wParam==VK_NEXT )     /*PageDown*/
        {
          ActivateNextPage();
        }
      }
    }
    return TRUE; 
  }

	return CPropertySheet::DefWindowProc(PSM_ISDIALOGMESSAGE, wParam, lParam);
}

/////////////////////////////////////////////////////////////////////
//
BOOL CTreePropSheetBase::PreTranslateMessage(MSG* pMsg) 
{
  if( pMsg->hwnd == GetPageTreeControl()->GetSafeHwnd() )
  {
    // If not in skipping empty page mode, keep the standard behavior.
    if( !m_bSkipEmptyPages )
      return CPropertySheet::PreTranslateMessage(pMsg);

    if( pMsg->message == WM_KEYDOWN )
    {
      // Get the current tree item.
      HTREEITEM hCurrentItem = m_pwndPageTree->GetSelectedItem();
      if( NULL == hCurrentItem )
        return TRUE;

      if( pMsg->wParam == VK_UP )
      {
        // Active the previous page according to tree ordering - 
        // skipping empty pages on the way.
        ActivatePreviousPage( hCurrentItem );
   	    return TRUE;
      }
      else if ( pMsg->wParam == VK_DOWN )
      {
        // Active the next page according to tree ordering -
        // skipping empty pages on the way.
        ActivateNextPage( hCurrentItem );
  	    return TRUE;
      }
      else if( pMsg->wParam == VK_LEFT )
      {
        /* Here, we try to mimic the tree keyboard handling by doing 
           one of the two things:the following
           - If the tree item is expanded, collapse it
           - If the tree item is collapse, find a parent item that has a page
             associated with it and select it, collapsing all items along the 
             way. */
        if( IsItemExpanded( hCurrentItem ) )
        {
          // Collapse the item since it is expanded.
          m_pwndPageTree->Expand( hCurrentItem, TVE_COLLAPSE );
        }
        else
        {
          // Already collapsed, search for a candidate for selection.
          HTREEITEM hItem = m_pwndPageTree->GetParentItem( hCurrentItem );
          while( NULL != hItem && !HasValidPropertyPageAssociated( hItem ) )
          {
            // Add item to the stack.
            hItem = m_pwndPageTree->GetParentItem( hItem );
          }
          // If the item points to a valid page, select it and collapse 
          if( NULL != hItem && HasValidPropertyPageAssociated( hItem ) )
          {
            m_pwndPageTree->SelectItem( hItem );
          }
        }
        return TRUE;
      }
      else if( pMsg->wParam == VK_RIGHT )
      {
        /* Here, we try to mimic the tree keyboard handling by doing 
           one of the two things:the following
           - If the tree item is collapsed, expand it
           - If the tree item is expanded, find a child item that has a page
             associated with it and select it, expanding all items along the 
             way. The child has to be a first child in the hierarchy. */
        if( IsItemExpanded( hCurrentItem ) )
        {
          // Already expanded, search for a candidate for selection.
          HTREEITEM hItem = m_pwndPageTree->GetChildItem( hCurrentItem );
          while( NULL != hItem && !HasValidPropertyPageAssociated( hItem ) )
          {
            // Add item to the stack.
            hItem = m_pwndPageTree->GetChildItem( hItem );
          }
          // If the item points to a valid page, select it and collapse 
          if( NULL != hItem && HasValidPropertyPageAssociated( hItem ) )
          {
            m_pwndPageTree->SelectItem( hItem );
          }
        }
        else
        {
          // Expand the item since it is collapsed.
          m_pwndPageTree->Expand( hCurrentItem, TVE_EXPAND );
        }
        return TRUE;
      }
    }
  }
  else if( WM_ENABLE == pMsg->message)
  {
    // Handle WM_ENABLE messages for property pages: Update the property page
    // information map.
    TRACE("");

  }

	return CPropertySheet::PreTranslateMessage(pMsg);
}

} //namespace TreePropSheet

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -