c++ CTriangleButton

#pragma once


// CTriangleButton

class CTriangleButton : public CButton
{
	DECLARE_DYNAMIC(CTriangleButton)

public:
	enum POINTDIRECTION {POINT_UP, POINT_DOWN, POINT_LEFT, POINT_RIGHT};
	POINTDIRECTION PointDirection;
	CRgn CurrentRegion;

	CTriangleButton();
	virtual ~CTriangleButton();

protected:
	DECLARE_MESSAGE_MAP()
public:
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
protected:
	virtual void PreSubclassWindow();
};


// TriangleButton.cpp : 实现文件
//

#include "stdafx.h"
#include "TriangleButton.h"


// CTriangleButton

IMPLEMENT_DYNAMIC(CTriangleButton, CButton)

CTriangleButton::CTriangleButton()
{
	PointDirection = POINT_RIGHT;
}

CTriangleButton::~CTriangleButton()
{
}


BEGIN_MESSAGE_MAP(CTriangleButton, CButton)
END_MESSAGE_MAP()



// CTriangleButton 消息处理程序



void CTriangleButton::DrawItem(LPDRAWITEMSTRUCT  lpDrawItemStruct)
{

	// TODO:  添加您的代码以绘制指定项
	ASSERT(lpDrawItemStruct != NULL);
	CRect rect = lpDrawItemStruct->rcItem;
	CDC* pDC   = CDC::FromHandle(lpDrawItemStruct->hDC);
	UINT state = lpDrawItemStruct->itemState;
	UINT nStyle = GetStyle();

	int nSavedDC = pDC->SaveDC();

	//make the rect a square
	rect.bottom = rect.right = min(rect.bottom, rect.right);
	pDC->FillSolidRect(rect, ::GetSysColor(COLOR_BTNFACE));

	rect.right -= 1; rect.bottom -= 1;	//avoid drawing outside area

	//make some pens
	CPen HighlightPen(PS_SOLID, 1, ::GetSysColor(COLOR_3DHIGHLIGHT));
	CPen DarkShadowPen(PS_SOLID, 1, ::GetSysColor(COLOR_3DDKSHADOW));
	CPen ShadowPen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
	CPen BlackPen(PS_SOLID, 1, RGB(0,0,0));
	//NOTE: If U use this class for NT apps only, use the implementation of FocusPen below 
	//			instead, as WIN95 doesn't support this yet (though the doc says **dang ms-fools**)
	//			(WIN98 might also support this)
	//LOGBRUSH logbrush; logbrush.lbStyle = BS_SOLID; logbrush.lbColor = RGB(0,0,0); logbrush.lbHatch = NULL;
	//CPen FocusPen(PS_COSMETIC | PS_ALTERNATE, 1, &logbrush);
	CPen FocusPen(PS_DOT, 0, RGB(0,0,0));



	//Draw button
	switch (PointDirection) 
	{
		case POINT_UP : {
			//Draw the raised/sunken edges of the button (unless flat)
			if (nStyle & BS_FLAT) {					//style is flat
				pDC->SelectObject(BlackPen);
				pDC->MoveTo(rect.right / 2, 0);
				pDC->LineTo(0, rect.bottom);
				pDC->LineTo(rect.right, rect.bottom);
				pDC->LineTo(rect.right / 2, 0);
				pDC->SelectObject(HighlightPen);
				pDC->MoveTo(rect.right / 2, 2);
				pDC->LineTo(2, rect.bottom - 1);
				pDC->LineTo(rect.right - 2, rect.bottom - 1);
				pDC->LineTo(rect.right / 2, 2);
			}	else {												//style not flat
				if ((state & ODS_SELECTED))	{	//Button is down	
					pDC->SelectObject(HighlightPen);
					pDC->MoveTo(0, rect.bottom);
					pDC->LineTo(rect.right - 1, rect.bottom);
					pDC->LineTo(rect.right / 2, 0);

					pDC->SelectObject(ShadowPen);
					pDC->LineTo(0, rect.bottom);			

					pDC->SelectObject(DarkShadowPen);
					pDC->MoveTo(rect.right / 2 - 1, 4);
					pDC->LineTo(1, rect.bottom);
				} else {											//Button is not down
					pDC->SelectObject(HighlightPen);
					pDC->MoveTo(rect.right /2, 0);
					pDC->LineTo(0, rect.bottom - 1);

					pDC->SelectObject(ShadowPen);
					pDC->LineTo(rect.right - 1, rect.bottom - 1);
					pDC->LineTo(rect.right / 2, 0);

					pDC->SelectObject(DarkShadowPen);
					pDC->MoveTo(rect.right / 2 + 2, 3);
					pDC->LineTo(rect.right + 1, rect.bottom + 1);

					pDC->MoveTo(rect.right - 1, rect.bottom);
					pDC->LineTo(1, rect.bottom);
				}//else|if
			}//else|if	
			break;
						}//case

		case POINT_DOWN : {
			//Draw the raised/sunken edges of the button (unless flat)
			if (nStyle & BS_FLAT) {					//style is flat
				pDC->SelectObject(BlackPen);
				pDC->MoveTo(rect.right / 2, rect.bottom);
				pDC->LineTo(0, 0);
				pDC->LineTo(rect.right, 0);
				pDC->LineTo(rect.right / 2, rect.bottom);

				pDC->SelectObject(HighlightPen);
				pDC->MoveTo(rect.right / 2, rect.bottom - 2);
				pDC->LineTo(2, 1);
				pDC->LineTo(rect.right - 2, 1);
				pDC->LineTo(rect.right / 2, rect.bottom - 2);
			}	else {												//style not flat
				if ((state & ODS_SELECTED))	{	//Button is down	
					pDC->SelectObject(ShadowPen);
					pDC->MoveTo(rect.right, 1);
					pDC->LineTo(1, 1);
					pDC->LineTo(rect.right / 2, rect.bottom - 1);

					pDC->SelectObject(BlackPen);
					pDC->MoveTo(rect.right - 2, 2);
					pDC->LineTo(1, 2);

					pDC->SelectObject(HighlightPen);
					pDC->MoveTo(rect.right + 1, 0);
					pDC->LineTo(rect.right / 2 + 1, rect.bottom + 1);

				} else {											//Button is not down
					pDC->SelectObject(ShadowPen);
					pDC->MoveTo(0, 0);
					pDC->LineTo(rect.right / 2, rect.bottom);
					pDC->LineTo(rect.right, 0);
					pDC->MoveTo(1, 1);
					pDC->LineTo(rect.right / 2 + 1, rect.bottom);

					pDC->SelectObject(DarkShadowPen);
					pDC->MoveTo(rect.right, 2);
					pDC->LineTo(rect.right / 2 + 1, rect.bottom + 1);

					pDC->SelectObject(HighlightPen);
					pDC->MoveTo(0, 0);
					pDC->LineTo(rect.right, 0);

				}
			}//else|if
			break;
						  }//case

		case POINT_LEFT : {
			if (nStyle & BS_FLAT) {					//style is flat
				pDC->SelectObject(BlackPen);
				pDC->MoveTo(rect.right, 0);
				pDC->LineTo(0, rect.bottom / 2);
				pDC->LineTo(rect.right, rect.bottom);
				pDC->LineTo(rect.right, 0);

				pDC->SelectObject(HighlightPen);
				pDC->MoveTo(rect.right - 1, 2);
				pDC->LineTo(3, rect.bottom / 2);
				pDC->LineTo(rect.right - 1, rect.bottom - 2);
				pDC->LineTo(rect.right - 1, 2);
			}	else {												//style not flat
				if ((state & ODS_SELECTED))	{	//Button is down	
					pDC->SelectObject(ShadowPen);
					pDC->MoveTo(rect.right, 0);
					pDC->LineTo(0, rect.bottom / 2);

					pDC->SelectObject(DarkShadowPen);
					pDC->MoveTo(rect.right, 1);
					pDC->LineTo(2, rect.bottom / 2);

					pDC->SelectObject(HighlightPen);
					pDC->MoveTo(rect.right, 0);
					pDC->LineTo(rect.right, rect.bottom);
					pDC->LineTo(0, rect.bottom / 2);
				} else {											//Button is not down
					pDC->SelectObject(ShadowPen);
					pDC->MoveTo(rect.right - 1, 0);
					pDC->LineTo(rect.right - 1, rect.bottom - 1);
					pDC->LineTo(0, rect.bottom / 2);
					pDC->MoveTo(1, rect.bottom / 2 + 1);
					pDC->LineTo(6, rect.bottom / 2 + 4);

					pDC->SelectObject(DarkShadowPen);
					pDC->MoveTo(rect.right, 1);
					pDC->LineTo(rect.right, rect.bottom);
					pDC->LineTo(2, rect.bottom / 2 + 2);

					pDC->SelectObject(HighlightPen);
					pDC->MoveTo(0, rect.bottom / 2);
					pDC->LineTo(rect.right, 0);
				}
			}//else|if
			break;
						  }//case

		case POINT_RIGHT : {
			if (nStyle & BS_FLAT) {					//style is flat
				pDC->SelectObject(BlackPen);
				pDC->MoveTo(0, 0);
				pDC->LineTo(rect.right, rect.bottom / 2);
				pDC->LineTo(0, rect.bottom);
				pDC->LineTo(0, 0);

				pDC->SelectObject(HighlightPen);
				pDC->MoveTo(1, 2);
				pDC->LineTo(rect.right - 2, rect.bottom / 2);
				pDC->LineTo(1, rect.bottom - 2);
				pDC->LineTo(1, 2);
			}	else {												//style not flat
				if ((state & ODS_SELECTED))	{	//Button is down	
					pDC->SelectObject(ShadowPen);
					pDC->MoveTo(0, rect.bottom);
					pDC->LineTo(0, 0);
					pDC->LineTo(rect.right, rect.bottom / 2);

					pDC->SelectObject(DarkShadowPen);
					pDC->MoveTo(1, rect.bottom - 2);
					pDC->LineTo(1, 1);
					pDC->MoveTo(rect.right - 3, rect.bottom / 2);
					pDC->LineTo(0, 1);

					pDC->SelectObject(HighlightPen);
					pDC->MoveTo(0, rect.bottom);
					pDC->LineTo(rect.right, rect.bottom / 2);

				} else {											//Button is not down
					pDC->SelectObject(ShadowPen);
					pDC->MoveTo(0, rect.bottom);
					pDC->LineTo(rect.right, rect.bottom / 2);

					pDC->SelectObject(DarkShadowPen);
					pDC->MoveTo(0, rect.bottom + 1);
					pDC->LineTo(rect.right, rect.bottom / 2 + 1);

					pDC->SelectObject(HighlightPen);
					pDC->MoveTo(0, rect.bottom);
					pDC->LineTo(0, 0);
					pDC->LineTo(rect.right, rect.bottom / 2);
				}
			}//else|if

			break;
						   }//case

		default :
			ASSERT(FALSE);
	}//switch



	//Draw text	if any
	CString strText;
	GetWindowText(strText);
	if (!strText.IsEmpty()) {
		CSize TextExtent = pDC->GetTextExtent(strText);
		CPoint TextPos;
		pDC->SetBkMode(TRANSPARENT);

		switch (PointDirection) {
			case POINT_UP : {
				TextPos = CPoint((int)(rect.right / 2.0 - TextExtent.cx / 2.0),
					rect.bottom - (int)(rect.bottom / 5.0 + TextExtent.cy));

				int iXLimit = (int)((rect.bottom / 5.0 + TextExtent.cy) * 4.0 / 7.0);

				CRgn rgn; rgn.CreateRectRgn(iXLimit, TextPos.y, rect.right - iXLimit, rect.bottom - 2);
				pDC->SelectClipRgn(&rgn);

				break;
							}//case
			case POINT_DOWN : {
				TextPos = CPoint((int)(rect.right / 2.0 - TextExtent.cx / 2.0),
					(int)(rect.bottom / 5.0));

				int iXLimit = (int)((rect.bottom / 5.0 + TextExtent.cy) * 4.0 / 7.0);

				CRgn rgn; rgn.CreateRectRgn(iXLimit, (int)(rect.bottom / 5.0), rect.right - iXLimit, (int)(rect.bottom / 5.0) + TextExtent.cy + 2);
				pDC->SelectClipRgn(&rgn);

				break;
							  }

			case POINT_LEFT : {
				TextPos = CPoint((int)((rect.right / 2.0 - TextExtent.cx / 2.0) + (rect.right / 8.0)),
					(int)(rect.bottom / 2.0 - TextExtent.cy / 2.0) );

				int iXLimitLeft = (int)(TextExtent.cy / 2.0 * 7.0 / 4.0) + 4;
				int iXLimitRight = rect.right - 4;

				CRgn rgn; rgn.CreateRectRgn(iXLimitLeft, (int)(rect.bottom / 2.0 - TextExtent.cy / 2.0),
					iXLimitRight, (int)(rect.bottom / 2.0 + TextExtent.cy / 2.0) );
				pDC->SelectClipRgn(&rgn);

				break;
							  }//case

			case POINT_RIGHT : {
				TextPos = CPoint((int)((rect.right / 2.0 - TextExtent.cx / 2.0) - (rect.right / 8.0)),
					(int)(rect.bottom / 2.0 - TextExtent.cy / 2.0) );

				int iXLimitLeft = 4;
				int iXLimitRight = rect.right - (int)(TextExtent.cy / 2.0 * 7.0 / 4.0) - 4;

				CRgn rgn; rgn.CreateRectRgn(iXLimitLeft, (int)(rect.bottom / 2.0 - TextExtent.cy / 2.0),
					iXLimitRight, (int)(rect.bottom / 2.0 + TextExtent.cy / 2.0) );
				pDC->SelectClipRgn(&rgn);

				break;
							   }//case

			default :
				ASSERT(FALSE);
		}//switch

		//common for all directions
		if (state & ODS_SELECTED) TextPos.Offset(1,1);

		if (state & ODS_DISABLED) {
			pDC->DrawState(TextPos, TextExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
		} else {
			pDC->TextOut(TextPos.x, TextPos.y, strText);
		}

	}//if			


	

	pDC->RestoreDC(nSavedDC);

}

void CTriangleButton::PreSubclassWindow()
{
	// TODO: 在此添加专用代码和/或调用基类

	CButton::PreSubclassWindow();

	//get client rectangle
	CRect rect;
	GetClientRect(rect);
	rect.bottom = rect.right = min(rect.bottom,rect.right);	//make it square
	rect.bottom -= rect.bottom % 2; rect.right -= rect.right % 2;

	SetWindowPos(NULL, 0, 0, rect.right, rect.bottom, SWP_NOMOVE | SWP_NOZORDER);

	CPoint Head, RightLeg, LeftLeg;

	switch (PointDirection) {
		case POINT_UP :
			Head.x = rect.right / 2; Head.y = 0;
			RightLeg.x = rect.right; RightLeg.y = rect.bottom;
			LeftLeg.x = 0; LeftLeg.y = rect.bottom;
			break;
		case POINT_DOWN :
			Head.x = rect.right / 2; Head.y = rect.bottom;
			RightLeg.x = 0; RightLeg.y = 0;
			LeftLeg.x = rect.right; LeftLeg.y = 0;
			break;
		case POINT_LEFT :
			Head.x = 0; Head.y = rect.bottom / 2;
			RightLeg.x = rect.right; RightLeg.y = 0;
			LeftLeg.x = rect.right; LeftLeg.y = rect.bottom;
			break;
		case POINT_RIGHT :
			Head.x = rect.right; Head.y = rect.bottom / 2;
			RightLeg.x = 0; RightLeg.y = rect.bottom;
			LeftLeg.x = 0; LeftLeg.y = 0;
			break;
		default :
			ASSERT(FALSE);
	}//switch

	CPoint points[3];
	points[0] = Head; points[1] = RightLeg; points[2] = LeftLeg;

	SetWindowRgn(NULL, FALSE);

	CurrentRegion.DeleteObject();
	CurrentRegion.CreatePolygonRgn(points, 3, ALTERNATE);

	SetWindowRgn(CurrentRegion, TRUE);

	ModifyStyle(0, BS_OWNERDRAW);
}

 

已标记关键词 清除标记
<p> <span style="color:#337FE5;"><strong>【为什么还需要学习C++?】</strong></span> </p> <p style="margin-left:0cm;"> 你是否接触很多语言,但从来没有了解过编程语言的本质? </p> <p style="margin-left:0cm;text-align:start;"> 你是否想成为一名资深开发人员,想开发别人做不了的高性能程序? </p> <p style="margin-left:0cm;text-align:start;"> 你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹? </p> <p style="margin-left:0cm;text-align:start;">   </p> <p style="margin-left:0cm;text-align:start;"> 那么C++就是你个人能力提升,职业之路进阶的不二之选。 </p> <p style="margin-left:0cm;text-align:start;"> <br /> </p> <p style="margin-left:0cm;text-align:start;"> <br /> </p> <p style="margin-left:0cm;"> <strong><span style="color:#337FE5;">【课程特色】</span></strong> </p> <p style="margin-left:0cm;text-align:start;"> 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。 </p> <p style="margin-left:0cm;text-align:start;"> 2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。 </p> <p style="margin-left:0cm;text-align:start;"> 3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。 </p> <p style="margin-left:0cm;text-align:start;"> <br /> </p> <p class="ql-long-24357476"> <span style="color:#337FE5;"><strong>【学完后我将达到什么水平?】</strong></span> </p> <p class="ql-long-24357476"> 1.对C++的各个知识能够熟练配置、开发、部署; </p> <p class="ql-long-24357476"> 2.吊打一切关于C++的笔试面试题; </p> <p class="ql-long-24357476"> 3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。 </p> <p class="MsoNoSpacing" style="margin-left:18pt;"> <br /> </p> <div> <br /> </div> <p> <br /> </p> <p style="margin-left:0cm;text-align:start;"> <span style="color:#337FE5;"><strong>【面向人群】</strong></span> </p> <p style="margin-left:0cm;text-align:start;"> <span style="color:#222226;font-family:PingFangSC-Regular, "font-size:14px;background-color:#FFFFFF;">1.希望一站式快速入门的C++初学者;</span> </p> <p style="margin-left:0cm;text-align:start;"> <span style="color:#222226;font-family:PingFangSC-Regular, "font-size:14px;background-color:#FFFFFF;">2.希望快速学习 C++、掌握编程要义、修炼内功的开发者;</span> </p> <p style="margin-left:0cm;text-align:start;"> <span style="color:#222226;font-family:PingFangSC-Regular, "font-size:14px;background-color:#FFFFFF;">3.有志于挑战更高级的开发项目,成为资深开发的工程师。</span> </p> <p style="margin-left:0cm;text-align:start;"> <br /> </p> <p> <br /> </p> <p> <span style="color:#337FE5;"><strong>【课程设计】</strong></span> </p> <p> 本课程包含3大模块 </p> <p> <strong>基础篇</strong><br /> 本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。 </p> <p> <br /> <strong>进阶篇</strong><br /> 本篇主要讲解编程中常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。 </p> <p> <br /> <strong>提升篇:</strong><br /> 本篇可以帮助学员更加高效的进行c++开发,其中包含类型转换、文件操作、异常处理、代码重用等内容。 </p> <p> <img src="https://img-bss.csdnimg.cn/202007091130239667.png" alt="" /> </p>
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页