void CMenuItem::DrawControl(CDC &dc, CRect rcUpdate) { int nWidth = m_rc.Width(); int nHeight = m_rc.Height(); if(!m_bUpdate) { int nImageCount = m_bSelect ? 6 : 4; if(m_nImagePicCount != 4) { // 如果修改过img-count属性,则用此属性设置的图片个数 nImageCount = m_nImagePicCount; } if(m_bIsSeparator) { nImageCount = 1; } UpdateMemDC(dc, nWidth * nImageCount, nHeight); // 刷新图片的大小(因为m_bSelect选项有可能在SetBitmap之后有变化) if(m_pImage != NULL) { if(m_bIsPopup && (m_pImagePopupArrow == NULL)) { m_sizeImage.SetSize(m_pImage->GetWidth() / 2, m_pImage->GetHeight()); }else { m_sizeImage.SetSize(m_pImage->GetWidth() / nImageCount, m_pImage->GetHeight()); } } Graphics graphics(m_memDC); CRect rcTemp(0, 0, nWidth, nHeight); for(int i = 0; i < nImageCount; i++) { m_memDC.BitBlt(i * nWidth, 0, nWidth, nHeight, &dc, m_rc.left ,m_rc.top, SRCCOPY); if(enBSHover == i || (enBSDown == i && !m_bSelect) || enBSHoverDown == i) { // 画菜单项背景 if(m_pImageHover != NULL) { // 使用拉伸模式属性画图 graphics.DrawImage(m_pImageHover, RectF((Gdiplus::REAL)(i * nWidth+m_nFrameWidth), 0, (Gdiplus::REAL)(nWidth-m_nFrameWidth*2), (Gdiplus::REAL)nHeight), 0, 0, (Gdiplus::REAL)m_sizeHover.cx, (Gdiplus::REAL)m_sizeHover.cy, UnitPixel); }else { // 使用颜色填充 SolidBrush brush(m_clrHover);//Color(254, 71, 156, 235)); graphics.FillRectangle(&brush, i * nWidth+m_nFrameWidth, 0, nWidth-m_nFrameWidth*2, nHeight); } } if(m_pImage != NULL) { if(m_bIsSeparator) { // 如果是分隔线,则采用平铺方式画图 TextureBrush tileBrush(m_pImage, WrapModeTile); graphics.FillRectangle(&tileBrush, RectF((Gdiplus::REAL)rcTemp.left, (Gdiplus::REAL)(rcTemp.top + (nHeight - m_sizeImage.cy) / 2), (Gdiplus::REAL)(nWidth-m_nFrameWidth*2), (Gdiplus::REAL)m_sizeImage.cy)); }else if(m_bIsPopup && (m_pImagePopupArrow == NULL)) { // 如果是弹出菜单,并且没有设置菜单的箭头图片,则用菜单图片作为右侧的箭头图片 graphics.DrawImage(m_pImage, Rect(rcTemp.right - m_sizeImage.cx - 6, rcTemp.top + (nHeight - m_sizeImage.cy) / 2, m_sizeImage.cx, m_sizeImage.cy), (i % 2) * m_sizeImage.cx, 0, m_sizeImage.cx, m_sizeImage.cy, UnitPixel); }else { // 普通菜单项的图片 graphics.DrawImage(m_pImage, Rect(rcTemp.left + (m_nLeft - m_sizeImage.cx) / 2, rcTemp.top + (nHeight - m_sizeImage.cy) / 2, m_sizeImage.cx, m_sizeImage.cy), i * m_sizeImage.cx, 0, m_sizeImage.cx, m_sizeImage.cy, UnitPixel); } } // 如果是弹出菜单,并且设置了菜单的箭头图片,则画右侧的箭头图片 if(m_bIsPopup && (m_pImagePopupArrow != NULL)) { graphics.DrawImage(m_pImagePopupArrow, Rect(rcTemp.right - m_sizePopupArrow.cx - 6, rcTemp.top + (nHeight - m_sizePopupArrow.cy) / 2, m_sizePopupArrow.cx, m_sizePopupArrow.cy), (i % 2) * m_sizePopupArrow.cx, 0, m_sizePopupArrow.cx, m_sizePopupArrow.cy, UnitPixel); } rcTemp.OffsetRect(nWidth, 0); } if(!m_strTitle.IsEmpty()) { m_memDC.SetBkMode(TRANSPARENT); rcTemp.SetRect(0, 0, nWidth, nHeight); BSTR bsFont = m_strFont.AllocSysString(); FontFamily fontFamily(bsFont); Font font(&fontFamily, (REAL)m_nFontWidth, m_fontStyle, UnitPixel); graphics.SetTextRenderingHint( TextRenderingHintClearTypeGridFit ); ::SysFreeString(bsFont); StringFormat strFormat; strFormat.SetAlignment(StringAlignmentNear); strFormat.SetFormatFlags( StringFormatFlagsNoWrap | StringFormatFlagsMeasureTrailingSpaces); Size size = GetTextBounds(font, strFormat, m_strTitle); CPoint point = GetOriginPoint(nWidth - m_nLeft, nHeight, size.Width, size.Height, m_uAlignment, m_uVAlignment); for(int i = 0; i < nImageCount; i++) { SolidBrush solidBrush(enBSDisable == i ? Color(254, 128, 128, 128) : (enBSHover == i || (enBSDown == i && !m_bSelect) || enBSHoverDown == i ? Color(254, 255, 255, 255) : Color(254, 56, 56, 56))); RectF rect((Gdiplus::REAL)(m_nLeft + point.x + i * nWidth), (Gdiplus::REAL)point.y, (Gdiplus::REAL)(nWidth - (m_nLeft + point.x)), (Gdiplus::REAL)size.Height); BSTR bsTitle = m_strTitle.AllocSysString(); graphics.DrawString(bsTitle, (INT)wcslen(bsTitle), &font, rect, &strFormat, &solidBrush); ::SysFreeString(bsTitle); } } } dc.BitBlt(m_rc.left,m_rc.top, m_rc.Width(), m_rc.Height(), &m_memDC, m_enButtonState * nWidth, 0, SRCCOPY); }
// 画控件 void CMenuItem::DrawControl(CDC &dc, CRect rcUpdate) { int nWidth = m_rc.Width(); int nHeight = m_rc.Height(); if(!m_bUpdate) { int nImageCount = m_bSelect ? 6 : 4; if(m_bIsSeparator) { nImageCount = 1; } UpdateMemDC(dc, nWidth * nImageCount, nHeight); // 刷新图片的大小(因为m_bSelect选项有可能在SetBitmap之后有变化) if(m_pImage != NULL) { if(m_bIsPopup && (m_pImagePopupArrow == NULL)) { // 弹出菜单的箭头,固定是两个小图片 m_sizeImage.SetSize(m_pImage->GetWidth() / 2, m_pImage->GetHeight()); }else if(m_bIsSeparator) { // 分隔线,只有一个图片 m_sizeImage.SetSize(m_pImage->GetWidth(), m_pImage->GetHeight()); }else if(m_bSelect) { // checkbox或radiobutton,固定为6个小图片 m_sizeImage.SetSize(m_pImage->GetWidth() / 6, m_pImage->GetHeight()); }else { // 按照设置的小图片个数计算 m_sizeImage.SetSize(m_pImage->GetWidth() / m_nImagePicCount, m_pImage->GetHeight()); } } Graphics graphics(m_memDC); CRect rcTemp(0, 0, nWidth, nHeight); for(int i = 0; i < nImageCount; i++) { m_memDC.BitBlt(i * nWidth, 0, nWidth, nHeight, &dc, m_rc.left ,m_rc.top, SRCCOPY); if(enBSHover == i || (enBSDown == i && !m_bSelect) || enBSHoverDown == i) { // 画菜单项背景 if(m_pImageHover != NULL) { // 使用拉伸模式属性画图 graphics.DrawImage(m_pImageHover, RectF((Gdiplus::REAL)(i * nWidth+m_nFrameWidth), 0, (Gdiplus::REAL)(nWidth-m_nFrameWidth*2), (Gdiplus::REAL)nHeight), 0, 0, (Gdiplus::REAL)m_sizeHover.cx, (Gdiplus::REAL)m_sizeHover.cy, UnitPixel); }else { // 使用颜色填充 SolidBrush brush(m_clrHover);//Color(254, 71, 156, 235)); graphics.FillRectangle(&brush, i * nWidth+m_nFrameWidth, 0, nWidth-m_nFrameWidth*2, nHeight); } } // 画菜单项图片 if(m_pImage != NULL) { if(m_bIsSeparator) { // 如果是分隔线,则采用平铺方式画图 TextureBrush tileBrush(m_pImage, WrapModeTile); graphics.FillRectangle(&tileBrush, RectF((Gdiplus::REAL)rcTemp.left, (Gdiplus::REAL)(rcTemp.top + (nHeight - m_sizeImage.cy) / 2), (Gdiplus::REAL)(nWidth-m_nFrameWidth*2), (Gdiplus::REAL)m_sizeImage.cy)); }else if(m_bIsPopup && (m_pImagePopupArrow == NULL)) { // 如果是弹出菜单,并且没有设置菜单的箭头图片,则用菜单图片作为右侧的箭头图片 graphics.DrawImage(m_pImage, Rect(rcTemp.right - m_sizeImage.cx - 6, rcTemp.top + (nHeight - m_sizeImage.cy) / 2, m_sizeImage.cx, m_sizeImage.cy), (i % 2) * m_sizeImage.cx, 0, m_sizeImage.cx, m_sizeImage.cy, UnitPixel); }else if(m_bSelect) { // checkbox或radiobutton graphics.DrawImage(m_pImage, Rect(rcTemp.left + (m_nLeft - m_sizeImage.cx) / 2, rcTemp.top + (nHeight - m_sizeImage.cy) / 2, m_sizeImage.cx, m_sizeImage.cy), i * m_sizeImage.cx, 0, m_sizeImage.cx, m_sizeImage.cy, UnitPixel); }else { // 普通菜单项的图片,如果小图片个数不足,则使用第一个小图片 graphics.DrawImage(m_pImage, Rect(rcTemp.left + (m_nLeft - m_sizeImage.cx) / 2, rcTemp.top + (nHeight - m_sizeImage.cy) / 2, m_sizeImage.cx, m_sizeImage.cy), ((m_nImagePicCount-1 < i) ? 0 : i) * m_sizeImage.cx, 0, m_sizeImage.cx, m_sizeImage.cy, UnitPixel); } } // 如果是弹出菜单,并且设置了菜单的箭头图片,则画右侧的箭头图片 if(m_bIsPopup && (m_pImagePopupArrow != NULL)) { graphics.DrawImage(m_pImagePopupArrow, Rect(rcTemp.right - m_sizePopupArrow.cx - 6, rcTemp.top + (nHeight - m_sizePopupArrow.cy) / 2, m_sizePopupArrow.cx, m_sizePopupArrow.cy), (i % 2) * m_sizePopupArrow.cx, 0, m_sizePopupArrow.cx, m_sizePopupArrow.cy, UnitPixel); } rcTemp.OffsetRect(nWidth, 0); } // 画菜单项文字 if(!m_strTitle.IsEmpty()) { m_memDC.SetBkMode(TRANSPARENT); rcTemp.SetRect(0, 0, nWidth, nHeight); BSTR bsFont = m_strFont.AllocSysString(); FontFamily fontFamily(bsFont); Font font(&fontFamily, (REAL)m_nFontWidth, m_fontStyle, UnitPixel); graphics.SetTextRenderingHint( TextRenderingHintClearTypeGridFit ); ::SysFreeString(bsFont); // 设置菜单文字的水平和垂直对齐方式,默认是水平方向左对齐,垂直方向中间对齐 DUI_STRING_ALIGN_DEFINE(); strFormat.SetFormatFlags( StringFormatFlagsNoWrap | StringFormatFlagsMeasureTrailingSpaces); for(int i = 0; i < nImageCount; i++) { SolidBrush solidBrush(enBSDisable == i ? Color(254, 128, 128, 128) : (enBSHover == i || (enBSDown == i && !m_bSelect) || enBSHoverDown == i ? Color(254, 255, 255, 255) : Color(254, 56, 56, 56))); RectF rect((Gdiplus::REAL)(m_nLeft + i * nWidth), (Gdiplus::REAL)0, (Gdiplus::REAL)(nWidth - m_nLeft), (Gdiplus::REAL)nHeight); BSTR bsTitle = m_strTitle.AllocSysString(); graphics.DrawString(bsTitle, (INT)wcslen(bsTitle), &font, rect, &strFormat, &solidBrush); ::SysFreeString(bsTitle); } } } dc.BitBlt(m_rc.left,m_rc.top, m_rc.Width(), m_rc.Height(), &m_memDC, m_enButtonState * nWidth, 0, SRCCOPY); }