#include "stdafx.h" #include "resource.h" #include "GroupBox.h" #define WM_CHILD_SIZE WM_USER+10 BEGIN_MESSAGE_MAP(WGroupBox,CDialog) ON_WM_NCPAINT() ON_WM_NCLBUTTONDOWN() ON_WM_NCLBUTTONDBLCLK() ON_WM_NCHITTEST() ON_WM_NCACTIVATE() END_MESSAGE_MAP() BOOL WGroupBox::Create(UINT nIDTemplate,CWnd*pParentWnd) { if(!CDialog::Create(nIDTemplate,pParentWnd)) return FALSE; CRect rect; GetWindowRect(rect); m_initSize.cx=rect.Width(); m_initSize.cy=rect.Height(); Fold(); return TRUE; } BOOL WGroupBox::PreTranslateMessage(MSG* pMsg) { if(pMsg->message==WM_KEYDOWN) { int nVirtKey = (int)pMsg->wParam; // virtual-key code if(nVirtKey==VK_RETURN) { UpdateData(); return TRUE; } else if(nVirtKey==VK_ESCAPE) return TRUE; else if(VK_TAB==nVirtKey&&GetFocus()==this) { GetParent()->SetFocus(); return TRUE; } } return CDialog::PreTranslateMessage(pMsg); } BOOL WGroupBox::OnNcActivate(BOOL bActive) { BOOL bRet=CDialog::OnNcActivate(bActive); m_bActive=bActive==TRUE; RedrawWindow(); return bRet; } void WGroupBox::OnNcPaint() { CRect rectClient,rectWindow; GetClientRect(rectClient); GetWindowRect(rectWindow); int height=20,width=rectWindow.Width(); CWindowDC dc(this); dc.SetMapMode(MM_TEXT); CPoint pts[6]; pts[0].x=height/3; pts[0].y=0; pts[1].x=width-height/3; pts[1].y=0; pts[2].x=width; pts[2].y=height/3; pts[3].x=width; pts[3].y=height; pts[4].x=0; pts[4].y=height; pts[5].x=0; pts[5].y=height/3; COLORREF colorTitle=RGB(190,190,190); if(m_bActive) colorTitle=GetSysColor(COLOR_ACTIVECAPTION); CPen pen(PS_SOLID, 1,colorTitle); CBrush brush(colorTitle); CPen* pOldPen = dc.SelectObject(&pen); CBrush* pOldBrush = dc.SelectObject(&brush); dc.Polygon(pts, 6); dc.SelectObject(pOldPen); dc.SelectObject(pOldBrush); CString sTitle; GetWindowText(sTitle); dc.SetTextColor(RGB(255,255,255)); dc.SetBkMode(TRANSPARENT); CFont font; font.CreateStockObject(DEFAULT_GUI_FONT); CFont *pOldFont=dc.SelectObject(&font); dc.TextOut(10,6,sTitle); dc.SelectObject(pOldFont); DrawIconEx(dc.GetSafeHdc(),width-20,4,AfxGetApp()->LoadIcon(m_bFold?IDI_GROUP_FOLD:IDI_GROUP_UNFOLD), 16,16,NULL,NULL,DI_NORMAL); } #if ADS<17 UINT WGroupBox::OnNcHitTest(CPoint point) #else LRESULT WGroupBox::OnNcHitTest(CPoint point) #endif { CPoint point1=point; ScreenToClient(&point1); if(point1.y<23) return HTCAPTION; else return CDialog::OnNcHitTest(point); } void WGroupBox::OnNcLButtonDown(UINT nHitTest,CPoint point) { if(nHitTest==HTCAPTION) { if(m_bFold) UnFold(); else Fold(); } else CDialog::OnNcLButtonDown(nHitTest,point); } void WGroupBox::OnNcLButtonDblClk(UINT nHitTest,CPoint point) { if(nHitTest==HTCAPTION) { if(m_bFold) UnFold(); else Fold(); } else CDialog::OnNcLButtonDown(nHitTest,point); } void WGroupBox::Fold() { m_bFold=true; CRect rect; GetWindowRect(rect); GetParent()->ScreenToClient(rect); rect.bottom=rect.top+23; MoveWindow(rect); GetParent()->PostMessage(WM_CHILD_SIZE); } void WGroupBox::UnFold() { m_bFold=false; CRect rect; GetWindowRect(rect); GetParent()->ScreenToClient(rect); rect.bottom=rect.top+m_initSize.cy; MoveWindow(rect); GetParent()->PostMessage(WM_CHILD_SIZE); } BEGIN_MESSAGE_MAP(WGroupBoxes,CWnd) ON_MESSAGE(WM_CHILD_SIZE,OnChildSize) ON_WM_VSCROLL() ON_WM_SIZE() END_MESSAGE_MAP() BOOL WGroupBoxes::Create(CWnd*pParent) { const TCHAR* pszClassName = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_SAVEBITS|CS_DBLCLKS, LoadCursor(NULL,IDC_ARROW),GetSysColorBrush(COLOR_BTNFACE)); return CWnd::CreateEx(NULL,pszClassName,_T(""),WS_VISIBLE|WS_CHILD,CRect(0,0,0,0),pParent,5000); } void WGroupBoxes::AddGroup(WGroupBox*pGroup,UINT idTemplate) { pGroup->Create(idTemplate,this); m_allGroup.AddTail(pGroup); RecalcLayout(); } void WGroupBoxes::InsertGroup(int i,WGroupBox*pGroup,UINT idTemplate) { pGroup->Create(idTemplate,this); m_allGroup.Insert(i,pGroup); RecalcLayout(); } WGroupBox* WGroupBoxes::FindGroup(const TCHAR* sName) { for(m_allGroup.MoveToFirst();!m_allGroup.IsOut();m_allGroup.MoveToNext()) { CString sTitle; WGroupBox* pWnd=m_allGroup.GetCurData(); pWnd->GetWindowText(sTitle); if(sTitle==sName) return pWnd; } return NULL; } void WGroupBoxes::Clear() { if(GetSafeHwnd()!=NULL) for(m_allGroup.MoveToFirst(); !m_allGroup.IsOut();m_allGroup.MoveToNext()) m_allGroup.GetCurData()->DestroyWindow(); m_allGroup.Clear(); } int WGroupBoxes::GetHeight() { int h=0; for(m_allGroup.MoveToFirst();!m_allGroup.IsOut();m_allGroup.MoveToNext()) { CRect rect; m_allGroup.GetCurData()->GetWindowRect(rect); h+=rect.Height(); } return h; } void WGroupBoxes::OnSize(UINT nType,int cx,int cy) { CWnd::OnSize(nType,cx,cy); RecalcLayout(); } LONG_PTR WGroupBoxes::OnChildSize(UINT_PTR, LONG_PTR) { RecalcLayout(); return 0; } void WGroupBoxes::RecalcLayout() { static bool bIn=false; if(bIn) return; bIn=true; CRect rect; GetClientRect(rect); int h=GetHeight(); if(rect.Height()range) SetScrollPos(SB_VERT,range); } else { SetScrollPos(SB_VERT,0); ShowScrollBar(SB_VERT,FALSE); } h=-GetScrollPos(SB_VERT); GetClientRect(rect);//May Change! for(m_allGroup.MoveToFirst();!m_allGroup.IsOut();m_allGroup.MoveToNext()) { WGroupBox* pGroup=m_allGroup.GetCurData(); CRect rectOld,rectNew; pGroup->GetWindowRect(rectOld); ScreenToClient(rectOld); rectNew.left=0; rectNew.top=h; rectNew.right=rect.Width()-2; rectNew.bottom=rectOld.Height()+h; if(rectOld!=rectNew) pGroup->MoveWindow(rectNew); h+=rectOld.Height(); } bIn=false; } void WGroupBoxes::OnVScroll(UINT nSBCode,UINT nPos,CScrollBar*pScrollBar) { CRect rect; GetClientRect(&rect); int yMin,yMax; GetScrollRange(SB_VERT,&yMin,&yMax); int y0=GetScrollPos(SB_VERT); int y=y0; switch (nSBCode) { case SB_TOP: y = yMin; break; case SB_BOTTOM: y = yMax; break; case SB_LINEUP: y -=10; break; case SB_LINEDOWN: y +=10; break; case SB_PAGEUP: y -=100; break; case SB_PAGEDOWN: y +=100; break; case SB_THUMBTRACK: y = nPos; break; } if(yyMax) y=yMax; ScrollWindow(0,y0-y); SetScrollPos(SB_VERT,y); CWnd::OnVScroll(nSBCode, nPos, pScrollBar); }