⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 area.cpp

📁 Windows 图形编程 书籍
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	static TCHAR mess[128];
	RECT rect;

	GetRgnBox(hRegion, & rect);

	if ( PtInRegion(hRegion, x, y) )
		wsprintf(mess, "(%d, %d) in [%d,%d,%d,%d]", x, y, rect.left, rect.top, rect.right, rect.bottom);
	else
		wsprintf(mess, "(%d, %d) not in [%d,%d,%d,%d]", x, y, rect.left, rect.top, rect.right, rect.bottom);

	return mess;
}

BOOL RectContainedInRegion(HRGN hrgn, CONST RECT * lprc)
{
	HRGN hCombine = CreateRectRgnIndirect(lprc);
	CombineRgn(hCombine, hrgn, hCombine, RGN_OR);
	
	BOOL rslt = EqualRgn(hCombine, hrgn);
	
	DeleteObject(hCombine);

	return rslt;
}


void KMyCanvas::TestRegionOper(HDC hDC)
{
	HRGN hRgn1 = CreateRectRgn(0, 0, 0, 0);
	HRGN hRgn2 = CreateRectRgn(0, 0, 1, 1);
	HRGN hRgn3 = CreateRectRgn(1, 1, 1, 1);
	HRGN hRgn4 = CreateRectRgn(10, 10, 1, 1);
	HRGN hRgn5 = CreateEllipticRgn(10, 10, 1, 1);
	HRGN hRgn6 = CreateRectRgn(- (1<<27), - (1<<27), (1<<27)-1, (1<<27)-1);

	Label(hDC, 180, 10, TestPtInRegion(0, 0, hRgn1));
	Label(hDC, 180, 30, TestPtInRegion(0, 0, hRgn2));
	Label(hDC, 180, 50, TestPtInRegion(1, 0, hRgn2));
	Label(hDC, 180, 70, TestPtInRegion(1, 1, hRgn3));
	
	Label(hDC, 320, 10, TestPtInRegion(1, 1, hRgn4));
	Label(hDC, 320, 30, TestPtInRegion(5, 5, hRgn5));
	Label(hDC, 320, 50, TestPtInRegion(5, 5, hRgn6));

	if ( EqualRgn(hRgn1, hRgn3) )
		Label(hDC, 340, 70, "Empty Set Unique");
	else
		Label(hDC, 340, 70, "Empty Set Not Unique");

	RECT rect = { 2, 2, 4, 5 };
	RectContainedInRegion(hRgn4, & rect);
	RectContainedInRegion(hRgn2, & rect);

	DeleteObject(hRgn1);
	DeleteObject(hRgn2);
	DeleteObject(hRgn3);
	DeleteObject(hRgn4);
	DeleteObject(hRgn5);
	DeleteObject(hRgn6);
	
	////////////////////////////////
	{
		HRGN hRgn1 = CreateEllipticRgn(0, 0, 110, 100);
		HRGN hRgn2 = CreateEllipticRgn(0, 50, 110, 150);
		HBRUSH red = CreateSolidBrush(RGB(0, 0, 0xFF));

		for (int i=0; i<6; i++)
		{
			const TCHAR * Title[] = { "Two Regions", "RGN_AND", "RGN_OR", "RGN_XOR", "RGN_DIFF", "RGN_COPY" };

			SetViewportOrgEx(hDC, 20+i*115, 90, NULL);

			FrameRgn(hDC, hRgn1, red, 1, 1);
			FrameRgn(hDC, hRgn2, red, 1, 1);

			HRGN hRgn = CreateRectRgn(0, 0, 0, 0);

			switch ( i )
			{
				case 1: CombineRgn(hRgn, hRgn1, hRgn2, RGN_AND);  break;
				case 2: CombineRgn(hRgn, hRgn1, hRgn2, RGN_OR);   break;
				case 3: CombineRgn(hRgn, hRgn1, hRgn2, RGN_XOR);  break;
				case 4: CombineRgn(hRgn, hRgn1, hRgn2, RGN_DIFF); break;
				case 5: CombineRgn(hRgn, hRgn1, hRgn2, RGN_COPY);  break;
			}

			KGDIObject brush(hDC, CreateSolidBrush(RGB(0xFF, 0xFF, 0)));

			PaintRgn(hDC, hRgn);
			DeleteObject(hRgn);

			Label(hDC, 0, 160, Title[i]);
		}
	}

	// Test GetRegionData
	{
		HBRUSH brush[2];
		brush[0] = CreateSolidBrush(RGB(0, 0, 0xFF));
		brush[1] = CreateSolidBrush(RGB(0xFF, 0xFF, 0));

		for (int i=0; i<4; i++)
		{
			SetViewportOrgEx(hDC, 20+i*170, 280, NULL);

			HRGN hRgn;
			const TCHAR * desp1[] = { "CreateRectRgn",
				                     "CreateRoundRectRgn",
									 "CreateEllipticRgn",
									 "CreatePolygonRgn"
			};										

			const TCHAR * desp2[] = { "(0, 0, 21, 21)",
				                     "(0, 0, 21, 21, 10, 10)",
									 "(0, 0, 21, 21)",
									 "(0, 0, 21, 0, 10, 21)"
			};										

			switch (i)
			{
				case 0:	hRgn = CreateRectRgn(0, 0, 21, 21); break;
				case 1: hRgn = CreateRoundRectRgn(0, 0, 21, 21, 10, 10); break;
				case 2: hRgn = CreateEllipticRgn(0, 0, 21, 21); break;
				case 3: {
					POINT P[] = { 0, 0, 21, 0, 10, 21 };
					hRgn = CreatePolygonRgn(P, 3, WINDING);
						}
			}

			KRegion region;
			region.GetRegionData(hRgn);
//			DeleteObject(hRgn);

			TCHAR temp[64];

			RECT rect = region.m_pRegion->rdh.rcBound;

			Label(hDC, 0, 148, desp1[i]);
			Label(hDC, 0, 168, desp2[i]);

			wsprintf(temp, "rcBound: [%d, %d, %d, %d]", rect.left, rect.top, rect.right, rect.bottom);
			Label(hDC, 0, 190, temp);

			wsprintf(temp, "nCount : %d", region.m_nRectCount);
			Label(hDC, 0, 210, temp);

			wsprintf(temp, "Size   : %d bytes", region.m_nRegionSize);
			Label(hDC, 0, 230, temp);

			Rectangle(hDC, rect.left * 7, rect.top*7, rect.right*7, rect.bottom*7);

			for (int j=0; j<region.m_nRectCount; j++)
			{
				rect = region.m_pRect[j];

				rect.left   *= 7;
				rect.right  *= 7;
				rect.top    *= 7;
				rect.bottom *= 7;

				FillRect(hDC, & rect, brush[j&1]);
			}

			/////////// Play with ExtCreateRegion
  			if ( region.m_nRectCount>=2 )
			{
  				RECT r = region.m_pRect[0];
  				region.m_pRect[0] = region.m_pRect[region.m_nRectCount-1];
  				region.m_pRect[region.m_nRectCount-1] = r;
			}

//			{
//				long t = region.m_pRect[0].left;
//				region.m_pRect[0].left = region.m_pRect[0].right;
//				region.m_pRect[0].right = t;
//			}

			HRGN hRgn1 = region.CreateRegion(NULL);

			if ( hRgn1 )
				Label(hDC, 0, 250, "OK");
			else
				Label(hDC, 0, 250, "Fail");

			if ( hRgn1 )
			{
				GetRgnBox(hRgn1, & rect);
				wsprintf(temp, "rcBound: [%d, %d, %d, %d]", rect.left, rect.top, rect.right, rect.bottom);
				Label(hDC, 0, 270, temp);

				if ( EqualRgn(hRgn, hRgn1) )
					Label(hDC, 100, 250, "Equal");
				else
					Label(hDC, 100, 250, "Not Equal");

				SetViewportOrgEx(hDC, 20+i*170, 280+300, NULL);

				Rectangle(hDC, rect.left * 7, rect.top*7, rect.right*7, rect.bottom*7);

				region.GetRegionData(hRgn1);

				for (int j=0; j<region.m_nRectCount; j++)
				{
					rect = region.m_pRect[j];

					rect.left   *= 7;
					rect.right  *= 7;
					rect.top    *= 7;
					rect.bottom *= 7;

					FillRect(hDC, & rect, brush[j&1]);
				}

				DeleteObject(hRgn1);
			}

			DeleteObject(hRgn);
		}

		DeleteObject(brush[0]);
		DeleteObject(brush[1]);
	}
/*
	{
		RGNDATA rgn[5];

		RECT rr = { 0, 0, 100, 100 };

		rgn[0].rdh.dwSize   = sizeof(rgn[0].rdh);
		rgn[0].rdh.iType    = RDH_RECTANGLES;
		rgn[0].rdh.nCount   = 2;
		rgn[0].rdh.nRgnSize = 2 * sizeof(RECT);
		rgn[0].rdh.rcBound  = rr;
		memcpy(rgn[0].Buffer, & rr, sizeof(rr));
		memcpy(rgn[0].Buffer+sizeof(rr), & rr, sizeof(rr));

		HRGN hRgn = ExtCreateRegion(NULL, sizeof(rgn), rgn);
	}		
*/
	SetViewportOrgEx(hDC, 0, 0, NULL);
}


void KMyCanvas::TestRegionPaint(HDC hDC)
{
	HBRUSH yellow = CreateSolidBrush(RGB(0, 0, 0xFF));
	HPEN   blue   = CreatePen(PS_SOLID, 3, RGB(0xFF, 0xFF, 0));
	
	SelectObject(hDC, blue);
	SelectObject(hDC, yellow);

//	SetBkMode(hDC, TRANSPARENT);
	SetROP2(hDC, R2_MASKNOTPEN);

	RoundRect(hDC, 50, 50, 130, 150, 40, 40);	Label(hDC, 50, 160, "RoundRect");

	HRGN hRgn = CreateRoundRectRgn(50, 50, 130, 150, 40, 40);

	OffsetRgn(hRgn, 90, 0); PaintRgn(hDC, hRgn);					Label(hDC, 140,  30, "PaintRgn");
	OffsetRgn(hRgn, 90, 0);  FillRgn(hDC, hRgn,  yellow);			Label(hDC, 230, 160, "FillRgn");
	OffsetRgn(hRgn, 90, 0); FrameRgn(hDC, hRgn,  yellow, 1, 1);		Label(hDC, 320,  30, "FrameRgn(1,1)");
	OffsetRgn(hRgn, 90, 0); FrameRgn(hDC, hRgn,  yellow, 1, 10);	Label(hDC, 410, 160, "FrameRgn(1,10)");
	OffsetRgn(hRgn, 90, 0); FrameRgn(hDC, hRgn,  yellow, 10, 1);	Label(hDC, 500,  30, "FrameRgn(10,1)");
	OffsetRgn(hRgn, 90, 0); FrameRgn(hDC, hRgn,  yellow, 10, 10);	Label(hDC, 590, 160, "FrameRgn(10,10)");
	OffsetRgn(hRgn, 90, 0); InvertRgn(hDC, hRgn);					Label(hDC, 680,  30, "InvertRgn");

	DeleteObject(hRgn);
	
	int nSave = SaveDC(hDC);
	SetMapMode(hDC, MM_ANISOTROPIC);
	SetViewportOrgEx(hDC, 200, 200, NULL);
	SetViewportExtEx(hDC, 15, 15, NULL);

	hRgn = CreateRoundRectRgn(0, 0, 20, 20, 10, 10);

	FrameRgn(hDC, hRgn, yellow, 1, 1);
	
	DeleteObject(hRgn);

	RestoreDC(hDC, nSave);

	SelectObject(hDC, GetStockObject(WHITE_BRUSH));
	SelectObject(hDC, GetStockObject(BLACK_PEN));
	DeleteObject(yellow);
	DeleteObject(blue);
//	SetBkMode(hDC, OPAQUE);
	SetROP2(hDC, R2_COPYPEN);
}

class KGradient
{
	COLORREF m_c0;
	COLORREF m_c1;

	TRIVERTEX m_vertex[12];
	ULONG     m_index [12];
	
public:
	
	KGradient(COLORREF c0, COLORREF c1)
	{
		m_c0 = c0;
		m_c1 = c1;
	}

	void Define(int i, int x, int y, int cr);
	BOOL Fill(HDC hDC, int nVertex, int nMesh, DWORD nMode, const POINT * pPoint, const int *pColor);
};

void KGradient::Define(int i, int x, int y, int c)
{
	m_index[i]        = i;
	m_vertex[i].x     = x;
	m_vertex[i].y     = y;
	m_vertex[i].Red   = ( ( GetRValue(m_c0) * c + GetRValue(m_c1) * (2-c) ) / 2 ) << 8;
	m_vertex[i].Green = ( ( GetGValue(m_c0) * c + GetGValue(m_c1) * (2-c) ) / 2 ) << 8;
	m_vertex[i].Blue  = ( ( GetBValue(m_c0) * c + GetBValue(m_c1) * (2-c) ) / 2 ) << 8;
	m_vertex[i].Alpha = 0;
}

BOOL KGradient::Fill(HDC hDC, int nVertex, int nMesh, DWORD nMode, const POINT * pPoint, const int *pColor)
{
	for (int i=0; i<nVertex; i++)
		Define(i, pPoint[i].x, pPoint[i].y, pColor[i]);

	return ::GradientFill(hDC, m_vertex, nVertex, m_index, nMesh, nMode);
}


