📄 statictreectrl.cpp
字号:
SetScrollPos( SB_VERT, 0 );
}
else
{
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_PAGE | SIF_RANGE;
si.nPage = rFrame.Height();
si.nMax = m_iDocHeight + 8;
si.nMin = 0 ;
SetScrollInfo( SB_VERT, &si );
EnableScrollBarCtrl( SB_VERT, TRUE );
}
m_bScrollBarMessage = FALSE;
}
HTREENODE CStaticTreeCtrl::FindNodeByPoint( const CPoint& point, HTREENODE pNode )
{
HTREENODE pFound = NULL;
// Found it?
if( pNode->rNode.PtInRect( point ) )
pFound = pNode;
// If this node isn't it then check the node's childs if it is open and there are any
if( pFound == NULL && pNode->bOpen && pNode->pChild != NULL )
pFound = FindNodeByPoint( point, pNode->pChild );
// If didn't find it among the node's childs, then check the next sibling
if( pFound == NULL && pNode->pSibling != NULL )
pFound = FindNodeByPoint( point, pNode->pSibling );
return pFound;
}
/*BOOL CStaticTreeCtrl::NodeTextDlg( CString& csText )
{
BOOL bRet = FALSE;
CDLG_TreeNodeText tntDlg;
tntDlg.m_csItemText = csText;
if( tntDlg.DoModal() == IDOK )
{
csText = tntDlg.m_csItemText;
bRet = TRUE;
}
return bRet;
}*/
/////////////////////////////////////////////////////////////////////////////
// CStaticTreeCtrl message handlers
void CStaticTreeCtrl::OnPaint()
{
CPaintDC dc(this); // Device context for painting
// Double-buffering
CDC* pDCMem = new CDC;
CBitmap* pOldBitmapHpxs = NULL;
CBitmap bmpCanvas;
CRect rFrame;
GetClientRect( rFrame );
pDCMem->CreateCompatibleDC( &dc );
bmpCanvas.CreateCompatibleBitmap( &dc, rFrame.Width(), rFrame.Height() );
pOldBitmapHpxs = pDCMem->SelectObject( &bmpCanvas );
// START DRAW -------------------------------------------------
// If there is a bitmap loaded, use it
// Otherwise, paint the background white
if( m_bmpBackground.GetSafeHandle() != NULL )
{
CDC* pDCTemp = new CDC;;
BITMAP bmp;
pDCTemp->CreateCompatibleDC( &dc );
m_bmpBackground.GetBitmap( &bmp );
// Select the bitmap into the temp device context
CBitmap* pOldBitmap = (CBitmap*) pDCTemp->SelectObject( &m_bmpBackground );
// Stretch the bitmap to fill the entire control area
pDCMem->StretchBlt( 0, 0, rFrame.Width(), rFrame.Height(), pDCTemp, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY );
pDCTemp->SelectObject( pOldBitmap );
delete pDCTemp;
}
else
pDCMem->FillSolidRect( rFrame, RGB(255,255,255) );
UINT nMode = pDCMem->SetBkMode( TRANSPARENT );
CFont* pOldFont = pDCMem->SelectObject( &m_Font );
int iLastNodePos = 0;
if( m_pTopNode->pChild != NULL )
{
iLastNodePos = DrawNodesRecursive( pDCMem, m_pTopNode->pChild,
rFrame.left + m_iIndent,
m_iPadding - GetScrollPos( SB_VERT ),
rFrame );
if( m_bShowLines )
DrawLinesRecursive( pDCMem, m_pTopNode->pChild );
}
pDCMem->SelectObject( pOldFont );
pDCMem->SetBkMode( nMode );
pDCMem->Draw3dRect( rFrame, RGB(0,0,0), RGB(0,0,0) ); // Border
// END DRAW -------------------------------------------------
dc.BitBlt( 0, 0, rFrame.Width(), rFrame.Height(), pDCMem, 0, 0, SRCCOPY );
pDCMem->SelectObject( pOldBitmapHpxs );
//hpxs添加
bmpCanvas.DeleteObject();
delete pDCMem;
// Has the total document height changed?
if( iLastNodePos != m_iDocHeight )
{
BOOL bInvalidate = ( ( m_iDocHeight < rFrame.Height() ) != ( iLastNodePos < rFrame.Height() ) );
m_iDocHeight = iLastNodePos;
ResetScrollBar();
// If the scrollbar has just been hidden/shown, repaint
if( bInvalidate )
Invalidate();
}
}
void CStaticTreeCtrl::OnSize(UINT nType, int cx, int cy)
{
// Setting the scroll sends its own size message. Prevent it thus avoiding an ugly loop.
// Other than that, resizing the control means that the tree height may change (word-wrap).
if( !m_bScrollBarMessage )
ResetScrollBar();
CStatic::OnSize(nType, cx, cy);
}
void CStaticTreeCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
int iScrollBarPos = GetScrollPos( SB_VERT );
CRect rFrame;
GetClientRect( rFrame );
switch( nSBCode )
{
case SB_LINEUP:
iScrollBarPos = max( iScrollBarPos - m_iLineHeight, 0 );
break;
case SB_LINEDOWN:
iScrollBarPos = min( iScrollBarPos + m_iLineHeight, GetScrollLimit( SB_VERT ) );
break;
case SB_PAGEUP:
iScrollBarPos = max( iScrollBarPos - rFrame.Height(), 0 );
break;
case SB_PAGEDOWN:
iScrollBarPos = min( iScrollBarPos + rFrame.Height(), GetScrollLimit( SB_VERT ) );
break;
case SB_THUMBTRACK:
case SB_THUMBPOSITION:
iScrollBarPos = nPos;
break;
}
SetScrollPos( SB_VERT, iScrollBarPos );
Invalidate();
CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}
LRESULT CStaticTreeCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if( message == WM_NCHITTEST || message == WM_NCLBUTTONDOWN || message == WM_NCLBUTTONDBLCLK )
return ::DefWindowProc( m_hWnd, message, wParam, lParam );
return CStatic::WindowProc(message, wParam, lParam);
}
void CStaticTreeCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
HTREENODE pClickedOn = NULL; // Assume no node was clicked on
if( m_pTopNode->pChild != NULL) // If the tree is populated, search it
pClickedOn = FindNodeByPoint( point, m_pTopNode->pChild );
if( pClickedOn != NULL ) // If a node was clicked on
ToggleNode( pClickedOn, TRUE );
else
CStatic::OnLButtonUp(nFlags, point);
}
/*BOOL CStaticTreeCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
// zDelta greater than 0, means rotating away from the user, that is, scrolling up
OnVScroll( ( zDelta > 0 )? SB_LINEUP:SB_LINEDOWN, 0, NULL );
return CStatic::OnMouseWheel(nFlags, zDelta, pt);
}
void CStaticTreeCtrl::OnContextMenu(CWnd* , CPoint point)
{
CPoint cp( point );
// WM_CONTEXTMENU passes absolute coordinates, we need them local
ScreenToClient( &cp );
// Find the node that has been clicked on
if( m_pTopNode->pChild == NULL )
m_pSelected = NULL; // Empty tree
else
m_pSelected = FindNodeByPoint( cp, m_pTopNode->pChild );
CContextMenu ccmPopUp;
ccmPopUp.CreatePopupMenu();
// Customize the menu appearance and behavior
ccmPopUp
.ToggleSound ( m_bAudioOn )
.SetTextFont ( &m_Font )
.SetColors ( RGB(70,36,36), RGB(253,249,249), RGB(172,96,96), RGB(244,234,234), RGB(182,109,109) );
// Get a device context so that it'll be possible for the context menu
// to calculate the size of the menu item's text
CDC *pDC = GetDC();
int iSaved = pDC->SaveDC();
CFont* pOldFont = pDC->SelectObject( &m_Font );
// ADDING MENU ITEMS - Start
// If a node has been clicked on, use the first 45 chars of its text as the
// first menu item (always disabled)
if( m_pSelected != NULL )
{
CString csDots = ( m_pSelected->csLabel.GetLength() > 45 )? _T("..."):_T("");
CString cs = m_pSelected->csLabel.Left( 45 ) + csDots;
ccmPopUp.AppendMenuItem( MF_DISABLED, WM_APP, cs, _T(""), pDC );
ccmPopUp.AppendMenuItem( MF_SEPARATOR, 0, _T(""), _T(""), pDC );
}
UINT nFlag = ( m_pSelected != NULL )? MF_ENABLED:MF_GRAYED;
// Node related items
ccmPopUp.AppendMenuItem( MF_ENABLED, CM_INSERTCHILD, _T("Insert Child"), _T("insertChild.wav"), pDC );
ccmPopUp.AppendMenuItem( nFlag, CM_INSERTSIBLING, _T("Insert Sibling"), _T("insertSibling.wav"), pDC );
ccmPopUp.AppendMenuItem( nFlag, CM_DELETENODE, _T("Delete Node"), _T("deleteNode.wav"), pDC );
ccmPopUp.AppendMenuItem( nFlag, CM_MODIFYNODETEXT, _T("Modify Node Text"), _T("modifyNodeText.wav"), pDC );
ccmPopUp.AppendMenuItem( nFlag, CM_CHANGENODECOLOR, _T("Change Node Color"), _T("changeNodeColor.wav"), pDC );
ccmPopUp.AppendMenuItem( MF_SEPARATOR, 0, _T(""), _T(""), pDC );
// Connecting lines related items
ccmPopUp.AppendMenuItem( MF_ENABLED, CM_TOGGLECONNECTINGLINES, _T("Toggle Connecting Lines"), _T("toggleConnectingLines.wav"), pDC );
ccmPopUp.AppendMenuItem( MF_ENABLED, CM_SETCONNECTINGLINESCOLOR, _T("Set Connecting Lines Color"), _T("setConnectingLinesColor.wav"), pDC );
ccmPopUp.AppendMenuItem( MF_SEPARATOR, 0, _T(""), _T(""), pDC );
// Tree appearance items
ccmPopUp.AppendMenuItem( MF_ENABLED, CM_SETFONT, _T("Set Font"), _T("setFont.wav"), pDC );
ccmPopUp.AppendMenuItem( MF_ENABLED, CM_SETDEFAULTCOLOR, _T("Set Default Text Color"), _T("setDefaultColor.wav"), pDC );
ccmPopUp.AppendMenuItem( MF_ENABLED, CM_SETBACKGROUNDBITMAP, _T("Set Background Bitmap"), _T("setBackgroundBitmap.wav"), pDC );
ccmPopUp.AppendMenuItem( MF_SEPARATOR, 0, _T(""), _T(""), pDC );
// Context menu sound toggle item
ccmPopUp.AppendMenuItem( MF_ENABLED, CM_TOGGLEMENUSOUND, _T("Toggle Menu Sound"), _T("toggleMenuSound.wav"), pDC );
// ADDING MENU ITEMS - End
// Display the context menu
ccmPopUp.TrackPopupMenu( TPM_LEFTALIGN, point.x, point.y, this );
// Clean up
pDC->SelectObject( pOldFont );
pDC->RestoreDC( iSaved );
ReleaseDC( pDC );
}
*/
/*void CStaticTreeCtrl::OnCM_InsertChild()
{
CString csText("");
if( NodeTextDlg( csText ) == TRUE )
{
if( m_pSelected == NULL )
InsertChild( m_pTopNode, csText );
else
{
InsertChild( m_pSelected, csText );
m_pSelected = NULL;
}
Invalidate();
}
}*/
/*void CStaticTreeCtrl::OnCM_InsertSibling()
{
CString csText("");
if( NodeTextDlg( csText ) == TRUE )
{
InsertSibling( m_pSelected, csText );
m_pSelected = NULL;
Invalidate();
}
}
void CStaticTreeCtrl::OnCM_DeleteNode()
{
DeleteNode( m_pSelected, TRUE );
m_pSelected = NULL;
}
void CStaticTreeCtrl::OnCM_ModifyNodeText()
{
if( NodeTextDlg( m_pSelected->csLabel ) == TRUE )
{
m_pSelected = NULL;
Invalidate();
}
}
void CStaticTreeCtrl::OnCM_ChangeNodeColor()
{
COLORREF cr = ( m_pSelected->bUseDefaultTextColor )? m_crDefaultTextColor:m_pSelected->crText;
CColorDialog ccd( cr, CC_FULLOPEN | CC_ANYCOLOR );
if ( ccd.DoModal() == IDOK )
SetNodeColor( m_pSelected, ccd.GetColor(), TRUE );
m_pSelected = NULL;
}
void CStaticTreeCtrl::OnCM_ToggleConnectingLines()
{
m_bShowLines = !m_bShowLines;
Invalidate();
}
void CStaticTreeCtrl::OnCM_SetConnectingLinesColor()
{
CColorDialog ccd( m_crConnectingLines, CC_FULLOPEN | CC_ANYCOLOR );
if ( ccd.DoModal() == IDOK )
{
m_crConnectingLines = ccd.GetColor();
Invalidate();
}
}
void CStaticTreeCtrl::OnCM_SetFont()
{
CFontDialog cfd( &m_lgFont , CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT );
if( cfd.DoModal() == IDOK )
{
SetTextFont( cfd.GetSize() / 10, cfd.IsBold(), cfd.IsItalic(), cfd.GetFaceName() );
Invalidate();
}
}
void CStaticTreeCtrl::OnCM_SetDefaultColor()
{
CColorDialog ccd( m_crDefaultTextColor, CC_FULLOPEN | CC_ANYCOLOR );
if ( ccd.DoModal() == IDOK )
{
m_crDefaultTextColor = ccd.GetColor();
Invalidate();
}
}
void CStaticTreeCtrl::OnCM_SetBackgroundBitmap()
{
SetBackgroundBitmap( TRUE );
}
void CStaticTreeCtrl::OnCM_ToggleMenuSound()
{
m_bAudioOn = !m_bAudioOn;
}
*/
void CStaticTreeCtrl::SetNodeText(HTREENODE pNode, CString strText)
{
pNode->csLabel = strText;
Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -