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

📄 collapsiblepanel.h

📁 这是一本学习 window编程的很好的参考教材
💻 H
📖 第 1 页 / 共 4 页
字号:
	}
	void _CreateButton(CDCHandle dc, int iIndex, RECT rcItem)
	{
		// Create bitmap for button-background
		PANEL& panel = m_aPanels[iIndex];
		::OffsetRect(&rcItem, -rcItem.left, -rcItem.top);
		int cx = rcItem.right - rcItem.left;
		int cy = rcItem.bottom - rcItem.top;
		CDC dcMem;
		dcMem.CreateCompatibleDC(dc);
		CBitmapHandle bmp;
		bmp.CreateCompatibleBitmap(dc, cx, cy);
		HBITMAP hOldBmp = dcMem.SelectBitmap(bmp);
		// Clear background
		dcMem.FillSolidRect(&rcItem, m_Theme.clrBack);
		// Figure out colors
		COLORREF clrBar1 = panel.clrBar1;
		if( clrBar1 == CLR_INVALID ) clrBar1 = m_Theme.clrBarActive1;
		if( iIndex == m_iCurSel && (m_dwExtStyle & CPS_EX_SELHIGHLIGHT) != 0 ) clrBar1 = m_Theme.clrBarSel1;
		if( !panel.bEnabled ) clrBar1 = m_Theme.clrBarInactive1;
		COLORREF clrBar2 = panel.clrBar2;
		if( clrBar2 == CLR_INVALID ) clrBar2 = m_Theme.clrBarActive2;
		if( iIndex == m_iCurSel && (m_dwExtStyle & CPS_EX_SELHIGHLIGHT) != 0 ) clrBar2 = m_Theme.clrBarSel2;
		if( !panel.bEnabled ) clrBar2 = m_Theme.clrBarInactive2;
		// Draw stuff
		if( (m_dwExtStyle & CPS_EX_OWNERDRAW) != 0 )
		{
#ifndef ODS_INACTIVE
			const UINT ODS_INACTIVE = 0x0080;
#endif
			DRAWITEMSTRUCT dis = { 0 };
			dis.CtlID = GetDlgCtrlID();
			dis.CtlType = ODT_STATIC;
			dis.itemAction = ODA_DRAWENTIRE;
			dis.hwndItem = m_hWnd;
			dis.hDC = dc;
			dis.itemID = iIndex;
			dis.itemState = 0;
			if( m_iCurSel == iIndex ) dis.itemState |= ODS_SELECTED;
			if( !panel.bExpanded ) dis.itemState |= ODS_INACTIVE;
			if( !panel.bEnabled ) dis.itemState |= ODS_DISABLED;
			dis.rcItem = GetPanelRect(iIndex, FALSE);
			::SendMessage(GetParent(), WM_DRAWITEM, (WPARAM) dis.CtlID, (LPARAM) &dis);
		}
		else if( (m_dwExtStyle & CPS_EX_FLATSTYLE) != 0 )
		{
			CPen pen;
			pen.CreatePen(PS_SOLID, 1, clrBar2);
			CBrush brush;
			brush.CreateSolidBrush(clrBar1);
			HPEN hOldPen = dcMem.SelectPen(pen);
			HBRUSH hOldBrush = dcMem.SelectBrush(brush);
			dcMem.Rectangle(&rcItem);
			dcMem.SelectBrush(hOldBrush);
			dcMem.SelectPen(hOldPen);
		}
		else
		{
			// Prepare brushes and pens
			CPen pen;
			pen.CreatePen(PS_SOLID, 1, clrBar2);
			CBrush brush;
			brush.CreateSolidBrush(clrBar1);
			HPEN hOldPen = dcMem.SelectPen(pen);
			HBRUSH hOldBrush = dcMem.SelectBrush(brush);
			// Create clip region
			CRgn rgn;
			rgn.CreateRoundRectRgn(rcItem.left, rcItem.top, rcItem.right, rcItem.bottom + 666, m_Theme.iArc, m_Theme.iArc);
			dcMem.SelectClipRgn(rgn);
			// Paint gradient
			dcMem.FillSolidRect(&rcItem,iIndex==m_iCurSel?RGB(240,241,245): m_Theme.clrBack);
			//if( dcMem.GetDeviceCaps(BITSPIXEL) > 8 ) {
			//	// This will make 2^6 = 64 fountain steps
			//	const int nShift = 6;
			//	int nSteps = 1 << nShift;
			//	for( int i = 0; i < nSteps; i++ ) {
			//		// Do a little alpha blending
			//	/*	BYTE bR = (BYTE) ((GetRValue(clrBar1) * (nSteps - i) +
			//			GetRValue(clrBar2) * i) >> nShift);
			//		BYTE bG = (BYTE) ((GetGValue(clrBar1) * (nSteps - i) +
			//			GetGValue(clrBar2) * i) >> nShift);
			//		BYTE bB = (BYTE) ((GetBValue(clrBar1) * (nSteps - i) +
			//			GetBValue(clrBar2) * i) >> nShift);*/
			//		// then paint with the resulting color
			//		RECT r2 = rcItem;
			//		r2.left = rcItem.left + ((i * (rcItem.right - rcItem.left)) >> nShift);
			//		r2.right = rcItem.left + (((i + 1) * (rcItem.right - rcItem.left)) >> nShift);
			//		if( (r2.right - r2.left) > 0 ) dcMem.FillSolidRect(&rcItem,clrBar2/*RGB(bR,bG,bB)*/);
			//	}
			//}
			dcMem.SelectClipRgn(NULL);
			// Repaint frame
			dcMem.SelectStockBrush(NULL_BRUSH);
			dcMem.RoundRect(rcItem.left, rcItem.top, rcItem.right, rcItem.bottom + 666, m_Theme.iArc, m_Theme.iArc);
			// Done
			dcMem.SelectBrush(hOldBrush);
			dcMem.SelectPen(hOldPen);
		}
		dcMem.SelectBitmap(hOldBmp);
		panel.hbmpButton = bmp.Detach();
	}

	// Message map and handlers

	BEGIN_MSG_MAP(CTabPanelImpl)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		MESSAGE_HANDLER(WM_VSCROLL, OnVScroll)
		MESSAGE_HANDLER(WM_TIMER, OnTimer)
		MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
		MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDown)
		CHAIN_MSG_MAP( COffscreenDrawRect< T > )
	END_MSG_MAP()

	LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		LRESULT lRes = DefWindowProc();
		_Init();
		return lRes;
	}
	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		RemoveAllItems();
		if( m_bOwnCollapseIcons ) {
			if( !m_iconCollapse.IsNull() ) m_iconCollapse.DestroyIcon();
			if( !m_iconExpand.IsNull() ) m_iconExpand.DestroyIcon();
		}
		if( (m_dwExtStyle & CPS_EX_SHAREIMAGELIST) == 0 ) {
			if( m_Images.IsNull() ) m_Images.Destroy();
			if( m_ImagesGrey.IsNull() ) m_ImagesGrey.Destroy();
		}
		bHandled = FALSE;
		return 0;
	}
	LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
	{
		if( m_cxLastWidth != LOWORD(lParam) ) {
			m_cxLastWidth = LOWORD(lParam);
			_RecalcLayout();
			_RearrangePanels();
			_RecalcScrollBar();
		}
		if( m_cyLastHeight != HIWORD(lParam) ) {
			m_cyLastHeight = HIWORD(lParam);
			_RecalcScrollBar();
		}
		bHandled = FALSE;
		return 0;
	}
	LRESULT OnTimer(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = FALSE;
		if( wParam != ANIMATETIMER_ID ) return 0;
		// Process movement of any animating panel
		bool bStillAnimating = false;
		DWORD dwTick = ::GetTickCount();
		for( int i = 0; i < m_aPanels.GetSize(); i++ ) {
			if( m_aPanels[i].dwAnimateStopTime > 0 ) {
				PANEL& panel = m_aPanels[i];
				if( dwTick >= panel.dwAnimateStopTime ) {
					// Done animating this panel
					panel.dwAnimateStopTime = 0;
					panel.cy = panel.bExpanded ? panel.szChild.cy : 0;
					// Show/hide child window
					::ShowWindow(panel.hWnd, /*panel.bExpanded ?*/ SW_SHOWNOACTIVATE /*: SW_HIDE*/);
					// Send notification
					::SendMessage(GetParent(), WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(), CPN_EXPANDED), (LPARAM) m_hWnd);
				}
				else 
				{
					// TODO: Need to calculate height based on the current time
					//       relative to the start time to favour slow machines.
					int iDiff = panel.bExpanded ? panel.szChild.cy - panel.cy : panel.cy;
					iDiff /= 2;
					panel.cy = panel.bExpanded ? panel.szChild.cy - iDiff : iDiff;
					bStillAnimating = true;
				}
			}
		}
		_RearrangePanels();
		if( !bStillAnimating ) 
		{
			_RecalcScrollBar();
			KillTimer(ANIMATETIMER_ID);
		}
		return 0;
	}
	LRESULT OnVScroll(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		// Scrollbar support added by Anatoly Ivasyuk
		// Get all the vertial scroll bar information
		SCROLLINFO si = { 0 };
		si.cbSize = sizeof(si);
		si.fMask  = SIF_ALL;
		GetScrollInfo(SB_VERT, &si);  
		// Save the position for comparison later on
		int yPos = si.nPos;  
		switch( LOWORD(wParam) ) {
case SB_TOP:
	// User clicked the HOME keyboard key
	si.nPos = si.nMin;
	break;           
case SB_BOTTOM:
	// User clicked the END keyboard key
	si.nPos = si.nMax;
	break;          
case SB_LINEUP:
	// User clicked the top arrow
	si.nPos -= 1;
	break;           
case SB_LINEDOWN:
	// User clicked the bottom arrow
	si.nPos += 1;
	break;           
case SB_PAGEUP:
	// User clicked the shaft above the scroll box
	si.nPos -= si.nPage;
	break;           
case SB_PAGEDOWN:
	// User clicked the shaft below the scroll box
	si.nPos += si.nPage;
	break;           
case SB_THUMBTRACK:
	// User dragged the scroll box
	si.nPos = si.nTrackPos;
	break;           
default:
	break; 
		}
		// Set the position and then retrieve it.  Due to adjustments
		//   by Windows it may not be the same as the value set.
		si.fMask = SIF_POS;
		SetScrollInfo(SB_VERT, &si, TRUE);
		GetScrollInfo(SB_VERT, &si);
		if( si.nPos != yPos ) {                    
			_RecalcLayout();
			_RearrangePanels();
			Invalidate();
		}       
		return 0;
	}
	LRESULT OnLButtonDown(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
	{
		POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
		for( int i = 0; i < m_aPanels.GetSize(); i++ ) {
			
			RECT rc ={0};
			rc.bottom=m_cyButton;
			rc.left=i*(m_cxButton+5);
			rc.right=rc.left+m_cxButton;
			
			//if( (m_dwExtStyle & CPS_EX_EXPANDCLICK) != 0 ) ::SetRect(&rc, rc.right - 30, rc.top + 3, rc.right, rc.bottom - 3);
			if( ::PtInRect(&rc, pt) ) {
				SetCurSel(i) ;
				if( GetItemEnabled(i) ) {
					

					SetItemExpanded(i, !GetItemExpanded(i), TRUE);
					if( (m_dwExtStyle & CPS_EX_SELHIGHLIGHT) != 0 ) _RecalcLayout();
					break;
				}
				
			}
			

		}
		return 0;
	}

	// Paint override

	void DoPaint(CDCHandle dc, RECT& rect)
	{
		ATLASSERT(!m_iconExpand.IsNull());

		RECT rcClient;
		GetClientRect(&rcClient);

		dc.FillSolidRect(&rect, m_Theme.clrBack);

		::InflateRect(&rcClient, -m_szMargin.cx, -m_szMargin.cy);

		HFONT hOldFont = dc.SelectFont(GetFont());
		dc.SetBkMode(TRANSPARENT);
		
		RECT rcItem ={0};
		rcItem.bottom=m_cyButton;
		rcItem.right=0;
			// Should we paint this button at all?
		
		for( int i = 0; i < m_aPanels.GetSize(); i++ ) {
			
			
			rcItem.left=i*(m_cxButton+5)+m_szMargin.cx;
			rcItem.right=rcItem.left+m_cxButton;
			RECT rcButton = rcItem;
			
			RECT rcDummy = { 0 };
			if( !::IntersectRect(&rcDummy, &rect, &rcButton) ) continue;
			// Recreate button bitmap?
			const PANEL& panel = m_aPanels[i];
			RECT rcBar = { rcButton.left, rcButton.bottom - m_cyBar, rcButton.right, rcButton.bottom };
			if (i==m_iCurSel) {
				rcBar.bottom+=m_cyButton;
			}
			if( panel.hbmpButton == NULL ) _CreateButton(dc, i, rcBar);
			ATLASSERT(panel.hbmpButton!=NULL);
			// Paint button
			CDC dcBmp;
			dcBmp.CreateCompatibleDC(dc);
			HBITMAP hOldBmp = dcBmp.SelectBitmap(panel.hbmpButton);
			dc.BitBlt(rcBar.left, rcBar.top, rcBar.right - rcBar.left, rcBar.bottom, dcBmp, 0, 0, SRCCOPY);
			dcBmp.SelectBitmap(hOldBmp);
			// Rect for text
			RECT rcText = rcButton;
			rcText.left += 5;
			rcText.right -= 4;
			rcText.top = rcText.bottom - m_cyBar;
			
			// Add expander
			if( (m_dwExtStyle & CPS_EX_NOEXPANDBUTTON) == 0 ) {
				dc.DrawIconEx(rcBar.right - 24, rcBar.top + 3, i!=m_iCurSel? m_iconCollapse : m_iconExpand, 16, 16);
				rcText.right -= 26;
			}
			// Add icon
			if( panel.iImage >= 0 && !m_Images.IsNull() ) {
				SIZE szIcon;
				m_Images.GetIconSize(szIcon);
				POINT pt = { rcItem.left + 2, rcItem.top + 2 };
				if( !panel.bEnabled && !m_ImagesGrey.IsNull() ) {
					m_ImagesGrey.Draw(dc, panel.iImage, pt, ILD_TRANSPARENT);
				}
				else {
					m_Images.Draw(dc, panel.iImage, pt, ILD_TRANSPARENT);
				}
				rcText.left += szIcon.cx;
			}
			// Print text
			COLORREF clrText = panel.clrText;
			if( clrText == CLR_INVALID ) clrText = m_Theme.clrTextActive;
			if( i == m_iCurSel && (m_dwExtStyle & CPS_EX_SELHIGHLIGHT) != 0 ) clrText = m_Theme.clrTextSel;
			if( !m_aPanels[i].bEnabled ) clrText = m_Theme.clrTextInactive;
			dc.SetTextColor(clrText);

			/*SIZE size;
			GetTextExtentPoint32(dc,panel.pstrTitle, strlen(panel.pstrTitle), &size);
			rcText.right=rcText.left+size.cx;
			rcText.bottom=rcText.top+size.cy;*/


			dc.DrawText(panel.pstrTitle, -1, &rcText, DT_SINGLELINE | DT_END_ELLIPSIS | DT_VCENTER);
			// Optional border around child
			if( GetStyle() & WS_BORDER ) {
				RECT rcChild = rcItem;
				rcChild.top += m_cyButton;
				if (i==m_iCurSel) {
					rcChild.bottom+=m_cyButton;
				}
				CPen pen;
				pen.CreatePen(PS_SOLID, 1, m_Theme.clrBorder);
				HPEN hOldPen = dc.SelectPen(pen);
				HBRUSH hOldBrush = dc.SelectStockBrush(NULL_BRUSH);
				dc.Rectangle(&rcChild);
				dc.SelectBrush(hOldBrush);
				dc.SelectPen(hOldPen);
			}
			
		}
		dc.SelectFont(hOldFont);
	}
};

class CTabPanelCtrl : public CTabPanelImpl<CTabPanelCtrl>
{
public:
	DECLARE_WND_CLASS(_T("WTL_TabPanel"))
};
////////////////////////////////////////////////////////////////////////////////////
#endif // !defined(AFX_COLLAPSIBLEPANEL_H__20031129_797C_31F4_B029_0080AD509054__INCLUDED_)

⌨️ 快捷键说明

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