Files
envi-code/SourceCode/Code2026/EarthWormMain/CmdGroupWnd.cpp
T
2026-09-28 15:28:50 +08:00

361 lines
7.3 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);
}