void KMyCanvas::TestGradientFill(HDC hDC)
{
	const COLORREF c0 = RGB(0x20, 0x20, 0x20);
	const COLORREF c1 = RGB(0xF0, 0xF0, 0x20);

	for (int i=0; i<4; i++)
		GradientRectangle(hDC, 100+110*i, 50, 200+110*i, 150, c0, c1, i*45);

	for (i=0; i<4; i++)
		SymGradientRectangle(hDC, 100+110*i, 160, 200+110*i, 260, c0, c1, i*45);

	for (i=0; i<4; i++)
		CornerGradientRectangle(hDC, 100+110*i, 270, 200+110*i, 370, c0, c1, i);

	CenterGradientRectangle(hDC, 560, 150, 660, 250, c0, c1);
	CenterGradientRectangle(hDC, 560, 260, 660, 360, c1, c0);

	//  Buttons
	SetViewportOrgEx(hDC, 20, 400, NULL);

	RoundRectButton(hDC, 0,   0,  80, 80,  0, 10, RGB(0x20, 0x20, 0x20), RGB(0xF0, 0xF0, 0x20));
	RoundRectButton(hDC, 100, 0, 180, 80, 40, 10, RGB(0xF0, 0x20, 0x20), RGB(0x20, 0xF0, 0x20));
	RoundRectButton(hDC, 200, 0, 280, 80, 80, 10, RGB(0xFF, 0xFF, 0x20), RGB(0x20, 0x20, 0xF0));
	
	   GradientRectangle(hDC, 0, 100, 200, 200, RGB(0xFF, 0x0, 0), RGB(0, 0, 0xFF), 0);
	HLSGradientRectangle(hDC, 0, 220, 200, 320, RGB(0xFF, 0x0, 0), RGB(0, 0, 0xFF), 200);

	RadialGradientFill(hDC, 400, 150, 400   , 150   , 100, RGB(0xFF, 0xFF, 0xFF), RGB(0, 0, 0xFF), 8);
	RadialGradientFill(hDC, 620, 150, 620-30, 150-60, 100, RGB(0xFF, 0xFF, 0xFF), RGB(0, 0, 0xFF), 16);
	RadialGradientFill(hDC, 840, 150, 840-30, 150+30, 100, RGB(0xFF, 0xFF, 0xFF), RGB(0, 0, 0xFF), 256);

	SetViewportOrgEx(hDC, 0, 0, NULL);

	{
		RECT r = { 700, 50, 850, 50+150 };

		KGDIObject blue(hDC, CreatePen(PS_SOLID, 3, RGB(0, 0, 0xFF)));
		KGDIObject yellow(hDC, CreateSolidBrush(RGB(0xFF, 0xFF, 0)));
	
		Rectangle(hDC, 700, 50, 850, 50+150);
		
		BrickPatternFill(hDC, 700, 50, 850, 50+150, 15, 15);
		BrickPatternFill(hDC, 860, 50, 860+150, 50+150, 10, 10);
	}
}

