Пример #1
0
void CDuiSlider::DrawControl(CDC &dc, CRect rcUpdate)
{
	int nWidth = m_rc.Width();
	int nHeight = m_rc.Height();

	if(!m_bUpdate)
	{
		UpdateMemDC(dc, nWidth, nHeight * 4);

		Graphics graphics(m_memDC);

		// 画4个状态的内存图片
		for(int i = 0; i < 4; i++)
		{
			// 复制背景
			m_memDC.BitBlt(0, i * nHeight, nWidth, nHeight, &dc, m_rc.left ,m_rc.top, SRCCOPY);

			int nPosY = i * nHeight;

			if(m_pImageForeGround != NULL)	// 使用背景和前景图片画进度条
			{
				if(m_pImageBackGround != NULL)	// 画背景
				{
					DrawImageFrameMID(graphics, m_pImageBackGround, CRect(0, nPosY + m_nThumbTop, nWidth, nPosY + m_nThumbTop + m_nSliderHeight),
						0, 0, m_sizeBackGround.cx, m_sizeBackGround.cy,
						m_nHeadLength, 0, m_nHeadLength, 0);
				}

				if(m_nProgress != 0)	// 画前景
				{
					DrawImageFrameMID(graphics, m_pImageForeGround, CRect(0, nPosY + m_nThumbTop, nWidth * m_nProgress / m_nMaxProgress, nPosY + m_nThumbTop + m_nSliderHeight),
						0, 0, m_sizeForeGround.cx, m_sizeForeGround.cy,
						m_nHeadLength, 0, m_nHeadLength, 0);
				}
			}else
			if(m_pImage != NULL)	// 使用单张图片画进度条
			{
				DrawImageFrame(graphics, m_pImage, CRect(0, nPosY + m_nThumbTop, nWidth, nPosY + m_nThumbTop + m_nSliderHeight), 
					0, 0, m_sizeImage.cx, m_sizeImage.cy, 2);

				if(m_nProgress != 0)
				{
					DrawImageFrame(graphics, m_pImage, CRect(0, nPosY + m_nThumbTop, nWidth * m_nProgress / m_nMaxProgress, nPosY + m_nThumbTop + m_nSliderHeight), 
						m_sizeImage.cx, 0, m_sizeImage.cx, m_sizeImage.cy, 2);
				}
			}

			// 画滑块
			if(m_pImageThumb != NULL)
			{
				// 计算滑块的位置
				int nPos = (int)__max(m_rc.Width() * m_nProgress / m_nMaxProgress - m_nThumbWidth / 2, 0);
				nPos = (int)__min(nPos, m_rc.Width() - m_nThumbWidth);
				Rect rect(nPos, nPosY, m_nThumbWidth, m_nThumbHeight);
				graphics.DrawImage(m_pImageThumb, rect, i * m_sizeThumb.cx, 0, m_sizeThumb.cx, m_sizeThumb.cy, UnitPixel);
			}

			// 画进度文字
			if(m_bShowText)
			{
				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( StringFormatFlagsNoClip | StringFormatFlagsMeasureTrailingSpaces);

				CString strText;
				// 只有最大值设置为100情况下才会显示百分号
				strText.Format(_T("%s%d%s"), m_strTitle, m_nProgress, (m_nMaxProgress == 100) ? _T("%") : _T(""));
				BSTR bsTitle = strText.AllocSysString();
				RectF rect((Gdiplus::REAL)(0), (Gdiplus::REAL)nPosY, (Gdiplus::REAL)nWidth, (Gdiplus::REAL)nHeight);
				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, 0, m_enButtonState * nHeight, SRCCOPY);
}
Пример #2
0
void CWndShadow::Update(HWND hParent)
{
	//int ShadSize = 5;
	//int Multi = 100 / ShadSize;

	RECT WndRect;
	GetWindowRect(hParent, &WndRect);
	int nShadWndWid = 0;
	int nShadWndHei = 0;
	if(m_pShadowImage != NULL)
	{
		// 九宫格方式,计算阴影窗口总的宽度和高度
		nShadWndWid = WndRect.right - WndRect.left + m_nShadowWLT + m_nShadowWRB;
		nShadWndHei = WndRect.bottom - WndRect.top + m_nShadowHLT + m_nShadowHRB;
	}else
	{
		// 算法阴影方式,计算阴影窗口总的宽度和高度
		nShadWndWid = WndRect.right - WndRect.left + m_nSize * 2;
		nShadWndHei = WndRect.bottom - WndRect.top + m_nSize * 2;
	}

	// Create the alpha blending bitmap
	BITMAPINFO bmi;        // bitmap header

	ZeroMemory(&bmi, sizeof(BITMAPINFO));
	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bmi.bmiHeader.biWidth = nShadWndWid;
	bmi.bmiHeader.biHeight = nShadWndHei;
	bmi.bmiHeader.biPlanes = 1;
	bmi.bmiHeader.biBitCount = 32;         // four 8-bit components
	bmi.bmiHeader.biCompression = BI_RGB;
	bmi.bmiHeader.biSizeImage = nShadWndWid * nShadWndHei * 4;

	BYTE *pvBits;          // pointer to DIB section
	HBITMAP hbitmap = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&pvBits, NULL, 0);
	HDC hMemDC = CreateCompatibleDC(NULL);
	HBITMAP hOriBmp = (HBITMAP)SelectObject(hMemDC, hbitmap);

	if(m_pShadowImage != NULL)
	{
		// 九宫格方式画阴影图片
		Graphics graphics(hMemDC);
		CRect rcTemp(0, 0, nShadWndWid, nShadWndHei);
		DrawImageFrameMID(graphics, m_pShadowImage, rcTemp,
			0, 0, m_pShadowImage->GetWidth(), m_pShadowImage->GetHeight(),
			m_nShadowWLT, m_nShadowHLT, m_nShadowWRB+1, m_nShadowHRB+1);
	}else
	{
		// 画算法阴影
		ZeroMemory(pvBits, bmi.bmiHeader.biSizeImage);
		MakeShadow((UINT32 *)pvBits, hParent, &WndRect);
	}

	// 计算阴影窗口偏移位置
	POINT ptDst;  
    if(m_pShadowImage != NULL)  
    {
        ptDst.x = WndRect.left - m_nShadowWLT;  
        ptDst.y = WndRect.top - m_nShadowHLT;  
    }  
    else  
    {  
        ptDst.x = WndRect.left + m_nxOffset - m_nSize;  
        ptDst.y = WndRect.top + m_nyOffset - m_nSize;  
    }

	POINT ptSrc = {0, 0};
	SIZE WndSize = {nShadWndWid, nShadWndHei};
	BLENDFUNCTION blendPixelFunction= { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };

	MoveWindow(m_hWnd, ptDst.x, ptDst.y, nShadWndWid, nShadWndHei, FALSE);

	BOOL bRet= s_UpdateLayeredWindow(m_hWnd, NULL, &ptDst, &WndSize, hMemDC,
		&ptSrc, 0, &blendPixelFunction, ULW_ALPHA);

	_ASSERT(bRet); // something was wrong....

	// Delete used resources
	SelectObject(hMemDC, hOriBmp);
	DeleteObject(hbitmap);
	DeleteDC(hMemDC);

}
Пример #3
0
// 画控件
void CDuiTabCtrl::DrawControl(CDC &dc, CRect rcUpdate)
{
	int nWidth = m_rc.Width();
	//int nHeight = m_rc.Height();	// 纵向内存DC的高度是整个tabctrl的高度,不只是页签部分高度
	int nTabHeight = m_nTabCtrlHeight;	// 纵向内存DC高度改为tabctrl部分高度

	if(!m_bUpdate)
	{
		// 创建内存DC,纵向分为6层:
		// 1.tab页签图片-原图
		// 2.tab页签图片-鼠标热点
		// 3.tab页签图片-鼠标按下
		// 4,5,6层是上面3层的备份
		UpdateMemDC(dc, nWidth, nTabHeight * 3 * 2);

		Graphics graphics(m_memDC);

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

		// 设置tab页签文字的水平和垂直对齐方式
		DUI_STRING_ALIGN_DEFINE();
		strFormat.SetFormatFlags( StringFormatFlagsNoWrap | StringFormatFlagsMeasureTrailingSpaces);
		
		// 画内存DC的3个层的内容
		for(int i = 0; i < 3; i++)
		{
			// 将背景内容拷贝到内存DC
			m_memDC.BitBlt(0, i * nTabHeight, nWidth, nTabHeight, &dc, m_rc.left, m_rc.top, SRCCOPY);

			// 画tab页签
			int nXPos = m_nTabLeftPading;
			int nYPos = i * nTabHeight;
			for(size_t j = 0; j < m_vecItemInfo.size(); j++)
			{
				TabItemInfo &itemInfo = m_vecItemInfo.at(j);
				
				if(!itemInfo.bVisible)
				{
					continue;
				}

				// 图片位置(根据对齐方式进行计算)
				CPoint point = GetOriginPoint(m_nTabItemWidth, m_nTabCtrlHeight, itemInfo.sizeImage.cx, itemInfo.sizeImage.cy,
						GetGDIAlignment(m_uAlignment), GetGDIVAlignment(m_uVAlignment));
				// 如果有图片和文字,则图片的垂直对齐按照上对齐方式
				if(!itemInfo.strText.IsEmpty())
				{
					point.y = 0;
				}

				// 画tab页签底图
				if(itemInfo.pImage != NULL)	// 如果页签设置了图片,则使用tab页签指定的图片
				{
					int nImageIndex = i;
					if(itemInfo.nImageCount == 1)
					{
						nImageIndex = 0;
					}
					graphics.DrawImage(itemInfo.pImage, Rect(nXPos + point.x, nYPos + point.y,  itemInfo.sizeImage.cx, itemInfo.sizeImage.cy),
						itemInfo.sizeImage.cx * nImageIndex, 0, itemInfo.sizeImage.cx, itemInfo.sizeImage.cy, UnitPixel);
				}else
				if((m_pImage != NULL) && (itemInfo.nImageIndex != -1))	// 如果设置了页签图片索引,使用tabctrl图片的索引图片
				{
					if(m_enTabImageMode == enTIMNormal)	// 普通模式
					{
						graphics.DrawImage(m_pImage, Rect(nXPos + point.x, nYPos + point.y,  itemInfo.sizeImage.cx, itemInfo.sizeImage.cy),
							itemInfo.sizeImage.cx * itemInfo.nImageIndex, 0, itemInfo.sizeImage.cx, itemInfo.sizeImage.cy, UnitPixel);
					}else
					if(m_enTabImageMode == enTIMMID)	// 九宫格模式
					{
						CRect rcTemp(nXPos, nYPos, nXPos+m_nTabItemWidth, nYPos+m_nTabCtrlHeight);
						DrawImageFrameMID(graphics, m_pImage, rcTemp, m_sizeImage.cx * i, 0, m_sizeImage.cx, m_sizeImage.cy,
							m_nWLT, m_nHLT, m_nWRB, m_nHRB);
					}
				}

				// 画tab页签热点图(如果存在tabctrl设置的热点图的话)
				if((m_pImageHover != NULL) && (i > 0))
				{
					int nX = (itemInfo.rc.Width() - m_sizeHover.cx) / 2;
					if(nX < 0)
					{
						nX = 0;
					}
					graphics.DrawImage(m_pImageHover, Rect(nXPos + nX, nYPos,  m_sizeHover.cx, m_sizeHover.cy),
						m_sizeHover.cx * (i-1), 0, m_sizeHover.cx, m_sizeHover.cy, UnitPixel);
				}

				// 画tab页签文字
				if(!itemInfo.strText.IsEmpty())
				{
					// 设置页签文字颜色
					SolidBrush solidBrushItem(m_clrText);
					if((m_nHoverItem == j) && (m_clrTextHover.GetValue() != Color(0, 0, 0, 0).GetValue()))	// 设置了鼠标移动颜色,则使用
					{
						solidBrushItem.SetColor(m_clrTextHover);
					}else
					if((m_nDownItem == j) && (m_clrTextDown.GetValue() != Color(0, 0, 0, 0).GetValue()))	// 设置了鼠标按下颜色,则使用
					{
						solidBrushItem.SetColor(m_clrTextDown);
					}

					RectF rectText((Gdiplus::REAL)nXPos,
							(Gdiplus::REAL)(nYPos + itemInfo.sizeImage.cy + 1),
							(Gdiplus::REAL)((m_pImageTabBtn != NULL) ? (itemInfo.rc.Width()-m_sizeTabBtn.cx) : itemInfo.rc.Width()),
							(Gdiplus::REAL)(m_nTabCtrlHeight - itemInfo.sizeImage.cy - 1));
					if(m_nTabCtrlHeight <= itemInfo.sizeImage.cy)
					{
						// 如果tabctrl高度小于图片高度,则文字直接居中显示
						rectText.Y = (Gdiplus::REAL)nYPos;
						rectText.Height = (Gdiplus::REAL)m_nTabCtrlHeight;
					}

					// 计算是否需要显示tip
					itemInfo.bNeedTextTip = rectText.Width < GetTextBounds(font, itemInfo.strText).Width;

					BSTR bsText = itemInfo.strText.AllocSysString();
					graphics.DrawString(bsText, (INT)wcslen(bsText), &font, rectText, &strFormat, &solidBrushItem);
					::SysFreeString(bsText);
				}

				nXPos += itemInfo.rc.Width();

				// 画tab页签之间的分隔图片(采用拉伸方式)
				if(j < m_vecItemInfo.size() - 1 && m_pImageSeperator != NULL)
				{
					CRect &rc = m_vecRcSeperator.at(j);
					int nSepHeight = itemInfo.rc.Height();	// m_sizeSeperator.cy
					graphics.DrawImage(m_pImageSeperator, Rect(nXPos, nYPos, m_sizeSeperator.cx, nSepHeight),
						0, 0, m_sizeSeperator.cx, m_sizeSeperator.cy, UnitPixel);

					nXPos += m_sizeSeperator.cx;
				}
			}
		}

		// 内存dc复制一份进行备份
		m_memDC.BitBlt(0, nTabHeight * 3, nWidth, nTabHeight * 3, &m_memDC, 0, 0, SRCCOPY);
	}

	// 画Tab页签按钮到内存dc
	if(m_pImageTabBtn != NULL)
	{
		// 现将备份的内存dc整体进行恢复,避免页签按钮叠加之后的影响
		m_memDC.BitBlt(0, 0, nWidth, nTabHeight * 3, &m_memDC, 0, nTabHeight * 3, SRCCOPY);

		Graphics graphics(m_memDC);
		for(int i = 0; i < 3; i++)
		{
			for(size_t j = 0; j < m_vecItemInfo.size(); j++)
			{
				TabItemInfo &itemInfo = m_vecItemInfo.at(j);
				graphics.DrawImage(m_pImageTabBtn,
					RectF((Gdiplus::REAL)itemInfo.rcButton.left, (Gdiplus::REAL)(nTabHeight * i + itemInfo.rcButton.top),
					(Gdiplus::REAL)itemInfo.rcButton.Width(), (Gdiplus::REAL)itemInfo.rcButton.Height()),
					(Gdiplus::REAL)(itemInfo.buttonState * m_sizeTabBtn.cx), 0,
					(Gdiplus::REAL)m_sizeTabBtn.cx, (Gdiplus::REAL)m_sizeTabBtn.cy,
					UnitPixel); 
			}
		}
	}

	// 内存dc输出到dc
	// 1.画原图
	dc.BitBlt(m_rc.left,m_rc.top, nWidth, nTabHeight, &m_memDC, 0, 0, SRCCOPY);

	// 2.画鼠标热点的Tab页签
	if((m_nHoverItem != -1) && (m_nHoverItem < (int)m_vecItemInfo.size()))
	{
		TabItemInfo &itemInfo = m_vecItemInfo.at(m_nHoverItem);

		dc.BitBlt(itemInfo.rc.left, itemInfo.rc.top, itemInfo.rc.Width(), itemInfo.rc.Height(), &m_memDC,
			itemInfo.rc.left - m_rc.left, itemInfo.rc.top - m_rc.top + nTabHeight, SRCCOPY);
	}

	// 3.画鼠标按下的Tab页签
	if((m_nDownItem != -1) && (m_nDownItem < (int)m_vecItemInfo.size()))
	{
		TabItemInfo &itemInfo = m_vecItemInfo.at(m_nDownItem);

		dc.BitBlt(itemInfo.rc.left, itemInfo.rc.top, itemInfo.rc.Width(), itemInfo.rc.Height(), &m_memDC,
			itemInfo.rc.left - m_rc.left, itemInfo.rc.top - m_rc.top + nTabHeight * 2, SRCCOPY);
	}
}
Пример #4
0
void CDlgPopup::DrawWindow(CDC *pDC)
{
	if(!m_bInitFinish) return;

	CRect rcClient;
	GetClientRect(&rcClient);

	CDC MemDC;
	MemDC.CreateCompatibleDC(pDC);

	CBitmap memBit;
	//memBit.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
	// 因为直接使用CreateCompatibleBitmap在16位颜色下会有问题,因此改为调用DuiCreateCompatibleBitmap函数
	HBITMAP	hMemBitmap = DuiCreateCompatibleBitmap(rcClient);
	memBit.Attach(hMemBitmap);

	CBitmap *pOldBit = MemDC.SelectObject(&memBit);

	MemDC.SetBkMode(TRANSPARENT);
	if(m_pImage)
	{
		Graphics graphics(MemDC);
		if(m_enBackMode == enBMFrame)	// 边框模式
		{
			DrawImageFrame(graphics, m_pImage, rcClient, 0, 0, m_sizeBKImage.cx, m_sizeBKImage.cy, m_nFrameSize);
		}else
		if(m_enBackMode == enBMMID)	// 九宫格边框模式
		{
			DrawImageFrameMID(graphics, m_pImage, rcClient, 0, 0, m_sizeBKImage.cx, m_sizeBKImage.cy,
				m_nFrameWLT, m_nFrameHLT, m_nFrameWRB, m_nFrameHRB);
		}else	// 图片模式
		{
			graphics.DrawImage(m_pImage, Rect(0, 0, m_sizeBKImage.cx, m_sizeBKImage.cy), 0, 0, m_sizeBKImage.cx, m_sizeBKImage.cy, UnitPixel);
		}
	}
	else
	{
		MemDC.FillSolidRect(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), RGB(0, 147, 209));
		MemDC.FillSolidRect(rcClient.left + 1, rcClient.top + 1, rcClient.Width() - 2, rcClient.Height() - 2, RGB(255, 255, 255));
	}

	DrawWindow(MemDC, rcClient);
	DrawWindowEx(MemDC, rcClient);

	for (size_t i = 0; i < m_vecArea.size(); i++)
	{
		CControlBase * pControlBase = m_vecArea.at(i);
		if (pControlBase)
		{
			pControlBase->Draw(MemDC, rcClient);
		}
	}

	for (size_t i = 0; i < m_vecControl.size(); i++)
	{
		CControlBase * pControlBase = m_vecControl.at(i);
		if (pControlBase)
		{
			pControlBase->Draw(MemDC, rcClient);			
		}
	}

	ClientToScreen(&rcClient);
	POINT pointDes;
	pointDes.x = rcClient.left;
	pointDes.y = rcClient.top;
	POINT pointSrc;
	pointSrc.x = 0;
	pointSrc.y = 0;
	SIZE sizeDes;
	sizeDes.cx = rcClient.Width();
	sizeDes.cy = rcClient.Height();

	BLENDFUNCTION blend;
	memset( &blend, 0, sizeof( blend) );
	blend.AlphaFormat = AC_SRC_ALPHA ;
	blend.SourceConstantAlpha = m_nBackTranslucent;

	HWND hWnd = GetSafeHwnd();
	SetWindowLong(hWnd,GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
	// 如果允许背景Alpha通道,则根据是否有背景图片决定是否使用Aplha通道
	DWORD dwFlags = 0;
	if(m_bBackAlpha)
	{
		dwFlags = (m_pImage ? ULW_ALPHA : ULW_COLORKEY);
	}
	UpdateLayeredWindow(pDC, &pointDes, &sizeDes, &MemDC, &pointSrc, 0, &blend, dwFlags);

	MemDC.SelectObject(pOldBit);
	memBit.DeleteObject();
	MemDC.DeleteDC();
}