gusucode.com > MFC编程,实现类似VC6.0的界面设计源码程序 > MFC编程,实现类似VC6.0的界面设计源码程序/VCface/bardemo/scbarg.cpp
// sizecbar.cpp : implementation file // #include "stdafx.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif int CALLBACK EnumFontFamProc(ENUMLOGFONT FAR *lpelf, NEWTEXTMETRIC FAR *lpntm, int FontType, LPARAM lParam) { UNUSED_ALWAYS(lpelf); UNUSED_ALWAYS(lpntm); UNUSED_ALWAYS(FontType); UNUSED_ALWAYS(lParam); return 0; } ///////////////////////////////////////////////////////////////////////// // CCoolBar IMPLEMENT_DYNAMIC(CCoolBar, baseCCoolBar); CCoolBar::CCoolBar() { m_hNotifyWnd = NULL; m_cyGripper = 12; SetSCBStyle(GetSCBStyle() | SCBS_SIZECHILD); m_bActive = FALSE; CDC dc; dc.CreateCompatibleDC(NULL); m_sFontFace = (::EnumFontFamilies(dc.m_hDC, _T("宋体"), (FONTENUMPROC) EnumFontFamProc, 0) == 0) ? _T("宋体") : _T("Tahoma"); dc.DeleteDC(); } CCoolBar::~CCoolBar() { } BEGIN_MESSAGE_MAP(CCoolBar, baseCCoolBar) //{{AFX_MSG_MAP(CCoolBar) ON_WM_NCLBUTTONUP() ON_WM_NCHITTEST() //}}AFX_MSG_MAP ON_MESSAGE(WM_SETTEXT, OnSetText) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////// // CCoolBar message handlers BOOL CCoolBar::Create(LPCTSTR lpszWindowName, CWnd* pParentWnd, CSize sizeDefault, BOOL bHasGripper, UINT nID, DWORD dwStyle) { ASSERT_VALID(pParentWnd); m_hNotifyWnd = pParentWnd->m_hWnd; return baseCCoolBar::Create(lpszWindowName, pParentWnd, sizeDefault, bHasGripper, nID, dwStyle); } BOOL CCoolBar::Create(LPCTSTR lpszWindowName, CWnd* pParentWnd, UINT nID, DWORD dwStyle) { ASSERT_VALID(pParentWnd); m_hNotifyWnd = pParentWnd->m_hWnd; return baseCCoolBar::Create(lpszWindowName, pParentWnd, nID, dwStyle); } ///////////////////////////////////////////////////////////////////////// // Mouse Handling // void CCoolBar::OnNcLButtonUp(UINT nHitTest, CPoint point) { if (nHitTest == HTCLOSE) m_pDockSite->ShowControlBar(this, FALSE, FALSE); // hide baseCCoolBar::OnNcLButtonUp(nHitTest, point); } #ifndef COLOR_GRADIENTACTIVECAPTION #define COLOR_GRADIENTACTIVECAPTION 27 #define COLOR_GRADIENTINACTIVECAPTION 28 #define SPI_GETGRADIENTCAPTIONS 0x1008 #endif void CCoolBar::NcCalcClient(LPRECT pRc, UINT nDockBarID) { CRect rcBar(pRc); // save the bar rect // subtract edges baseCCoolBar::NcCalcClient(pRc, nDockBarID); if (!HasGripper()) return; CRect rc(pRc); // the client rect as calculated by the base class BOOL bHorz = (nDockBarID == AFX_IDW_DOCKBAR_TOP) || (nDockBarID == AFX_IDW_DOCKBAR_BOTTOM); if (bHorz) rc.DeflateRect(m_cyGripper, 0, 0, 0); else rc.DeflateRect(0, m_cyGripper, 0, 0); // set position for the "x" (hide bar) button CPoint ptOrgBtn; if (bHorz) ptOrgBtn = CPoint(rc.left - 14, rc.top); else ptOrgBtn = CPoint(rc.right - 12, rc.top - 14); m_biHide.Move(ptOrgBtn - rcBar.TopLeft()); *pRc = rc; } void CCoolBar::NcPaintGripper(CDC* pDC, CRect rcClient) { if (!HasGripper()) return; #ifndef _SCB_STYLE_FLAT CRect gripper = rcClient; CRect rcbtn = m_biHide.GetRect(); BOOL bHorz = IsHorzDocked(); gripper.DeflateRect(1, 1); if (bHorz) { // gripper at left gripper.left -= m_cyGripper; gripper.right = gripper.left + 3; gripper.top = rcbtn.bottom + 3; } else { // gripper at top gripper.top -= m_cyGripper; gripper.bottom = gripper.top + 3; gripper.right = rcbtn.left - 3; } pDC->Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNSHADOW)); gripper.OffsetRect(bHorz ? 3 : 0, bHorz ? 0 : 3); pDC->Draw3dRect(gripper, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNSHADOW)); m_biHide.Paint(pDC); #else // compute the caption rectangle BOOL bHorz = IsHorzDocked(); CRect rcGrip = rcClient; CRect rcBtn = m_biHide.GetRect(); if (bHorz) { // right side gripper rcGrip.left -= m_cyGripper + 1; rcGrip.right = rcGrip.left + 11; rcGrip.top = rcBtn.bottom + 3; } else { // gripper at top rcGrip.top -= m_cyGripper + 1; rcGrip.bottom = rcGrip.top + 11; rcGrip.right = rcBtn.left - 3; } rcGrip.InflateRect(bHorz ? 1 : 0, bHorz ? 0 : 1); // draw the caption background //CBrush br; COLORREF clrCptn = m_bActive ? ::GetSysColor(COLOR_ACTIVECAPTION) : ::GetSysColor(COLOR_INACTIVECAPTION); // query gradient info (usually TRUE for Win98/Win2k) BOOL bGradient = FALSE; ::SystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &bGradient, 0); if (!bGradient) pDC->FillSolidRect(&rcGrip, clrCptn); // solid color else { // gradient from left to right or from bottom to top // get second gradient color (the right end) COLORREF clrCptnRight = m_bActive ? ::GetSysColor(COLOR_GRADIENTACTIVECAPTION) : ::GetSysColor(COLOR_GRADIENTINACTIVECAPTION); // this will make 2^6 = 64 fountain steps int nShift = 6; int nSteps = 1 << nShift; for (int i = 0; i < nSteps; i++) { // do a little alpha blending int nR = (GetRValue(clrCptn) * (nSteps - i) + GetRValue(clrCptnRight) * i) >> nShift; int nG = (GetGValue(clrCptn) * (nSteps - i) + GetGValue(clrCptnRight) * i) >> nShift; int nB = (GetBValue(clrCptn) * (nSteps - i) + GetBValue(clrCptnRight) * i) >> nShift; COLORREF cr = RGB(nR, nG, nB); // then paint with the resulting color CRect r2 = rcGrip; if (bHorz) { r2.bottom = rcGrip.bottom - ((i * rcGrip.Height()) >> nShift); r2.top = rcGrip.bottom - (((i + 1) * rcGrip.Height()) >> nShift); if (r2.Height() > 0) pDC->FillSolidRect(r2, cr); } else { r2.left = rcGrip.left + ((i * rcGrip.Width()) >> nShift); r2.right = rcGrip.left + (((i + 1) * rcGrip.Width()) >> nShift); if (r2.Width() > 0) pDC->FillSolidRect(r2, cr); } } } // draw the caption text - first select a font CFont font; int ppi = pDC->GetDeviceCaps(LOGPIXELSX); int pointsize = MulDiv(96, 96, ppi); // 8.5 points at 96 ppi LOGFONT lf; BOOL bFont = font.CreatePointFont(pointsize, m_sFontFace); if (bFont) { // get the text color COLORREF clrCptnText = m_bActive ? ::GetSysColor(COLOR_CAPTIONTEXT) : ::GetSysColor(COLOR_INACTIVECAPTIONTEXT); int nOldBkMode = pDC->SetBkMode(TRANSPARENT); COLORREF clrOldText = pDC->SetTextColor(clrCptnText); if (bHorz) { // rotate text 90 degrees CCW if horizontally docked font.GetLogFont(&lf); font.DeleteObject(); lf.lfEscapement = 900; font.CreateFontIndirect(&lf); } CFont* pOldFont = pDC->SelectObject(&font); CString sTitle; GetWindowText(sTitle); CPoint ptOrg = bHorz ? CPoint(rcGrip.left - 1, rcGrip.bottom - 3) : CPoint(rcGrip.left + 3, rcGrip.top - 1); pDC->ExtTextOut(ptOrg.x, ptOrg.y, ETO_CLIPPED, rcGrip, sTitle, NULL); pDC->SelectObject(pOldFont); pDC->SetBkMode(nOldBkMode); pDC->SetTextColor(clrOldText); } // draw the button m_biHide.Paint(pDC); #endif } UINT CCoolBar::OnNcHitTest(CPoint point) { CRect rcBar; GetWindowRect(rcBar); UINT nRet = baseCCoolBar::OnNcHitTest(point); if (nRet != HTCLIENT) return nRet; CRect rc = m_biHide.GetRect(); rc.OffsetRect(rcBar.TopLeft()); if (rc.PtInRect(point)) return HTCLOSE; return HTCLIENT; } ///////////////////////////////////////////////////////////////////////// // CCoolBar implementation helpers void CCoolBar::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler) { UNUSED_ALWAYS(bDisableIfNoHndler); UNUSED_ALWAYS(pTarget); if (!HasGripper()) return; BOOL bNeedPaint = FALSE; CPoint pt; ::GetCursorPos(&pt); BOOL bHit = (OnNcHitTest(pt) == HTCLOSE); BOOL bLButtonDown = (::GetKeyState(VK_LBUTTON) < 0); BOOL bWasPushed = m_biHide.bPushed; m_biHide.bPushed = bHit && bLButtonDown; BOOL bWasRaised = m_biHide.bRaised; m_biHide.bRaised = bHit && !bLButtonDown; CWnd* pFocus = GetFocus(); BOOL bActiveOld = m_bActive; m_bActive = (pFocus->GetSafeHwnd() && IsChild(pFocus)); if (m_bActive != bActiveOld) bNeedPaint = TRUE; bNeedPaint |= (m_biHide.bPushed ^ bWasPushed) || (m_biHide.bRaised ^ bWasRaised); if (bNeedPaint) SendMessage(WM_NCPAINT); } ///////////////////////////////////////////////////////////////////////// // CSCBButton CSCBButton::CSCBButton() { bRaised = FALSE; bPushed = FALSE; } void CSCBButton::Paint(CDC* pDC) { CRect rc = GetRect(); if (bPushed) pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNSHADOW), ::GetSysColor(COLOR_BTNHIGHLIGHT)); else if (bRaised) pDC->Draw3dRect(rc, ::GetSysColor(COLOR_BTNHIGHLIGHT), ::GetSysColor(COLOR_BTNSHADOW)); COLORREF clrOldTextColor = pDC->GetTextColor(); pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT)); int nPrevBkMode = pDC->SetBkMode(TRANSPARENT); CFont font; int ppi = pDC->GetDeviceCaps(LOGPIXELSX); int pointsize = MulDiv(60, 96, ppi); // 6 points at 96 ppi font.CreatePointFont(pointsize, _T("Marlett")); CFont* oldfont = pDC->SelectObject(&font); pDC->TextOut(ptOrg.x + 3, ptOrg.y + 3, CString(_T("r"))); // x-like pDC->SelectObject(oldfont); pDC->SetBkMode(nPrevBkMode); pDC->SetTextColor(clrOldTextColor); } BOOL CCoolBar::HasGripper() const { #if defined(_SCB_MINIFRAME_CAPTION) || !defined(_SCB_REPLACE_MINIFRAME) // if the miniframe has a caption, don't display the gripper if (IsFloating()) return FALSE; #endif //_SCB_MINIFRAME_CAPTION return TRUE; } LRESULT CCoolBar::OnSetText(WPARAM wParam, LPARAM lParam) { LRESULT lResult = baseCCoolBar::OnSetText(wParam, lParam); SendMessage(WM_NCPAINT); return lResult; } BOOL CCoolBar::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) { // 将WM_NOTIFY消息转交给消息通知窗口处理 ::SendMessage(m_hNotifyWnd, WM_NOTIFY, wParam, lParam); *pResult = 0; return TRUE; } void CCoolBar::SetNotifyWindow(HWND hNotifyWnd) { m_hNotifyWnd = hNotifyWnd; }