void KMyCanvas::OnDraw(HDC hDC, const RECT * rcPaint)
{
	switch ( m_test )
	{
		case IDM_TEST_DITHER:			TestDither(hDC);			break;
		case IDM_TEST_HATCHBRUSH:		TestHatch(hDC);				break;
		case IDM_TEST_SYSCOLORBRUSH:	TestSysColorBrush(hDC);		break;
		case IDM_TEST_RECTANGLE:		TestRectangle(hDC);			break;
		case IDM_TEST_DRAWFRAMECONTROL: TestDrawFrameControl(hDC);	break;
		case IDM_TEST_ELLIPSE:			TestEllipse(hDC);			break;
		case IDM_TEST_PIECHART:			TestPieChart(hDC);			break;
		case IDM_TEST_POLYFILLMODE:		TestPolyFillMode(hDC);		break;
		case IDM_TEST_FILLPATH:			TestFillPath(hDC);			break;
		case IDM_TEST_REGION:			TestRegion(hDC);			break;
		case IDM_TEST_REGIONOP:			TestRegionOper(hDC);		break;
		case IDM_TEST_REGIONPAINT:		TestRegionPaint(hDC);		break;
		case IDM_TEST_GRADIENTFILL:		TestGradientFill(hDC);		break;
	}
}


class KMyFrame : public KFrame
{
	virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
	{
		if ( uMsg==WM_NCPAINT )
		{
			KFrame::WndProc(hWnd, uMsg, wParam, lParam);

 			HDC hDC = GetDCEx(hWnd, (HRGN) wParam, 0x10000 | DCX_WINDOW|DCX_INTERSECTRGN);
			
			RECT rect;
			GetWindowRect(hWnd, & rect);

			OffsetRect(&rect, - rect.left, - rect.top);

			for (int i=0; i<4; i++)
			{
				FrameRect(hDC, & rect, GetSysColorBrush(COLOR_SCROLLBAR+i));
			
				InflateRect(&rect, -1, -1);
			}
			
			ReleaseDC(hWnd, hDC);

			return 0;
		}
		else
			return KFrame::WndProc(hWnd, uMsg, wParam, lParam);
	}

	void GetWndClassEx(WNDCLASSEX & wc)
	{
		KFrame::GetWndClassEx(wc);

		wc.hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_AREA));
	}

public:
	KMyFrame(HINSTANCE hInstance, const TBBUTTON * pButtons, int nCount,
		KToolbar * pToolbar, KCanvas * pCanvas, KStatusWindow * pStatus) :
		KFrame(hInstance, pButtons, nCount, pToolbar, pCanvas, pStatus)
	{
	}

};

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int nShow)
{
	KMyCanvas     canvas;
	KStatusWindow status;

	KMyFrame frame(hInst, NULL, 0, NULL, & canvas, & status);

	frame.CreateEx(0, _T("AreaDemo"), _T("Areas"),
		WS_OVERLAPPEDWINDOW,
	    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
	    NULL, LoadMenu(hInst, MAKEINTRESOURCE(IDR_MAIN)), hInst);

    frame.ShowWindow(nShow);
    frame.UpdateWindow();

    frame.MessageLoop();

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -