コード例 #1
0
ファイル: Panel.cpp プロジェクト: hezlog/DuiVision
// 鼠标坐标变换
BOOL CDuiPanel::OnMousePointChange(CPoint& point)
{
	if(m_pDuiPluginObject)
	{
		return m_pDuiPluginObject->OnMousePointChange(point);
	}

	if(m_bEnableScroll && ((m_nVirtualHeight > m_rc.Height()) || (m_nVirtualWidth > m_rc.Width())))
	{
		// 计算显示位置
		CDuiScrollVertical* pScrollV = (CDuiScrollVertical*)m_pControScrollV;
		int nCurPosV = pScrollV->GetScrollCurrentPos();	// 当前top位置
		int nMaxRangeV = pScrollV->GetScrollMaxRange();
		int nVirtualTop = (nMaxRangeV > 0) ? nCurPosV*(m_nVirtualHeight-m_rc.Height())/nMaxRangeV : 0;	// 当前显示的是虚拟图片中什么位置开始的图片

		CDuiScrollHorizontal* pScrollH = (CDuiScrollHorizontal*)m_pControScrollH;
		int nCurPosH = pScrollH->GetScrollCurrentPos();	// 当前top位置
		int nMaxRangeH = pScrollH->GetScrollMaxRange();
		int nVirtualLeft = (nMaxRangeH > 0) ? nCurPosH*(m_nVirtualWidth-m_rc.Width())/nMaxRangeH : 0;	// 当前显示的是虚拟图片中什么位置开始的图片

		point.Offset(nVirtualLeft, nVirtualTop);

		return TRUE;
	}

	return FALSE;
}
コード例 #2
0
void CDuiGridCtrl::DrawControl(CDC &dc, CRect rcUpdate)
{
	// 列表画图方法:
	// 1.列表的虚拟高度为每一行高度*行数
	// 2.列表显示的top坐标由scroll控件记录
	// 3.重画时候,根据top坐标位置计算出显示的第一行的序号,根据显示高度计算出显示的最后一行的序号
	// 4.根据计算出的显示的行,画相应的内容到内存dc中
	// 5.计算出显示的top坐标进行内存dc的拷贝
	int nTotalColumnWidth = GetTotalColumnWidth();	// 总的列宽度
	int nViewWidth = m_rc.Width() - m_nScrollWidth;	// 减去滚动条的显示区域宽度
	CDuiScrollHorizontal* pScrollH = (CDuiScrollHorizontal*)m_pControScrollH;
	int nCurPosH = pScrollH->GetScrollCurrentPos();	// 当前left位置
	int nMaxRangeH = pScrollH->GetScrollMaxRange();
	int nContentWidth = (nTotalColumnWidth > nViewWidth) ? nTotalColumnWidth : nViewWidth;	// 内容部分的宽度(如果总的列宽小于显示区域宽度,则使用显示区域宽度)
	m_nVirtualLeft = (nMaxRangeH > 0) ? (int)((double)nCurPosH*(nContentWidth-nViewWidth)/nMaxRangeH) : 0;	// 当前滚动条位置对应的虚拟的left位置

	int nHeightAll = m_vecRowInfo.size()*m_nRowHeight; // 总的虚拟高度 //m_rc.Height();
	CDuiScrollVertical* pScrollV = (CDuiScrollVertical*)m_pControScrollV;
	int nCurPosV = pScrollV->GetScrollCurrentPos();	// 当前top位置
	int nMaxRangeV = pScrollV->GetScrollMaxRange();
	m_nVirtualTop = (nMaxRangeV > 0) ? (int)((double)nCurPosV*(nHeightAll-m_rc.Height())/nMaxRangeV) : 0;	// 当前滚动条位置对应的虚拟的top位置
	if(m_nVirtualTop < 0)
	{
		m_nVirtualTop = 0;
		pScrollV->SetScrollCurrentPos(0);
	}
	m_nFirstViewRow = m_nVirtualTop / m_nRowHeight;					// 显示的第一行序号
	m_nLastViewRow = (m_nVirtualTop + m_rc.Height() - m_nHeaderHeight) / m_nRowHeight;	// 显示的最后一行序号
	if(m_nLastViewRow >= (int)m_vecRowInfo.size())
	{
		m_nLastViewRow = m_vecRowInfo.size() - 1;
	}
	if(m_nLastViewRow < 0)
	{
		m_nLastViewRow = 0;
	}
	int nHeightView = (m_nLastViewRow - m_nFirstViewRow +1) * m_nRowHeight;	// 显示涉及到的虚拟高度
	int nYViewPos = m_nVirtualTop - (m_nFirstViewRow * m_nRowHeight);		// 内存dc显示到屏幕时候的top位置
	if(nYViewPos < 0)
	{
		nYViewPos = 0;
	}

	if(!m_bUpdate)
	{
		UpdateMemDC(dc, nTotalColumnWidth, nHeightView);

		Graphics graphics(m_memDC);
		
		m_memDC.BitBlt(m_nVirtualLeft, 0, nViewWidth, nHeightView, &dc, m_rc.left, m_rc.top, WHITENESS);	// 画白色背景
		DrawVerticalTransition(m_memDC, dc, CRect(m_nVirtualLeft, nYViewPos, nViewWidth+m_nVirtualLeft, m_rc.Height()+nYViewPos-m_nHeaderHeight),	// 背景透明度
				m_rc, m_nBkTransparent, m_nBkTransparent);
		
		BSTR bsFontTitle = m_strFontTitle.AllocSysString();
		FontFamily fontFamilyTitle(bsFontTitle);
		Font fontTitle(&fontFamilyTitle, (REAL)m_nFontTitleWidth, m_fontTitleStyle, UnitPixel);
		::SysFreeString(bsFontTitle);

		BSTR bsFont = m_strFont.AllocSysString();
		FontFamily fontFamily(bsFont);
		Font font(&fontFamily, (REAL)m_nFontWidth, m_fontStyle, UnitPixel);
		::SysFreeString(bsFont);

		SolidBrush solidBrush(m_clrText);			// 正常文字画刷
		SolidBrush solidBrushH(m_clrTextHover);		// 热点文字画刷
		SolidBrush solidBrushD(m_clrTextDown);		// 当前行画刷
		SolidBrush solidBrushT(m_clrTitle);			// 标题文字画刷
		SolidBrush solidBrushS(m_clrSeperator);		// 分割线画刷

		graphics.SetTextRenderingHint( TextRenderingHintClearTypeGridFit );

		// 设置普通文字的水平和垂直对齐方式
		DUI_STRING_ALIGN_DEFINE();

		strFormat.SetTrimming(StringTrimmingEllipsisWord);	// 以单词为单位去尾,略去部分使用省略号
		//strFormat.SetFormatFlags( StringFormatFlagsNoClip | StringFormatFlagsMeasureTrailingSpaces);
		if(!m_bTextWrap)
		{
			strFormat.SetFormatFlags(StringFormatFlagsNoWrap | StringFormatFlagsMeasureTrailingSpaces);	// 不换行
		}

		// 标题字段采用中间对齐
		StringFormat strFormatHeader;
		strFormatHeader.SetAlignment(StringAlignmentCenter);	// 中间对齐
		strFormatHeader.SetLineAlignment(StringAlignmentCenter);	// 中间对齐
		if(!m_bTextWrap)
		{
			strFormatHeader.SetFormatFlags(StringFormatFlagsNoWrap | StringFormatFlagsMeasureTrailingSpaces);	// 不换行
		}

		// 画标题行
		if((m_nHeaderHeight > 0) && (m_vecColumnInfo.size() > 0))
		{
			// 画单元格内容
			int nPosItemX = 0;
			for(size_t j = 0; j < m_vecColumnInfo.size(); j++)
			{
				GridColumnInfo &columnInfo = m_vecColumnInfo.at(j);
				int nWidth = columnInfo.nWidth;
				if(j == 0)
				{
					nWidth += m_nLeftPos;
				}
				RectF rect((Gdiplus::REAL)nPosItemX, 0, (Gdiplus::REAL)nWidth, (Gdiplus::REAL)(m_nHeaderHeight-1));

				// 画列标题
				CString strTitle = columnInfo.strTitle;
				BSTR bsTitle = strTitle.AllocSysString();
				graphics.DrawString(bsTitle, (INT)wcslen(bsTitle), &font, rect, &strFormatHeader, &solidBrushT);
				::SysFreeString(bsTitle);

				nPosItemX += nWidth;
			}
		}
		
		if(m_vecRowInfo.size() > 0)
		{
			for(int i = m_nFirstViewRow; i <= m_nLastViewRow && i < (int)m_vecRowInfo.size(); i++)
			{
				GridRowInfo &rowInfo = m_vecRowInfo.at(i);
				SolidBrush solidBrushRow(rowInfo.clrText);	// 行定义的颜色

				int nXPos = 0;
				int nVI = i - m_nFirstViewRow;

				// 鼠标移动到行时候显示的背景颜色(如果设置为全0,则不显示行背景颜色)
				if((m_nHoverRow == i) && (m_clrRowHover.GetValue() != Color(0, 0, 0, 0).GetValue()))
				{
					SolidBrush brush(m_clrRowHover);
					graphics.FillRectangle(&brush, 0, m_nHeaderHeight + nVI*m_nRowHeight, nContentWidth, m_nRowHeight);
				}

				// 画检查框
				int nCheckImgY = 3;
				if((m_sizeCheckBox.cy*2 > m_nRowHeight) || (m_uVAlignment == VAlign_Middle))
				{
					nCheckImgY = (m_nRowHeight - m_sizeCheckBox.cy) / 2 + 1;
				}
				if((rowInfo.nCheck != -1) && (m_pImageCheckBox != NULL))
				{
					int nCheckImageIndex = ((m_nHoverRow == i) ? ((rowInfo.nCheck==1) ? 4 : 1) : ((rowInfo.nCheck==1) ? 2 : 0));
					graphics.DrawImage(m_pImageCheckBox, Rect(nXPos, m_nHeaderHeight + nVI*m_nRowHeight + nCheckImgY, m_sizeCheckBox.cx, m_sizeCheckBox.cy),
						nCheckImageIndex * m_sizeCheckBox.cx, 0, m_sizeCheckBox.cx, m_sizeCheckBox.cy, UnitPixel);
					rowInfo.rcCheck.SetRect(nXPos, i*m_nRowHeight + nCheckImgY, nXPos + m_sizeCheckBox.cx, i*m_nRowHeight + nCheckImgY + m_sizeCheckBox.cy);
					nXPos += (m_sizeCheckBox.cx + 3);
				}

				// 画行左边图片
				int nImgY = 3;
				if(rowInfo.pImage != NULL)
				{
					if((rowInfo.sizeImage.cy*2 > m_nRowHeight) || (m_uVAlignment == VAlign_Middle))
					{
						nImgY = (m_nRowHeight - rowInfo.sizeImage.cy) / 2 + 1;
					}
					// 使用行数据指定的图片
					graphics.DrawImage(rowInfo.pImage, Rect(nXPos, m_nHeaderHeight + nVI*m_nRowHeight + nImgY, rowInfo.sizeImage.cx, rowInfo.sizeImage.cy),
						0, 0, rowInfo.sizeImage.cx, rowInfo.sizeImage.cy, UnitPixel);
					nXPos += (rowInfo.sizeImage.cx + 3);
				}else
				if((rowInfo.nImageIndex != -1) && (m_pImage != NULL))
				{
					if((m_sizeImage.cy*2 > m_nRowHeight) || (m_uVAlignment == VAlign_Middle))
					{
						nImgY = (m_nRowHeight - m_sizeImage.cy) / 2 + 1;
					}
					// 使用索引图片
					graphics.DrawImage(m_pImage, Rect(nXPos, m_nHeaderHeight + nVI*m_nRowHeight + nImgY, m_sizeImage.cx, m_sizeImage.cy),
						rowInfo.nImageIndex*m_sizeImage.cx, 0, m_sizeImage.cx, m_sizeImage.cy, UnitPixel);
					nXPos += (m_sizeImage.cx + 3);
				}

				// 画行右边图片
				int nRightImageWidth = 0;
				nImgY = 3;
				if(rowInfo.pRightImage != NULL)
				{
					if((rowInfo.sizeRightImage.cy*2 > m_nRowHeight) || (m_uVAlignment == VAlign_Middle))
					{
						nImgY = (m_nRowHeight - rowInfo.sizeRightImage.cy) / 2 + 1;
					}
					// 使用行数据指定的图片
					graphics.DrawImage(rowInfo.pRightImage, Rect(nContentWidth-rowInfo.sizeRightImage.cx-1, m_nHeaderHeight + nVI*m_nRowHeight + nImgY, rowInfo.sizeRightImage.cx, rowInfo.sizeRightImage.cy),
						0, 0, rowInfo.sizeRightImage.cx, rowInfo.sizeRightImage.cy, UnitPixel);
					nRightImageWidth = rowInfo.sizeRightImage.cx + 1;
				}else
				if((rowInfo.nRightImageIndex != -1) && (m_pImage != NULL))
				{
					if((m_sizeImage.cy*2 > m_nRowHeight) || (m_uVAlignment == VAlign_Middle))
					{
						nImgY = (m_nRowHeight - m_sizeImage.cy) / 2 + 1;
					}
					// 使用索引图片
					graphics.DrawImage(m_pImage, Rect(nContentWidth-m_sizeImage.cx-1, m_nHeaderHeight + nVI*m_nRowHeight + nImgY, m_sizeImage.cx, m_sizeImage.cy),
						rowInfo.nRightImageIndex*m_sizeImage.cx, 0, m_sizeImage.cx, m_sizeImage.cy, UnitPixel);
					nRightImageWidth = m_sizeImage.cx + 1;
				}

				// 画单元格内容
				int nPosItemX = (m_nLeftPos != 0) ? m_nLeftPos : nXPos;
				for(size_t j = 0; j < rowInfo.vecItemInfo.size(); j++)
				{
					GridColumnInfo &columnInfo = m_vecColumnInfo.at(j);
					GridItemInfo &itemInfo = rowInfo.vecItemInfo.at(j);
					BOOL bSingleLine = (itemInfo.strContent.IsEmpty() || !itemInfo.strLink.IsEmpty());
					RectF rect((Gdiplus::REAL)nPosItemX,
						(Gdiplus::REAL)(m_nHeaderHeight + nVI*m_nRowHeight + 1),
						(Gdiplus::REAL)((j == 0) ? (itemInfo.rcItem.Width() - nPosItemX): itemInfo.rcItem.Width()),
						(Gdiplus::REAL)(bSingleLine ? (m_nRowHeight - 2) : (m_nRowHeight / 2 - 2)));
					if((int)(rect.GetRight()) > nContentWidth)
					{
						// 最后一列需要减去滚动条宽度
						rect.Width -= m_nScrollWidth;
					}

					// 画单元格图片
					int nItemImageX = 0;
					int nImgY = 3;
					if(itemInfo.pImage != NULL)
					{
						if((itemInfo.sizeImage.cy*2 > m_nRowHeight) || (m_uVAlignment == VAlign_Middle))
						{
							nImgY = (m_nRowHeight - rowInfo.sizeImage.cy) / 2 + 1;
						}
						// 使用单元格指定的图片
						graphics.DrawImage(itemInfo.pImage, Rect(nPosItemX+nItemImageX, m_nHeaderHeight + nVI*m_nRowHeight + nImgY, itemInfo.sizeImage.cx, itemInfo.sizeImage.cy),
							0, 0, itemInfo.sizeImage.cx, itemInfo.sizeImage.cy, UnitPixel);
						nItemImageX += (itemInfo.sizeImage.cx + 3);
					}else
					if((itemInfo.nImageIndex != -1) && (m_pImage != NULL))
					{
						if((m_sizeImage.cy*2 > m_nRowHeight) || (m_uVAlignment == VAlign_Middle))
						{
							nImgY = (m_nRowHeight - m_sizeImage.cy) / 2 + 1;
						}
						// 使用索引图片
						graphics.DrawImage(m_pImage, Rect(nPosItemX+nItemImageX, m_nHeaderHeight + nVI*m_nRowHeight + nImgY, m_sizeImage.cx, m_sizeImage.cy),
							itemInfo.nImageIndex*m_sizeImage.cx, 0, m_sizeImage.cx, m_sizeImage.cy, UnitPixel);
						nItemImageX += (m_sizeImage.cx + 3);
					}
					rect.Offset((Gdiplus::REAL)nItemImageX, 0);
					rect.Width -= (Gdiplus::REAL)nItemImageX;

					// 画单元格标题或链接内容
					SolidBrush solidBrushItem(m_clrText);
					if((m_nHoverRow == i) && (m_clrTextHover.GetValue() != Color(0, 0, 0, 0).GetValue()))	// 设置了鼠标移动颜色,则使用
					{
						solidBrushItem.SetColor(m_clrTextHover);
					}else
					if((m_nDownRow == i) && (m_clrTextDown.GetValue() != Color(0, 0, 0, 0).GetValue()))	// 设置了鼠标按下颜色,则使用
					{
						solidBrushItem.SetColor(m_clrTextDown);
					}else
					if(itemInfo.clrText.GetValue() != Color(0, 0, 0, 0).GetValue())	// 设置了单元格颜色,则使用
					{
						solidBrushItem.SetColor(itemInfo.clrText);
					}else
					if(rowInfo.bRowColor)	// 设置了行颜色,则使用
					{
						solidBrushItem.SetColor(rowInfo.clrText);
					}
					CString strItemTitle = itemInfo.strTitle;
					// 计算是否需要显示tip
					itemInfo.bNeedTitleTip = rect.Width < GetTextBounds(font, strItemTitle).Width;
					itemInfo.bNeedContentTip = rect.Width < GetTextBounds(font, itemInfo.strContent).Width;
					if(!itemInfo.strLink.IsEmpty())
					{
						strItemTitle = itemInfo.strLink;
						if((m_nHoverRow == i) && (rowInfo.nHoverItem == j))
						{
							solidBrushItem.SetColor(m_clrTextHover);
						}else
						{
							solidBrushItem.SetColor((itemInfo.clrText.GetValue() != Color(0, 0, 0, 0).GetValue()) ? itemInfo.clrText : m_clrText);
						}
					}

					// 设置单元格文字对齐方式,使用列的对齐方式
					StringFormat strFormatColumn;
					UINT uAlignment = m_uAlignment;
					if(columnInfo.uAlignment != 0xFFFFUL)
					{
						uAlignment = columnInfo.uAlignment;
					}
					if(uAlignment == Align_Left)
					{
						strFormatColumn.SetAlignment(StringAlignmentNear);
					}else
					if(uAlignment == Align_Center)
					{
						strFormatColumn.SetAlignment(StringAlignmentCenter);
					}else
					if(uAlignment == Align_Right)
					{
						strFormatColumn.SetAlignment(StringAlignmentFar);
					}
					UINT uVAlignment = m_uVAlignment;
					if(columnInfo.uVAlignment != 0xFFFFUL)
					{
						uVAlignment = columnInfo.uVAlignment;
					}
					if(uVAlignment == VAlign_Top)
					{
						strFormatColumn.SetLineAlignment(StringAlignmentNear);
					}else
					if(uVAlignment == VAlign_Middle)
					{
						strFormatColumn.SetLineAlignment(StringAlignmentCenter);
					}else
					if(uVAlignment == VAlign_Bottom)
					{
						strFormatColumn.SetLineAlignment(StringAlignmentFar);
					}
					if(!m_bTextWrap)
					{
						strFormatColumn.SetFormatFlags(StringFormatFlagsNoWrap | StringFormatFlagsMeasureTrailingSpaces);	// 不换行
					}

					// 根据bUseTitleFont决定用标题字体还是普通字体
					BSTR bsItemTitle = strItemTitle.AllocSysString();
					graphics.DrawString(bsItemTitle, (INT)wcslen(bsItemTitle),
						itemInfo.bUseTitleFont ? &fontTitle : &font, rect, &strFormatColumn, itemInfo.bUseTitleFont ? &solidBrushT : &solidBrushItem);
					::SysFreeString(bsItemTitle);

					// 画单元格内容
					if(!bSingleLine)
					{
						rect.Offset(0, (Gdiplus::REAL)m_nRowHeight / 2 + 2);
						rect.Height = (Gdiplus::REAL)m_nRowHeight / 2 - 4;
						BSTR bsItemContent = itemInfo.strContent.AllocSysString();
						graphics.DrawString(bsItemContent, (INT)wcslen(bsItemContent), &font, rect, &strFormatColumn, &solidBrushItem);
						::SysFreeString(bsItemContent);
					}

					// 设置单元格子控件的位置
					for(size_t k = 0; k < itemInfo.vecControl.size(); k++)
					{
						CControlBase* pControl = itemInfo.vecControl.at(k);
						if(pControl)
						{
							CRect rcParent = CRect(nPosItemX, m_nHeaderHeight + nVI*m_nRowHeight + 1,
								(int)(rect.X+rect.Width), (nVI+1)*m_nRowHeight - 1);
							if((int)(rect.GetRight()) > nContentWidth)
							{
								// 最后一列需要减去滚动条宽度
								rcParent.right -= m_nScrollWidth;
							}
							rcParent.OffsetRect(m_rc.left - m_nVirtualLeft, m_rc.top - (nYViewPos + m_nHeaderHeight));
							pControl->SetPositionWithParent(rcParent);
							CRect rcControl = pControl->GetRect();
							// 只有当前在显示范围内的控件设置为可见
							if( (rcControl.top < m_rc.top) || (rcControl.bottom > m_rc.bottom) ||
								(rcControl.left < m_rc.left) || (rcControl.right > m_rc.right) )
							{
								pControl->SetVisible(FALSE);
							}else
							{
								pControl->SetVisible(TRUE);
							}
						}
					}

					if(j == 0)
					{
						// 为了使第二列开始是对齐的,所以第二列开始位置按照第一列的宽度计算
						nPosItemX = itemInfo.rcItem.right;
					}else
					{
						nPosItemX += itemInfo.rcItem.Width();
					}
				}

				// 画分隔线(采用拉伸模式)
				if(m_pImageSeperator != NULL)
				{
					// 使用拉伸模式画图
					graphics.DrawImage(m_pImageSeperator, RectF(0, (Gdiplus::REAL)(m_nHeaderHeight + (nVI+1)*m_nRowHeight), (Gdiplus::REAL)(nContentWidth-2), (Gdiplus::REAL)m_sizeSeperator.cy),
							0, 0, (Gdiplus::REAL)m_sizeSeperator.cx, (Gdiplus::REAL)m_sizeSeperator.cy, UnitPixel);
				}else
				if(m_clrSeperator.GetValue() != Color(0, 0, 0, 0).GetValue())
				{
					// 未指定图片,并且分隔线显色不是全0,则画矩形
					graphics.FillRectangle(&solidBrushS, 0, m_nHeaderHeight + (nVI+1)*m_nRowHeight, nContentWidth-2, 1);
				}
			}

			// 把不在显示范围内的单元格的控件都设置为不可见
			for(int i = 0; i < (int)m_vecRowInfo.size(); i++)
			{
				if((i < m_nFirstViewRow) || (i > m_nLastViewRow))
				{
					GridRowInfo &rowInfo = m_vecRowInfo.at(i);
					for(size_t j = 0; j < rowInfo.vecItemInfo.size(); j++)
					{
						GridItemInfo &itemInfo = rowInfo.vecItemInfo.at(j);
						for(size_t k = 0; k < itemInfo.vecControl.size(); k++)
						{
							CControlBase* pControl = itemInfo.vecControl.at(k);
							if(pControl)
							{
								pControl->SetVisible(FALSE);
							}
						}
					}
				}
			}
		}
	}

	// 输出到界面DC,使用与的方式合并背景
	// 标题行输出
	if(m_nHeaderHeight > 0)
	{
		dc.BitBlt(m_rc.left,m_rc.top, nViewWidth, m_nHeaderHeight, &m_memDC, m_nVirtualLeft, 0, SRCCOPY);//SRCAND);
	}
	// 内容部分输出
	int nContentHeight = m_rc.Height() - m_nHeaderHeight;
	if(nTotalColumnWidth > m_rc.Width())
	{
		nContentHeight -= m_nScrollWidth;
	}
	dc.BitBlt(m_rc.left,m_rc.top + m_nHeaderHeight, nViewWidth, nContentHeight, &m_memDC, m_nVirtualLeft, nYViewPos + m_nHeaderHeight, SRCCOPY);//SRCAND);
}
コード例 #3
0
ファイル: DuiText.cpp プロジェクト: caomw/DuiVision
void CDuiText::DrawControl(CDC &dc, CRect rcUpdate)
{
	int nWidth = m_rc.Width();
	int nHeight = m_rc.Height();
	
	// 计算显示位置
	CDuiScrollVertical* pScrollV = (CDuiScrollVertical*)m_pControScrollV;
	int nCurPos = pScrollV->GetScrollCurrentPos();	// 当前top位置
	int nMaxRange = pScrollV->GetScrollMaxRange();
	int nVirtualTop = 0;	// 当前显示的是虚拟图片中什么位置开始的图片
	m_nVirtualHeight = GetVirtualHeight();
	if(m_nVirtualHeight > m_rc.Height())
	{
		nVirtualTop = (nMaxRange > 0) ? nCurPos*(m_nVirtualHeight-m_rc.Height())/nMaxRange : 0;
	}else
	{
		nVirtualTop = 0;
	}

	if(!m_bUpdate)
	{
		UpdateMemDC(dc, nWidth, m_nVirtualHeight);

		Graphics graphics(m_memDC);
		
		if(m_bBack)
		{
			SolidBrush brush(m_clrBack);
			graphics.FillRectangle(&brush, 0, 0, nWidth, nHeight);
		}
		else
		{
			//m_memDC.BitBlt(0, 0, nWidth, nHeight, &dc, m_rc.left ,m_rc.top, SRCCOPY);
			m_memDC.BitBlt(0, 0, nWidth, nHeight, &dc, m_rc.left ,m_rc.top, WHITENESS);	// 画白色背景
			DrawVerticalTransition(m_memDC, dc, CRect(0, 0+nVirtualTop, nWidth, nHeight+nVirtualTop),	// 背景透明度
					m_rc, m_nBkTransparent, m_nBkTransparent);
		}
		
		BSTR bsFont = m_strFont.AllocSysString();
		FontFamily fontFamily(bsFont);
		Font font(&fontFamily, (REAL)m_nFontWidth, m_fontStyle, UnitPixel);
		::SysFreeString(bsFont);

		SolidBrush solidBrush(m_clrText);
		
		graphics.SetTextRenderingHint( TextRenderingHintClearTypeGridFit );

		// 设置水平和垂直对齐方式
		DUI_STRING_ALIGN_DEFINE();

		//strFormat.SetFormatFlags( StringFormatFlagsNoWrap | StringFormatFlagsMeasureTrailingSpaces);
		strFormat.SetFormatFlags( StringFormatFlagsNoClip | StringFormatFlagsMeasureTrailingSpaces);
		//strFormat.SetTrimming(StringTrimmingEllipsisWord);	// 以单词为单位去尾,略去部分使用省略号

		int nXPos = 0;
		if(m_pImage != NULL)
		{
			graphics.DrawImage(m_pImage, Rect(0, (nHeight - m_sizeImage.cy) / 2, m_sizeImage.cx, m_sizeImage.cy),
				0, 0, m_sizeImage.cx, m_sizeImage.cy, UnitPixel);
			nXPos += m_sizeImage.cx + 5;
		}
		
		Size size = GetTextBounds(font, strFormat, nWidth, m_strTitle);
		
		int nStart = m_strTitle.Find(m_strMark, m_nStart);
		if(m_strMark.IsEmpty() || (nStart == -1))
		{
			int nTextWidth = nWidth - nXPos;
			if(m_bScrollV)
			{
				nTextWidth -= m_nScrollWidth;
			}

			// 先画阴影
			if(m_bEnableShadow)
			{
				RectF rectShadow((Gdiplus::REAL)(nXPos  + 1), (Gdiplus::REAL)1, (Gdiplus::REAL)nTextWidth, (Gdiplus::REAL)max(size.Height, nHeight));
				SolidBrush solidBrushS(m_clrTextShadow);
				BSTR bsTitle = m_strTitle.AllocSysString();
				graphics.DrawString(bsTitle, (INT)wcslen(bsTitle), &font, rectShadow, &strFormat, &solidBrushS);
				::SysFreeString(bsTitle);
			}

			// 再画正常的文字
			RectF rect((Gdiplus::REAL)(nXPos), (Gdiplus::REAL)0, (Gdiplus::REAL)nTextWidth, (Gdiplus::REAL)(max(size.Height, nHeight)));
			if((m_enButtonState == enBSHover) && m_bEnableHover)
			{
				SolidBrush solidBrushH(m_clrTextHover);
				BSTR bsTitle = m_strTitle.AllocSysString();
				graphics.DrawString(bsTitle, (INT)wcslen(bsTitle), &font, rect, &strFormat, &solidBrushH);
				::SysFreeString(bsTitle);
			}else
			{
				BSTR bsTitle = m_strTitle.AllocSysString();
				graphics.DrawString(bsTitle, (INT)wcslen(bsTitle), &font, rect, &strFormat, &solidBrush);
				::SysFreeString(bsTitle);
			}
		}
		else
		{
			SolidBrush solidBrushM(m_clrMark);
			SolidBrush solidBrushS(m_clrTextShadow);

			CString srtL = m_strTitle.Left(nStart);
			CString srtR  = m_strTitle.Right(m_strTitle.GetLength() - m_strMark.GetLength() - nStart);
			Size sizeL = GetTextBounds(font, strFormat, srtL);
			Size sizeM = GetTextBounds(font, strFormat, m_strMark);
			Size sizeR = GetTextBounds(font, strFormat, srtR);

			if(m_bEnableShadow)
			{
				BSTR bsL = srtL.AllocSysString();
				graphics.DrawString(bsL, (INT)wcslen(bsL), &font, 
					PointF((Gdiplus::REAL)(nXPos + 1), (Gdiplus::REAL)1), &strFormat, &solidBrushS);
				::SysFreeString(bsL);
				BSTR bsMark = m_strMark.AllocSysString();
				graphics.DrawString(bsMark, (INT)wcslen(bsMark), &font, 
					PointF((Gdiplus::REAL)(nXPos + sizeL.Width + 2 + 1), (Gdiplus::REAL)1), &strFormat, &solidBrushS);
				::SysFreeString(bsMark);
			}
			BSTR bsL = srtL.AllocSysString();
			graphics.DrawString(bsL, (INT)wcslen(bsL), &font, 
				PointF((Gdiplus::REAL)(nXPos), (Gdiplus::REAL)0), &strFormat, &solidBrush);
			::SysFreeString(bsL);
			BSTR bsMark = m_strMark.AllocSysString();
			graphics.DrawString(bsMark, (INT)wcslen(bsMark), &font, 
				PointF((Gdiplus::REAL)(nXPos + sizeL.Width + 2), (Gdiplus::REAL)0), &strFormat, &solidBrushM);
			::SysFreeString(bsMark);

			if(m_bEnableShadow)
			{
				RectF rect((Gdiplus::REAL)(nXPos + sizeL.Width + sizeM.Width + 4 + 1), (Gdiplus::REAL)(1), (Gdiplus::REAL)(nWidth - (nXPos + sizeL.Width + sizeM.Width + 4)), (Gdiplus::REAL)nHeight);
				BSTR bsR = srtR.AllocSysString();
				graphics.DrawString(bsR, (INT)wcslen(bsR), &font, 
					PointF((Gdiplus::REAL)(nXPos + sizeL.Width + sizeM.Width + 4), (Gdiplus::REAL)0), &strFormat, &solidBrushS);
				::SysFreeString(bsR);
			}
			//RectF rect(nXPos + point.x + sizeL.Width + sizeM.Width + 4, point.y, nWidth - (nXPos + sizeL.Width + sizeM.Width + 4 + point.x), size.Height);
			RectF rect((Gdiplus::REAL)(nXPos + sizeL.Width + sizeM.Width + 4), (Gdiplus::REAL)0, (Gdiplus::REAL)(nWidth - (nXPos + sizeL.Width + sizeM.Width + 4)), (Gdiplus::REAL)nHeight);
			BSTR bsR = srtR.AllocSysString();
			graphics.DrawString(bsR, (INT)wcslen(bsR), &font, 
				PointF((Gdiplus::REAL)(nXPos + sizeL.Width + sizeM.Width + 4), (Gdiplus::REAL)0), &strFormat, &solidBrush);
			::SysFreeString(bsR);
		}
	}

	dc.BitBlt(m_rc.left,m_rc.top, m_rc.Width(), m_rc.Height(), &m_memDC, 0, nVirtualTop, SRCCOPY);
}
コード例 #4
0
ファイル: Panel.cpp プロジェクト: hezlog/DuiVision
// 控件界面刷新
LRESULT CDuiPanel::OnControlUpdate(CRect rcUpdate, BOOL bUpdate, CControlBase *pUpdateControlBase) 
{
	if(pUpdateControlBase == NULL) return 0;

	if(bUpdate)
	{
		pUpdateControlBase->SetUpdate(FALSE);
	}

	int nVirtualTop = 0;
	if(m_nVirtualHeight > m_rc.Height())
	{
		// 计算显示位置
		CDuiScrollVertical* pScrollV = (CDuiScrollVertical*)m_pControScrollV;
		int nCurPos = pScrollV->GetScrollCurrentPos();	// 当前top位置
		int nMaxRange = pScrollV->GetScrollMaxRange();
		nVirtualTop = (nMaxRange > 0) ? nCurPos*(m_nVirtualHeight-m_rc.Height())/nMaxRange : 0;	// 当前显示的是虚拟图片中什么位置开始的图片
	}

	int nVirtualLeft = 0;
	if(m_nVirtualWidth > m_rc.Width())
	{
		// 计算显示位置
		CDuiScrollHorizontal* pScrollH = (CDuiScrollHorizontal*)m_pControScrollH;
		int nCurPosH = pScrollH->GetScrollCurrentPos();	// 当前top位置
		int nMaxRangeH = pScrollH->GetScrollMaxRange();
		nVirtualLeft = (nMaxRangeH > 0) ? nCurPosH*(m_nVirtualLeft-m_rc.Width())/nMaxRangeH : 0;	// 当前显示的是虚拟图片中什么位置开始的图片
	}

	CRect rcAllUpDate = rcUpdate;

	if(m_bInit)
	{
		BOOL bFind = false;

		for (size_t i = 0; i < m_vecControl.size(); i++)
		{
			CControlBase * pControlBase = m_vecControl.at(i);
			if (pControlBase)
			{
				if(bFind)
				{
					if (pControlBase->GetVisible() && !(pControlBase->GetRect() & rcUpdate).IsRectEmpty())
					{
						rcAllUpDate |= pControlBase->GetRect();
						pControlBase->SetUpdate(FALSE);
					}
				}
				else if(pControlBase == pUpdateControlBase)
				{
					bFind = true;
				}
			}
		}
	}

	// 按照滚动位置修改更新区域
	rcAllUpDate.OffsetRect(-nVirtualLeft, -nVirtualTop);
	rcAllUpDate |= m_rc;

	InvalidateRect(&rcAllUpDate);

	return 0L; 
};
コード例 #5
0
ファイル: Panel.cpp プロジェクト: hezlog/DuiVision
// 画子控件(支持滚动显示)
BOOL CDuiPanel::DrawSubControls(CDC &dc, CRect rcUpdate)
{
	// 如果不需要滚动条,则直接使用父控件的画图方法
	if(!m_bEnableScroll || ((m_nVirtualHeight <= m_rc.Height()) && (m_nVirtualWidth <= m_rc.Width())))
	{
		return __super::DrawSubControls(dc, rcUpdate);
	}

	BOOL bShowScrollV = m_nVirtualHeight > m_rc.Height();
	BOOL bShowScrollH = m_nVirtualWidth > m_rc.Width();

	// 计算显示位置
	CDuiScrollVertical* pScrollV = (CDuiScrollVertical*)m_pControScrollV;
	int nCurPosV = pScrollV->GetScrollCurrentPos();	// 当前top位置
	int nMaxRangeV = pScrollV->GetScrollMaxRange();
	int nVirtualTop = (nMaxRangeV > 0) ? nCurPosV*(m_nVirtualHeight-m_rc.Height())/nMaxRangeV : 0;	// 当前显示的是虚拟图片中什么位置开始的图片

	CDuiScrollHorizontal* pScrollH = (CDuiScrollHorizontal*)m_pControScrollH;
	int nCurPosH = pScrollH->GetScrollCurrentPos();	// 当前top位置
	int nMaxRangeH = pScrollH->GetScrollMaxRange();
	int nVirtualLeft = (nMaxRangeH > 0) ? nCurPosH*(m_nVirtualWidth-m_rc.Width())/nMaxRangeH : 0;	// 当前显示的是虚拟图片中什么位置开始的图片

	// 根据滚动条位置画子控件
	// 初始化虚拟显示dc,并复制背景到虚拟显示dc
	CBitmap	virtualBitmap;
	CDC virtualDC;
	virtualDC.CreateCompatibleDC(&dc);
	virtualBitmap.CreateCompatibleBitmap(&dc,
				bShowScrollH ? (m_rc.left + m_nVirtualWidth) : (m_rc.right - (bShowScrollV ? m_nScrollWidth : 0)),
				bShowScrollV ? (m_rc.top + m_nVirtualHeight) : (m_rc.bottom - (bShowScrollH ? m_nScrollWidth : 0)) );
	CBitmap* pOldVirtualBitmap = virtualDC.SelectObject(&virtualBitmap);
	virtualDC.BitBlt(m_rc.left+nVirtualLeft, m_rc.top+nVirtualTop,
				m_rc.Width()-(bShowScrollV ? m_nScrollWidth : 0),
				m_rc.Height()-(bShowScrollH ? m_nScrollWidth : 0),
				&dc, m_rc.left, m_rc.top, SRCCOPY);	// 背景复制到虚拟显示dc

	// 更新区域按照显示区域调整
	rcUpdate.OffsetRect(nVirtualLeft, nVirtualTop);

	// 画子控件到虚拟dc
	for (size_t i = 0; i < m_vecControl.size(); i++)
	{
		CControlBase * pControlBase = m_vecControl.at(i);
		if (pControlBase && pControlBase->GetVisible()
			&& (pControlBase != m_pControScrollV) && (pControlBase != m_pControScrollH))
		{
			// 如果顶部位置发生了变化,需要重画所有子控件,但会造成速度很慢
			if(m_nVirtualTop != nVirtualTop)
			{
				pControlBase->UpdateControl(true);
			}
			pControlBase->Draw(virtualDC, rcUpdate);		
		}
	}

	// 画滚动条,滚动条整个区域都需要更新
	m_pControScrollV->Draw(dc, m_pControScrollV->GetRect());
	m_pControScrollH->Draw(dc, m_pControScrollH->GetRect());

	m_nVirtualTop = nVirtualTop;
	m_nVirtualLeft = nVirtualLeft;

	// 虚拟显示dc复制到dc(滚动条部分不用复制)
	dc.BitBlt(m_rc.left, m_rc.top, m_rc.Width()-(bShowScrollV ? m_nScrollWidth : 0),
			m_rc.Height()-(bShowScrollH ? m_nScrollWidth : 0),
			&virtualDC, m_rc.left + nVirtualLeft, m_rc.top + nVirtualTop, SRCCOPY);

	// 释放虚拟显示dc
	virtualDC.SelectObject(pOldVirtualBitmap);
	virtualDC.DeleteDC();
	virtualBitmap.DeleteObject();

	return TRUE;
}