// 画窗口背景和控件 void CDuiVisionDesignerView::DrawBackgroundAndAreas(CDC &dc, const CRect &rcClient, const CRect &rcUpdate) { // 没有指定背景,则填充背景颜色为背景图片的平均色,当背景图片不够大时起到渐变色的效果 dc.FillSolidRect(rcUpdate.left, rcUpdate.top, rcUpdate.Width(), rcUpdate.Height(), m_clrBK); // 如果指定了背景,已经生成了背景的内存dc,则画背景,从背景内存dc输出到当前dc(背景dc的大小可能小于当前dc) if(m_bDrawImage) { CRect rcBk(1, 1, 1 + m_sizeBKImage.cx, 1 + m_sizeBKImage.cy); rcBk = rcBk & rcUpdate; if(!rcBk.IsRectEmpty()) { dc.BitBlt(rcBk.left, rcBk.top, rcBk.Width() , rcBk.Height(), &m_MemBKDC, rcBk.left, rcBk.top, SRCCOPY ); } } // 画所有的Area控件,实现半透明层 DrawAreaControl(dc, rcClient, m_crlBackTransParent, 40, 40); }
void CClosableTabCtrl::DrawItem(LPDRAWITEMSTRUCT lpDIS) { CRect rect(lpDIS->rcItem); int nTabIndex = lpDIS->itemID; if (nTabIndex < 0) return; TCHAR szLabel[256]; TC_ITEM tci; tci.mask = TCIF_TEXT | TCIF_IMAGE | TCIF_STATE; tci.pszText = szLabel; tci.cchTextMax = _countof(szLabel); tci.dwStateMask = TCIS_HIGHLIGHTED; if (!GetItem(nTabIndex, &tci)) return; //TRACE("CClosableTabCtrl::DrawItem: item=%u, state=%08x, color=%08x, rc=%3d,%3d,%3dx%3d\n", nTabIndex, tci.dwState, GetTextColor(lpDIS->hDC), lpDIS->rcItem.left, lpDIS->rcItem.top, lpDIS->rcItem.right - lpDIS->rcItem.left, lpDIS->rcItem.bottom - lpDIS->rcItem.top); CDC* pDC = CDC::FromHandle(lpDIS->hDC); if (!pDC) return; CRect rcFullItem(lpDIS->rcItem); bool bSelected = (lpDIS->itemState & ODS_SELECTED) != 0; /////////////////////////////////////////////////////////////////////////////////////// // Adding support for XP Styles (Vista Themes) for owner drawn tab controls simply // does *not* work under Vista. Maybe it works under XP (did not try), but that is // meaningless because under XP a owner drawn tab control is already rendered *with* // the proper XP Styles. So, for XP there is no need to care about the theme API at all. // // However, under Vista, a tab control which has the TCS_OWNERDRAWFIXED // style gets additional 3D-borders which are applied by Vista *after* WM_DRAWITEM // was processed. Thus, there is no known workaround available to prevent Vista from // adding those old fashioned 3D-borders. We can render the tab control items within // the WM_DRAWITEM handler in whatever style we want, but Vista will in each case // overwrite the borders of each tab control item with old fashioned 3D-borders... // // To complete this experience, tab controls also do not support NMCUSTOMDRAW. So, the // only known way to customize a tab control is by using TCS_OWNERDRAWFIXED which does // however not work properly under Vista. // // The "solution" which is currently implemented to prevent Vista from drawing those // 3D-borders is by using "ExcludeClipRect" to reduce the drawing area which is used // by Windows after WM_DRAWITEM was processed. This "solution" is very sensitive to // the used rectangles and offsets in general. Incrementing/Decrementing one of the // "rcItem", "rcFullItem", etc. rectangles makes the entire "solution" flawed again // because some borders would become visible again. // HTHEME hTheme = NULL; int iPartId = TABP_TABITEM; int iStateId = TIS_NORMAL; bool bVistaHotTracked = false; bool bVistaThemeActive = theApp.IsVistaThemeActive(); if (bVistaThemeActive) { // To determine if the current item is in 'hot tracking' mode, we need to evaluate // the current foreground color - there is no flag which would indicate this state // more safely. This applies only for Vista and for tab controls which have the // TCS_OWNERDRAWFIXED style. bVistaHotTracked = pDC->GetTextColor() == GetSysColor(COLOR_HOTLIGHT); hTheme = g_xpStyle.OpenThemeData(m_hWnd, L"TAB"); if (hTheme) { if (bSelected) { // get the real tab item rect rcFullItem.left += 1; rcFullItem.right -= 1; rcFullItem.bottom -= 1; } else rcFullItem.InflateRect(2, 2); // get the real tab item rect CRect rcBk(rcFullItem); if (bSelected) { iStateId = TTIS_SELECTED; if (nTabIndex == 0) { // First item if (nTabIndex == GetItemCount() - 1) iPartId = TABP_TOPTABITEMBOTHEDGE; // First & Last item else iPartId = TABP_TOPTABITEMLEFTEDGE; } else if (nTabIndex == GetItemCount() - 1) { // Last item iPartId = TABP_TOPTABITEMRIGHTEDGE; } else { iPartId = TABP_TOPTABITEM; } } else { rcBk.top += 2; iStateId = bVistaHotTracked ? TIS_HOT : TIS_NORMAL; if (nTabIndex == 0) { // First item if (nTabIndex == GetItemCount() - 1) iPartId = TABP_TABITEMBOTHEDGE; // First & Last item else iPartId = TABP_TABITEMLEFTEDGE; } else if (nTabIndex == GetItemCount() - 1) { // Last item iPartId = TABP_TABITEMRIGHTEDGE; } else { iPartId = TABP_TABITEM; } } if (g_xpStyle.IsThemeBackgroundPartiallyTransparent(hTheme, iPartId, iStateId)) g_xpStyle.DrawThemeParentBackground(m_hWnd, *pDC, &rcFullItem); g_xpStyle.DrawThemeBackground(hTheme, *pDC, iPartId, iStateId, &rcBk, NULL); } } // Following background clearing is needed for: // WinXP/Vista (when used without an application theme) // Vista (when used with an application theme but without a theme for the tab control) if ( (!g_xpStyle.IsThemeActive() || !g_xpStyle.IsAppThemed()) || (hTheme == NULL && bVistaThemeActive) ) pDC->FillSolidRect(&lpDIS->rcItem, GetSysColor(COLOR_BTNFACE)); int iOldBkMode = pDC->SetBkMode(TRANSPARENT); // Draw image on left side CImageList *piml = GetImageList(); if (tci.iImage >= 0 && piml && piml->m_hImageList) { IMAGEINFO ii; piml->GetImageInfo(0, &ii); rect.left += bSelected ? 8 : 4; piml->Draw(pDC, tci.iImage, CPoint(rect.left, rect.top + 2), ILD_TRANSPARENT); rect.left += (ii.rcImage.right - ii.rcImage.left); if (!bSelected) rect.left += 4; } bool bCloseable = m_bCloseable; if (bCloseable && GetParent()->SendMessage(UM_QUERYTAB, nTabIndex)) bCloseable = false; // Draw 'Close button' at right side if (bCloseable && m_ImgLstCloseButton.m_hImageList) { CRect rcCloseButton; GetCloseButtonRect(nTabIndex, rect, rcCloseButton, bSelected, bVistaThemeActive); HTHEME hThemeNC = bVistaThemeActive ? g_xpStyle.OpenThemeData(m_hWnd, _T("WINDOW")) : NULL; if (hThemeNC) { // Possible "Close" parts: WP_CLOSEBUTTON, WP_SMALLCLOSEBUTTON, WP_MDICLOSEBUTTON int iPartId = WP_SMALLCLOSEBUTTON; int iStateId = (bSelected || bVistaHotTracked) ? CBS_NORMAL : CBS_DISABLED; if (g_xpStyle.IsThemeBackgroundPartiallyTransparent(hTheme, iPartId, iStateId)) g_xpStyle.DrawThemeParentBackground(m_hWnd, *pDC, &rcCloseButton); g_xpStyle.DrawThemeBackground(hThemeNC, *pDC, iPartId, iStateId, rcCloseButton, NULL); g_xpStyle.CloseThemeData(hThemeNC); } else { m_ImgLstCloseButton.Draw(pDC, (bSelected || bVistaHotTracked) ? 0 : 1, rcCloseButton.TopLeft(), ILD_TRANSPARENT); } rect.right = rcCloseButton.left - 2; if (bSelected) rect.left += hTheme ? 4 : 2; } COLORREF crOldColor = CLR_NONE; if (tci.dwState & TCIS_HIGHLIGHTED) crOldColor = pDC->SetTextColor(RGB(192, 0, 0)); else if (bVistaHotTracked) crOldColor = pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT)); rect.top += bSelected ? 4 : 3; // Vista: Tab control has troubles with determining the width of a tab if the // label contains one '&' character. To get around this, we use the old code which // replaces one '&' character with two '&' characters and we do not specify DT_NOPREFIX // here when drawing the text. // // Vista: "DrawThemeText" can not be used in case we need a certain foreground color. Thus we always us // "DrawText" to always get the same font and metrics (just for safety). pDC->DrawText(szLabel, rect, DT_SINGLELINE | DT_TOP | DT_CENTER /*| DT_NOPREFIX*/); if (crOldColor != CLR_NONE) pDC->SetTextColor(crOldColor); pDC->SetBkMode(iOldBkMode); if (hTheme) { CRect rcClip(rcFullItem); if (bSelected) { rcClip.left -= 2 + 1; rcClip.right += 2 + 1; } else { rcClip.top += 2; } pDC->ExcludeClipRect(&rcClip); g_xpStyle.CloseThemeData(hTheme); } }
void TabControl::DrawItem(LPDRAWITEMSTRUCT lpDIS) { CRect rect(lpDIS->rcItem); int nTabIndex = lpDIS->itemID; if (nTabIndex < 0) return; TCHAR szLabel[256]; TC_ITEM tci; tci.mask = TCIF_TEXT | TCIF_PARAM; tci.pszText = szLabel; tci.cchTextMax = _countof(szLabel); if (!GetItem(nTabIndex, &tci)) return; CDC* pDC = CDC::FromHandle(lpDIS->hDC); if (!pDC) return; CRect rcFullItem(lpDIS->rcItem); bool bSelected = (lpDIS->itemState & ODS_SELECTED) != 0; HTHEME hTheme = NULL; int iPartId = TABP_TABITEM; int iStateId = TIS_NORMAL; bool bVistaHotTracked = false; bool bVistaThemeActive = theApp.IsVistaThemeActive(); if (bVistaThemeActive) { // To determine if the current item is in 'hot tracking' mode, we need to evaluate // the current foreground color - there is no flag which would indicate this state // more safely. This applies only for Vista and for tab controls which have the // TCS_OWNERDRAWFIXED style. bVistaHotTracked = pDC->GetTextColor() == GetSysColor(COLOR_HOTLIGHT); hTheme = g_xpStyle.OpenThemeData(m_hWnd, L"TAB"); if (hTheme) { if (bSelected) { // get the real tab item rect rcFullItem.left += 1; rcFullItem.right -= 1; rcFullItem.bottom -= 1; } else rcFullItem.InflateRect(2, 2); // get the real tab item rect CRect rcBk(rcFullItem); if (bSelected) { iStateId = TTIS_SELECTED; if (nTabIndex == 0) { // First item if (nTabIndex == GetItemCount() - 1) iPartId = TABP_TOPTABITEMBOTHEDGE; // First & Last item else iPartId = TABP_TOPTABITEMLEFTEDGE; } else if (nTabIndex == GetItemCount() - 1) { // Last item iPartId = TABP_TOPTABITEMRIGHTEDGE; } else { iPartId = TABP_TOPTABITEM; } } else { rcBk.top += 2; iStateId = bVistaHotTracked ? TIS_HOT : TIS_NORMAL; if (nTabIndex == 0) { // First item if (nTabIndex == GetItemCount() - 1) iPartId = TABP_TABITEMBOTHEDGE; // First & Last item else iPartId = TABP_TABITEMLEFTEDGE; } else if (nTabIndex == GetItemCount() - 1) { // Last item iPartId = TABP_TABITEMRIGHTEDGE; } else { iPartId = TABP_TABITEM; } } if (g_xpStyle.IsThemeBackgroundPartiallyTransparent(hTheme, iPartId, iStateId)) g_xpStyle.DrawThemeParentBackground(m_hWnd, *pDC, &rcFullItem); g_xpStyle.DrawThemeBackground(hTheme, *pDC, iPartId, iStateId, &rcBk, NULL); } } // Vista: Need to clear the background explicitly to avoid glitches with // *) a changed icon // *) hot tracking effect if (hTheme == NULL && bVistaThemeActive) pDC->FillSolidRect(&lpDIS->rcItem, GetSysColor(COLOR_BTNFACE)); int iOldBkMode = pDC->SetBkMode(TRANSPARENT); COLORREF crOldColor = CLR_NONE; if (tci.lParam != (DWORD)-1) crOldColor = pDC->SetTextColor(tci.lParam); else if (bVistaHotTracked) crOldColor = pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT)); rect.top += bSelected ? 4 : 3; // Vista: Tab control has troubles with determining the width of a tab if the // label contains one '&' character. To get around this, we use the old code which // replaces one '&' character with two '&' characters and we do not specify DT_NOPREFIX // here when drawing the text. // // Vista: "DrawThemeText" can not be used in case we need a certain foreground color. Thus we always us // "DrawText" to always get the same font and metrics (just for safety). pDC->DrawText(szLabel, rect, DT_SINGLELINE | DT_TOP | DT_CENTER /*| DT_NOPREFIX*/); if (crOldColor != CLR_NONE) pDC->SetTextColor(crOldColor); pDC->SetBkMode(iOldBkMode); if (hTheme) { CRect rcClip(rcFullItem); if (bSelected) { rcClip.left -= 2 + 1; rcClip.right += 2 + 1; } else { rcClip.top += 2; } pDC->ExcludeClipRect(&rcClip); g_xpStyle.CloseThemeData(hTheme); } }
void CClipMonView::ReDrawBkBuffer() { if (!m_bUseBkBuffer) { return; } CSize szView = GetScrollViewSize(); if (szView.cx == 0 || szView.cy == 0) { return; } CRect rcClient; TxGetClientRect(rcClient); CRect rcViewShowBuffer(rcClient); rcViewShowBuffer.MoveToXY(0,0); rcViewShowBuffer.OffsetRect(GetScrollPos(SB_HORZ), GetScrollPos(SB_VERT)); CRect rcBk(0,0, m_szbmpBackBuffer.cx, m_szbmpBackBuffer.cy); rcBk = GetCenterRect(rcViewShowBuffer, rcBk); if (rcBk.left < 0) { rcBk.MoveToX(0); } if (rcBk.top < 0) { rcBk.MoveToY(0); } m_rcViewBkBuffer = rcBk; m_BkBufferlock.Lock(); ASSERT(m_pBmpBackBuffer != NULL); Graphics gc(m_pBmpBackBuffer); SolidBrush bkBrush(m_drawParam.bkColor); Rect rCet = CRect2Rect(CRect(0,0, rcBk.Width(), rcBk.Height())); gc.FillRectangle(&bkBrush, rCet); CRect rcView(0, 0, szView.cx, szView.cy); //calc In Bound Item int nBegin = (rcBk.top - rcView.top) / m_drawParam.nItemHeight; int nCount = rcBk.Height() /m_drawParam.nItemHeight +1; VECTMPITEM vData; g_monDataMgr.GetRangeData(nBegin, nCount, vData); nCount = vData.size(); if (nCount == 0) { return; } CTxListHeader& headerCtrl = GetListHeader(); int nTopPos = rcView.top + (nBegin * m_drawParam.nItemHeight)- rcBk.top; Gdiplus::StringFormat fmt; fmt.SetAlignment(StringAlignmentCenter); fmt.SetLineAlignment(StringAlignmentCenter); fmt.SetTrimming(StringTrimmingEllipsisCharacter); fmt.SetFormatFlags(StringFormatFlagsLineLimit|StringFormatFlagsNoWrap); Pen pen(g_globalInfo.viewSetting.clrSeparateLine, 1.0); Rect rRowBk(0, nTopPos, rcBk.Width(), m_drawParam.nItemHeight); for (int i = 0; i < nCount; i++) { ARGB clr = 0xff000000; ARGB clrBk = 0xffffffff; vData[i].GetMonColor(clr, clrBk); bkBrush.SetColor(clrBk); gc.FillRectangle(&bkBrush, rRowBk); int nLeftPos = 0-rcBk.left; CRect rcItem(nLeftPos,nTopPos, 0, nTopPos + m_drawParam.nItemHeight); for (int cIdx = 0; cIdx < m_ColSetting.m_vTmpCols.size(); cIdx++) { if (rcItem.left > rcBk.right) { break; } rcItem.right = rcItem.left + headerCtrl.GetHeaderWidth(cIdx); if (rcItem.right >= rcBk.left) { ENUM_MONTYPE nMonType = (ENUM_MONTYPE)(m_ColSetting.m_vTmpCols[cIdx].nPosInType); if (nMonType != MONTYPE_TIMEREMAIN) { CString strText = vData[i].GetValue(nMonType); GPDrawShadowTextSimple(gc, strText, rcItem, *m_drawParam.pFont, clr, 0, 2,2, &fmt); //GPDrawShadowText(gc, strText, rcItem, *m_drawParam.pFont, clr, 0x22000000,0,0,0,0,&fmt); } //draw separate line gc.DrawLine(&pen, rcItem.right-1, rcItem.top, rcItem.right-1, rcItem.bottom); } rcItem.OffsetRect(rcItem.Width(), 0); } gc.DrawLine(&pen, rcBk.left, rcItem.bottom-1, rcBk.right, rcItem.bottom-1); nTopPos += m_drawParam.nItemHeight; rRowBk.Offset(0, m_drawParam.nItemHeight); } m_BkBufferlock.Unlock(); }