303 lines
6.2 KiB
C++
303 lines
6.2 KiB
C++
#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()<h)
|
|
{
|
|
ShowScrollBar(SB_VERT);
|
|
int range=h-rect.Height();
|
|
SetScrollRange(SB_VERT,0,range);
|
|
if(GetScrollPos(SB_VERT)>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(y<yMin)
|
|
y=yMin;
|
|
else if(y>yMax)
|
|
y=yMax;
|
|
ScrollWindow(0,y0-y);
|
|
SetScrollPos(SB_VERT,y);
|
|
CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
|
|
}
|
|
|