361 lines
7.4 KiB
C++
361 lines
7.4 KiB
C++
#include "stdafx.h"
|
|
#include "resource.h"
|
|
#include "CmdGroupWnd.h"
|
|
|
|
namespace
|
|
{
|
|
void createMemoryDC(CDC *pDC, const CSize &sz, CDC &memDC, CBitmap &memBitMap)
|
|
{
|
|
memDC.CreateCompatibleDC(NULL);
|
|
memBitMap.CreateCompatibleBitmap(pDC, sz.cx, sz.cy);
|
|
memDC.SelectObject(&memBitMap);
|
|
}
|
|
|
|
void releaseMeroryDC(CDC *pDC, CDC &memDC, CBitmap &memBitMap)
|
|
{
|
|
BITMAP bitmap;
|
|
ZeroMemory(&bitmap, sizeof(bitmap));
|
|
memBitMap.GetBitmap(&bitmap);
|
|
|
|
pDC->BitBlt(0, 0, bitmap.bmWidth, bitmap.bmHeight, &memDC, 0, 0, SRCCOPY);
|
|
|
|
memDC.DeleteDC();
|
|
memBitMap.DeleteObject();
|
|
}
|
|
|
|
bool BitBlt(CDC &dcDest, const CRect &reDest, const HBITMAP& hBitmap, const CPoint &ptSrc, DWORD dwRop)
|
|
{
|
|
CDC memDC;
|
|
memDC.CreateCompatibleDC(&dcDest);
|
|
memDC.SelectObject(hBitmap);
|
|
BOOL bRel = ::BitBlt(dcDest.GetSafeHdc()
|
|
, reDest.left
|
|
, reDest.top
|
|
, reDest.Width()
|
|
, reDest.Height(),
|
|
memDC.GetSafeHdc()
|
|
, ptSrc.x
|
|
, ptSrc.y
|
|
, dwRop);
|
|
memDC.DeleteDC();
|
|
return bRel ? true : false;
|
|
}
|
|
}
|
|
|
|
CmdGroupWnd::CmdGroupWnd(LPCTSTR pszName
|
|
, const ETYPE & ContentStyle
|
|
, const ETYPE & WndStyle)
|
|
: m_nNcH(22)
|
|
, m_eContentStyle(ContentStyle)
|
|
, m_eWndSta(eMax)
|
|
, m_eWndStyle(WndStyle)
|
|
, m_sWndName(pszName)
|
|
, m_nBorder(1) { }
|
|
|
|
CmdGroupWnd::~CmdGroupWnd() { }
|
|
|
|
bool CmdGroupWnd::Create(const CRect &rc, CWnd *pParent)
|
|
{
|
|
if (!pParent) return false;
|
|
|
|
DWORD dwStyle(WS_CHILD | WS_CAPTION | WS_VISIBLE );
|
|
|
|
if (CWnd::Create(NULL, m_sWndName, dwStyle, rc, pParent, NULL))
|
|
{
|
|
Invalidate(); // 防止圆角
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
COLORREF CmdGroupWnd::baseCaptionClr()
|
|
{
|
|
return m_eWndStyle == eLight ? RGB(222, 222, 222) : RGB(74, 74, 74);
|
|
}
|
|
|
|
COLORREF CmdGroupWnd::borderColor()
|
|
{
|
|
return m_eWndStyle == eLight ? RGB(158, 158, 158) : RGB(51, 51, 51);
|
|
}
|
|
|
|
COLORREF CmdGroupWnd::basePanelClr()
|
|
{
|
|
return m_eWndStyle == eLight ? RGB(240, 240, 240) : RGB(92, 92, 92);
|
|
}
|
|
|
|
void CmdGroupWnd::expandWnd(ETYPE expand)
|
|
{
|
|
CRect rc;
|
|
GetWindowRect(rc);
|
|
CSize sz(rc.Size());
|
|
if (expand == eMax)
|
|
{
|
|
CRgn rgnMax;
|
|
rgnMax.CreateRectRgn(0, 0, sz.cx, sz.cy);
|
|
SetWindowRgn((HRGN)rgnMax, TRUE);
|
|
}
|
|
else
|
|
{
|
|
CRgn rgnMin;
|
|
rgnMin.CreateRectRgn(0, 0, sz.cx, m_nNcH);
|
|
SetWindowRgn((HRGN)rgnMin, TRUE);
|
|
}
|
|
refreshParent();
|
|
}
|
|
|
|
CPoint CmdGroupWnd::getNcBtnBmpPos(const ETYPE &contentStyle, const ETYPE & wndStyle, bool bSelect)
|
|
{
|
|
// 参照 res/ncbtnimg.bmp
|
|
CPoint ptPos(0, 0);
|
|
|
|
switch (contentStyle)
|
|
{
|
|
case eList:
|
|
ptPos.y = 51;
|
|
break;
|
|
case ePanel:
|
|
ptPos.y = 68;
|
|
break;
|
|
case eIcon:
|
|
ptPos.y = 34;
|
|
break;
|
|
case eMin:
|
|
ptPos.y = 0;
|
|
break;
|
|
case eMax:
|
|
ptPos.y = 17;
|
|
break;
|
|
default:
|
|
return ptPos;
|
|
}
|
|
|
|
if (bSelect)
|
|
ptPos.x = 34;
|
|
|
|
if (wndStyle == eLight)
|
|
ptPos.x += 17;
|
|
|
|
return ptPos;
|
|
}
|
|
|
|
CRect CmdGroupWnd::getNcBtnWndPos(const ETYPE & btn)
|
|
{
|
|
int space(3);
|
|
CPoint pt(0, int((m_nNcH - 16) * .5));
|
|
|
|
CRect rc;
|
|
GetWindowRect(rc);
|
|
|
|
int w(rc.Width());
|
|
|
|
int maxBtnX = w - m_nBorder - space - 16;
|
|
int panelBtnX = maxBtnX - 3 * space - 16;
|
|
int listBtnX = panelBtnX - space - 16;
|
|
int iconBtnX = listBtnX - space - 16;
|
|
|
|
switch (btn)
|
|
{
|
|
case eList:
|
|
pt.x = listBtnX;
|
|
break;
|
|
case ePanel:
|
|
pt.x = panelBtnX;
|
|
break;
|
|
case eIcon:
|
|
pt.x = iconBtnX;
|
|
break;
|
|
case eMax:
|
|
case eMin:
|
|
pt.x = maxBtnX;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return CRect(pt, CSize(16, 16));
|
|
}
|
|
|
|
void CmdGroupWnd::refreshCmdBtn(const ETYPE & contentStyle)
|
|
{
|
|
refreshParent();
|
|
}
|
|
|
|
void CmdGroupWnd::refreshParent()
|
|
{
|
|
CWnd *pWnd = GetParent();
|
|
if (pWnd)
|
|
{
|
|
CRect rc;
|
|
GetWindowRect(rc);
|
|
pWnd->ScreenToClient(rc);
|
|
pWnd->InvalidateRect(rc);
|
|
}
|
|
}
|
|
|
|
void CmdGroupWnd::MoveWindow(LPCRECT lpRect, BOOL bRepaint)
|
|
{
|
|
CWnd::MoveWindow(lpRect, bRepaint);
|
|
}
|
|
|
|
BEGIN_MESSAGE_MAP(CmdGroupWnd, CWnd)
|
|
ON_WM_NCCALCSIZE()
|
|
ON_WM_NCPAINT()
|
|
ON_WM_PAINT()
|
|
ON_WM_NCLBUTTONDBLCLK()
|
|
ON_WM_NCLBUTTONDOWN()
|
|
END_MESSAGE_MAP()
|
|
|
|
void CmdGroupWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
|
|
{
|
|
int nTHight = m_nNcH; //标题栏的高度
|
|
int xFrame = 1 * m_nBorder; //左右边框的厚度
|
|
int yFrame = 1 * m_nBorder; //下边框的厚度
|
|
|
|
RECT *rc = (RECT *)lpncsp;
|
|
|
|
rc->top = rc->top + nTHight;
|
|
rc->left = rc->left + xFrame;
|
|
|
|
rc->right = rc->right - xFrame;
|
|
rc->bottom = rc->bottom - yFrame;
|
|
}
|
|
|
|
void CmdGroupWnd::OnNcPaint()
|
|
{
|
|
CWindowDC dc(this);
|
|
|
|
CRect rcClient, rcWnd;
|
|
GetClientRect(rcClient);
|
|
GetWindowRect(rcWnd);
|
|
CSize szClient(rcClient.Size());
|
|
|
|
CSize szMax(rcWnd.Size());
|
|
|
|
CDC memDC;
|
|
CBitmap memBitmap;
|
|
createMemoryDC(&dc, szMax, memDC, memBitmap);
|
|
|
|
// 先用borderClr打底色
|
|
memDC.FillSolidRect(CRect(CPoint(0, 0), szMax), borderColor());
|
|
|
|
// 再用baseClr画caption
|
|
CSize sz(szMax.cx, m_nNcH);
|
|
sz.cx = szMax.cx - 2 * m_nBorder;
|
|
sz.cy = m_nNcH - 2 * m_nBorder;
|
|
memDC.FillSolidRect(CRect(CPoint(m_nBorder, m_nBorder), sz), baseCaptionClr());
|
|
|
|
// 客户区底色
|
|
memDC.FillSolidRect(CRect(CPoint(m_nBorder, m_nNcH),szClient), basePanelClr());
|
|
|
|
CRect rcList, rcIcon, rcPanel, rcMax;
|
|
CPoint ptList, ptIcon, ptPanel, ptMax;
|
|
|
|
rcList = getNcBtnWndPos(eList);
|
|
rcIcon = getNcBtnWndPos(eIcon);
|
|
rcPanel = getNcBtnWndPos(ePanel);
|
|
rcMax = getNcBtnWndPos(eMax);
|
|
|
|
ptMax = getNcBtnBmpPos(m_eWndSta, m_eWndStyle, false);
|
|
ptList = getNcBtnBmpPos(eList, m_eWndStyle, m_eContentStyle == eList);
|
|
ptIcon = getNcBtnBmpPos(eIcon, m_eWndStyle, m_eContentStyle == eIcon);
|
|
ptPanel = getNcBtnBmpPos(ePanel, m_eWndStyle, m_eContentStyle == ePanel);
|
|
|
|
CAcModuleResourceOverride resOverride;
|
|
CBitmap bmp;
|
|
bmp.LoadBitmap(IDB_NCCAPTION);
|
|
|
|
|
|
BitBlt(memDC, rcMax, (HBITMAP)bmp, ptMax, SRCCOPY);
|
|
BitBlt(memDC, rcList, (HBITMAP)bmp, ptList, SRCCOPY);
|
|
BitBlt(memDC, rcIcon, (HBITMAP)bmp, ptIcon, SRCCOPY);
|
|
BitBlt(memDC, rcPanel, (HBITMAP)bmp, ptPanel, SRCCOPY);
|
|
|
|
DWORD dwOldTxtClr = memDC.SetTextColor(RGB(0, 0, 0));
|
|
int bkOld = memDC.SetBkMode(TRANSPARENT);
|
|
|
|
HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
|
|
LOGFONT logfont;
|
|
::GetObject(hFont, sizeof(LOGFONT), &logfont);
|
|
wcscpy(logfont.lfFaceName, _T("宋体"));
|
|
HFONT hNewFont = NULL;
|
|
hNewFont = ::CreateFontIndirect(&logfont);
|
|
if (hNewFont)
|
|
{
|
|
HFONT oldFont = (HFONT)(memDC.SelectObject(hNewFont));
|
|
|
|
memDC.DrawText(m_sWndName
|
|
, CRect(CPoint(1, 1), CSize(ptIcon.x - 1, m_nNcH - 2))
|
|
, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
|
|
|
|
DeleteObject(hNewFont);
|
|
memDC.SelectObject(oldFont);
|
|
}
|
|
memDC.SetBkMode(bkOld);
|
|
memDC.SetTextColor(dwOldTxtClr);
|
|
releaseMeroryDC(&dc, memDC, memBitmap);
|
|
|
|
}
|
|
|
|
void CmdGroupWnd::OnPaint()
|
|
{
|
|
CPaintDC dc(this);
|
|
}
|
|
|
|
void CmdGroupWnd::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
|
|
{
|
|
if (m_eWndSta == eMax)
|
|
m_eWndSta = eMin;
|
|
else
|
|
m_eWndSta = eMax;
|
|
|
|
expandWnd(m_eWndSta);
|
|
|
|
CWnd::OnNcLButtonDblClk(nHitTest, point);
|
|
}
|
|
|
|
void CmdGroupWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
|
|
{
|
|
CRect rcList, rcIcon, rcPanel, rcMax, rcWnd;
|
|
|
|
GetWindowRect(rcWnd);
|
|
|
|
point.x -= rcWnd.left;
|
|
point.y -= rcWnd.top;
|
|
|
|
rcList = getNcBtnWndPos(eList);
|
|
rcIcon = getNcBtnWndPos(eIcon);
|
|
rcPanel = getNcBtnWndPos(ePanel);
|
|
rcMax = getNcBtnWndPos(eMax);
|
|
|
|
if (rcMax.PtInRect(point))
|
|
{
|
|
SendMessage(WM_NCLBUTTONDBLCLK, (WPARAM)nHitTest, MAKELPARAM(point.x, point.y));
|
|
return;
|
|
}
|
|
|
|
if (rcList.PtInRect(point))
|
|
{
|
|
m_eContentStyle = eList;
|
|
SendMessage(WM_NCPAINT, 1, NULL);
|
|
refreshCmdBtn(eList);
|
|
return;
|
|
}
|
|
|
|
if (rcIcon.PtInRect(point))
|
|
{
|
|
m_eContentStyle = eIcon;
|
|
SendMessage(WM_NCPAINT, 1, NULL);
|
|
refreshCmdBtn(eIcon);
|
|
return;
|
|
}
|
|
|
|
if (rcPanel.PtInRect(point))
|
|
{
|
|
m_eContentStyle = ePanel;
|
|
SendMessage(WM_NCPAINT, 1, NULL);
|
|
refreshCmdBtn(ePanel);
|
|
return;
|
|
}
|
|
|
|
//CWnd::OnNcLButtonDown(nHitTest, point);
|
|
}
|