#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); }