VC++ CDialog 자체 그리기(개선 버전)

최소화, 최대화/복원, 닫기 단추를 설정하는 것이 번거롭다는 점을 감안하여 직접 최소화, 최대화/닫기, 닫기 단추를 새로 추가했습니다.핵심 코드는 다음과 같습니다.
void CSWDialog::DrawSysMenu(Gdiplus::Graphics& g)
{
	CRect rcClient; GetClientRect(rcClient);
	g.SetSmoothingMode(Gdiplus::/*SmoothingModeAntiAlias*/SmoothingModeHighQuality);
	if (m_bSysMnu[SYSMNU_CLOSE])
	{
		if (m_pSysCloseBitmap)
		{
			CRect rcClip = CRect(0, 0, m_pSysCloseBitmap->GetWidth() / 3, m_pSysCloseBitmap->GetHeight());
			if (m_nSysMnuHover == SYSMNU_CLOSE)
				rcClip.OffsetRect(m_pSysCloseBitmap->GetWidth() / 3, 0);
			CRect rcShow(m_rcClose);
			g.DrawImage(m_pSysCloseBitmap, RectF(rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height()), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), UnitPixel, NULL, NULL, NULL);
		}
		else
		{
			CRect rcShow(m_rcClose);

			//////////////////////////////////////////////////////////////////////////
			if (m_nSysMnuHover == SYSMNU_CLOSE)			{
				
				BYTE byAlpha = 128;
				Color colors[] =
				{
					Color(byAlpha, 255, 255, 255),
					Color(byAlpha, 0, 255, 0),
				};
				float positions[] = { 0.0f, 1.0f };
				LinearGradientBrush linGrBrush(RectF(0, 0, 80, 80), Color::White, Color::Green, LinearGradientModeVertical);
				//linGrBrush.SetInterpolationColors(colors, positions, 2);
				g.FillRectangle(&linGrBrush, rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height());
			}

			{
				rcShow.DeflateRect(6, 6);
				g.TranslateTransform(rcShow.left, rcShow.top);
				Gdiplus::Pen pen(Color(240, 0, 0, 0), 3);
				pen.SetStartCap(Gdiplus::LineCapRound);
				pen.SetEndCap(Gdiplus::LineCapRound);
				pen.SetLineJoin(Gdiplus::LineJoinRound);
				Point points[] = { Point(0, 0), Point(rcShow.Width(), rcShow.Height()), Point(0, rcShow.Height()), Point(rcShow.Width(), 0) };
				g.DrawLine(&pen, points[0], points[1]);
				g.DrawLine(&pen, points[2], points[3]);
				g.ResetTransform();
			}
			//////////////////////////////////////////////////////////////////////////
		}
	}

	if (m_bSysMnu[SYSMNU_MAX])
	{
		if (m_pSysMaxBitmap)
		{
			CRect rcClip = CRect(0, 0, m_pSysMaxBitmap->GetWidth() / 3, m_pSysMaxBitmap->GetHeight() / 2);
			if (IsZoomed())
				rcClip.OffsetRect(0, m_pSysMaxBitmap->GetHeight() / 2);

			if (m_nSysMnuHover == SYSMNU_MAX)
				rcClip.OffsetRect(m_pSysMaxBitmap->GetWidth() / 3, 0);

			CRect rcShow(m_rcMax);
			g.DrawImage(m_pSysMaxBitmap, RectF(rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height()), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), UnitPixel, NULL, NULL, NULL);
		}
		else
		{
			CRect rcShow(m_rcMax);

			//////////////////////////////////////////////////////////////////////////
			if (m_nSysMnuHover == SYSMNU_MAX) {

				BYTE byAlpha = 128;
				Color colors[] =
				{
					Color(byAlpha, 255, 255, 255),
					Color(byAlpha, 0, 255, 0),
				};
				float positions[] = { 0.0f, 1.0f };
				LinearGradientBrush linGrBrush(RectF(0, 0, 80, 80), Color::White, Color::Green, LinearGradientModeVertical);
				//linGrBrush.SetInterpolationColors(colors, positions, 2);
				g.FillRectangle(&linGrBrush, rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height());
			}

			{
				rcShow.DeflateRect(6, 6);				
				Gdiplus::Pen pen(Color(255, 0, 0, 0), 2);
				if (IsZoomed())
				{
					rcShow.top += 8;
					rcShow.right -= 8;
					g.TranslateTransform(rcShow.left, rcShow.top);
					g.DrawRectangle(&pen, 0, 0, rcShow.Width(), rcShow.Height());
					Point points[] = { Point(0, 2), Point(rcShow.Width(), 2) };
					g.DrawLine(&pen, points[0], points[1]);

					rcShow.OffsetRect(8, -8);
					{
						g.ResetTransform();
						g.TranslateTransform(rcShow.left, rcShow.top);
						g.DrawRectangle(&pen, 0, 0, rcShow.Width(), 2);
						//g.DrawLine(&pen, Point(0, 0), Point(rcShow.Width(), 0));
						//g.DrawLine(&pen, Point(0, 1), Point(rcShow.Width(), 1));
						g.DrawLine(&pen, Point(0, 0), Point(0, rcShow.Height() - 5));
						g.DrawLine(&pen, Point(rcShow.Width(), 0), Point(rcShow.Width(), rcShow.Height()));
						g.DrawLine(&pen, Point(5, rcShow.Height()), Point(rcShow.Width(), rcShow.Height()));
					}
				}
				else
				{
					g.TranslateTransform(rcShow.left, rcShow.top);
					g.DrawRectangle(&pen, 0, 0, rcShow.Width(), rcShow.Height());
					Point points[] = { Point(0, 2), Point(rcShow.Width(), 2) };
					g.DrawLine(&pen, points[0], points[1]);
				}
				g.ResetTransform();
			}
			//////////////////////////////////////////////////////////////////////////
		}
	}

	if (m_bSysMnu[SYSMNU_MIN])
	{
		if (m_pSysMinBitmap)
		{
			CRect rcClip = CRect(0, 0, m_pSysMinBitmap->GetWidth() / 3, m_pSysMinBitmap->GetHeight());
			if (m_nSysMnuHover == SYSMNU_MIN)
				rcClip.OffsetRect(m_pSysMinBitmap->GetWidth() / 3, 0);
			CRect rcShow(m_rcMin);
			g.DrawImage(m_pSysMinBitmap, RectF(rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height()), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), UnitPixel, NULL, NULL, NULL);
		}
		else
		{
			CRect rcShow(m_rcMin);

			//////////////////////////////////////////////////////////////////////////
			if (m_nSysMnuHover == SYSMNU_MIN) {

				BYTE byAlpha = 128;				
				Color colors[] =
				{
					Color(byAlpha, 255, 255, 255),
					Color(byAlpha, 0, 255, 0),
				};
				float positions[] = { 0.0f, 1.0f };
				LinearGradientBrush linGrBrush(RectF(0, 0, 80, 80), Color::White, Color::Green, LinearGradientModeVertical);
				//linGrBrush.SetInterpolationColors(colors, positions, 2);
				g.FillRectangle(&linGrBrush, rcShow.left, rcShow.top, rcShow.Width(), rcShow.Height());
			}

			{
				rcShow.DeflateRect(6, 6);
				rcShow.OffsetRect(0, 16);
				g.TranslateTransform(rcShow.left, rcShow.top);
				Gdiplus::SolidBrush brush(Color(255, 0, 0, 0));
				g.FillRectangle(&brush, 0, 0, rcShow.Width(), 3);
				g.ResetTransform();
			}
			//////////////////////////////////////////////////////////////////////////
		}
	}
}

좋은 웹페이지 즐겨찾기