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

📄 paint.cpp

📁 WIndows mobile 5.0 pocket pc sdk sample for win32
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/******************************************************************************\
*
*  MODULE:      PAINT.C
*
*  PURPOSE:     This is the module responsible for painting the SPINCUBE
*               custom control. When Paint() is called we retrieve a
*               pointer to a SPINCUBEINFO structure, and then use it's
*               current rotation & translation values to transform the
*               polyhedron described by gNormalizedVertices & gaiFacets.
*               Once we've transformed the vertices, we draw the
*               background, which consists of a grey rectangle and a few
*               black lines (a crass attempt to render a perspective
*               view into a "room"), on the offscreen bitmap associated
*               with the control (i.e. pSCI->hbmCompat). Then we walk the
*               facet list of the transformed polyhedron (gXformedVertices
*               & gaiFacets), drawing only those facets whose outward
*               normal faces us (again, drawing on pSCI->hbmCompat).
*               Finally, we BitBlt the appropriate rectangle from our
*               offscreen bitmap to the screen itself.
*
*               Drawing to the offscreen bitmap has two advantages over
*               drawing straight to the screen:
*
*                 1. The actual drawing the user sees consists of only
*                    a single BitBlt. Otherwise, the user would see us
*                    both erase the polyhedron in it's old position and
*                    draw it in it's new position (alot of flashing- not
*                    very smooth animation).
*
*                 2. When a spincube control with the SS_ERASE style
*                    is brought to the foreground, all it's contents
*                    i.e. the cube trails) are saved & can be re-Blted
*                    to the screen. Otherwise, all this info would be
*                    lost & there'd be a big blank spot in the middle
*                    of the control!
*
*               Interested persons should consult a text on 3 dimensional
*               graphics for more information (i.e. "Computer Graphics:
*               Principles and Practice", by Foley & van Dam).
*
*               Notes:
*
*               - A 3x2 tranformation matrix  is used instead of a  3x3
*                 matrix, since the transformed z-values aren't needed.
*                 (Normally these would be required for use in depth
*                 sorting  [for hidden surface removal], but  since we
*                 draw  only  a single convex polyhedron this  is not
*                 necessary.)
*
*               - A simplified perspective viewing transformation
*                 (which also  precludes the need for the transformed z
*                 coordinates). In a nutshell, the perspective  scale
*                 is as follows:
*
*                                    p' = S    x  p
*                                          per
*
*                 where:
*                        S    = WindowDepth /
*                         per      (WindowDepth + fCurrentZTranslation)
*
*                 (WindowDepth is  the greater of the  control's window
*                 height or window width.)
*
*
*  FUNCTIONS:   Paint()                         - the paint routine
*               TransformVertices()             - transforms vertices
*               ComputeRotationTransformation() - computes xformation
*                                                 based on current x, y
*                                                 and z rotation angles
*
*                           Microsoft Developer Support
*
\******************************************************************************/

#include <windows.h>
#include <math.h>
#include <stdlib.h>
#include "spincube.h"
#include "paint.h"



/******************************************************************************\
*
*  FUNCTION:     Paint
*
*  INPUTS:       hwnd - Handle of the window to draw into.
*
*  COMMENTS:     Draws window background & a polyhedron in the window.
*
\******************************************************************************/

void Paint(
	HWND hwnd
	)
{
	PSPINCUBEINFO  pSCI;
	RECT           rect;
	int            i;
	LONG           lScaleFactor;
	PAINTSTRUCT    ps;
	HRGN           hrgnClip;
	HBRUSH         hBrush, hBrushSave;
	int            iX, iY, iCX, iCY;
	int            facetIndex, numPoints;
	POINT          polygn[MAX_POINTS_PER_FACET];
	POINT          vector1, vector2;
	COLORREF       acrColor[6] = { 0x808080, 0xC0C0C0, 0xffffff,
		0xffffff, 0x000000, 0x000000 };
	POINT       points[5];
	
	pSCI = (PSPINCUBEINFO) GetWindowLong(hwnd, GWL_SPINCUBEDATA);
	BeginPaint(hwnd, &ps);
	if (memcmp((void *)&ps.rcPaint, (void *)&pSCI->rcCubeBoundary, sizeof(RECT))
		& !REPAINT_BKGND(pSCI))
	{
		//
		// We're not here because it's time to animate (i.e. this paint isn't
		//   the result of a WM_TIMER), so just do the Blt & blow out of here...
		//
		
		BitBlt(ps.hdc,
			ps.rcPaint.left,
			ps.rcPaint.top,
			ps.rcPaint.right - ps.rcPaint.left,
			ps.rcPaint.bottom - ps.rcPaint.top,
			pSCI->hdcCompat, ps.rcPaint.left,
			ps.rcPaint.top, SRCCOPY);
		
		EndPaint(hwnd, &ps);
		return;
	}
	
	
	//
	// The rectangle we get back is in Desktop coordinates, so we need to
	//   modify it to reflect coordinates relative to this window.
	//
	
	GetWindowRect(hwnd, &rect);
	
	rect.right  -= rect.left;
	rect.bottom -= rect.top;
	rect.left = rect.top = 0;
	
	
	//
	// Determine a "best fit" scale factor for our polyhedron
	//
	
	if (!(lScaleFactor = rect.right > rect.bottom ?
		rect.bottom/12 : rect.right/12))
	{
		lScaleFactor = 1;
	}
	
	
	TransformVertices(hwnd, &rect, pSCI, lScaleFactor);
	
	
	//
	// Draw the window frame & background
	//
	// Note: The chances are that we are coming through here because we
	//   got a WM_TIMER message & it's time to redraw the cube to simulate
	//   animation. In that case all we want to erase/redraw is that small
	//   rectangle which bounded the polyhedron the last time. The less
	//   drawing that actually gets done the better, since we wnat to
	//   minimize the flicker on the screen. __BeginPaint__ is perfect for
	//   this because it causes all drawing outside of the invalid region
	//   to be "clipped" (no drawing is performed outside of the invalid
	//   region), and it also validates the invalid region.
	//
	
	if (DO_ERASE(hwnd) || REPAINT_BKGND(pSCI))
	{
		hrgnClip = CreateRectRgnIndirect(&ps.rcPaint);
		SelectClipRgn(pSCI->hdcCompat, hrgnClip);
		DeleteObject(hrgnClip);
		
		SelectObject(pSCI->hdcCompat, GetStockObject (GRAY_BRUSH));
		Rectangle(pSCI->hdcCompat, (int)rect.left, (int)rect.top,
			(int)rect.right, (int)rect.bottom);
		
		iX = (rect.right  - rect.left) / 4;
		iY = (rect.bottom - rect.top ) / 4;
		
		// Windows CE v1.0 does not support MoveToEx or LineTo, so I've included
		// the original code in comments right above code I've written
		// to duplicate the original functionality.
		
		// all of this is used to just draw the background lines in the boxes
		// (over the black rectangles).
		
		// MoveToEx (pSCI->hdcCompat, (int)rect.left, (int)rect.top, NULL);
		points[0].x = (int)rect.left;
		points[0].y = (int)rect.top;
		
		// LineTo   (pSCI->hdcCompat, (int)rect.left + iX, (int)rect.top + iY);
		points[1].x = (int)rect.left + iX;
		points[1].y = (int)rect.top + iY;
		
		// LineTo   (pSCI->hdcCompat, (int)rect.left + iX, (int)rect.bottom - iY);
		points[2].x = (int)rect.left + iX;
		points[2].y = (int)rect.bottom - iY;
		
		// LineTo   (pSCI->hdcCompat, (int)rect.left,      (int)rect.bottom);
		points[3].x = (int)rect.left;
		points[3].y = (int)rect.bottom;
		
		Polyline( pSCI->hdcCompat, points, 4 );
		
		
		// MoveToEx (pSCI->hdcCompat, (int)rect.right, (int)rect.top, NULL);
		points[0].x = (int)rect.right;
		points[0].y = (int) rect.top;
		
		// LineTo   (pSCI->hdcCompat, (int)rect.right - iX, (int)rect.top + iY);
		points[1].x = (int)rect.right - iX;
		points[1].y = (int)rect.top + iY;
		
		// LineTo   (pSCI->hdcCompat, (int)rect.right - iX, (int)rect.bottom- iY);
		points[2].x = (int)rect.right - iX;
		points[2].y = (int)rect.bottom- iY;
		
		// LineTo   (pSCI->hdcCompat, (int)rect.right,      (int)rect.bottom);
		points[3].x = (int)rect.right;
		points[3].y = (int)rect.bottom;
		
		Polyline( pSCI->hdcCompat, points, 4 );
		
		// MoveToEx (pSCI->hdcCompat, (int)rect.left + iX,  (int)rect.top + iY, NULL);
		points[0].x = (int)rect.left + iX;
		points[0].y = (int)rect.top + iY, NULL;
		
		// LineTo   (pSCI->hdcCompat, (int)rect.right - iX, (int)rect.top + iY);
		points[1].x = (int)rect.right - iX;
		points[1].y = (int)rect.top + iY;
		
		Polyline( pSCI->hdcCompat, points, 2 );
		
		// MoveToEx (pSCI->hdcCompat, (int)rect.left + iX,  (int)rect.bottom - iY, NULL);
		points[0].x = (int)rect.left + iX;
		points[0].y = (int)rect.bottom - iY, NULL;
		
		// LineTo   (pSCI->hdcCompat, (int)rect.right - iX, (int)rect.bottom - iY);
		points[1].x = (int)rect.right - iX;
		points[1].y = (int)rect.bottom - iY;
		
		Polyline(pSCI->hdcCompat, points, 2);
		
		SelectClipRgn(pSCI->hdcCompat, NULL);
		
		pSCI->iOptions &= ~SPINCUBE_REPAINT_BKGND;
	}
	
	
	//
	// Draw the polyhedron. We'll walk through the facets list and compute
	//   the normal for each facet- if the normal has z > 0, then the facet
	//   faces us and we'll draw it. Note that this algorithim is ONLY valid
	//   for scenes with a single, convex polyhedron.
	//
	// Note: Use GetDC here because the above call to BeginPaint will
	//   probably not give us a DC with access to as much real estate as
	//   we'd like (we wouldn't be able to draw outside of the invalid
	//   region). We can party on the entire control window with the DC
	//   returned by GetDC.
	//
	
	for (i = 0, facetIndex = 0; i < NUMFACETS; i++)
	{
		vector1.x = gXformedVertices[gaiFacets[facetIndex + 1]].x -
			gXformedVertices[gaiFacets[facetIndex]].x;
		vector1.y = gXformedVertices[gaiFacets[facetIndex + 1]].y -
			gXformedVertices[gaiFacets[facetIndex]].y;
		vector2.x = gXformedVertices[gaiFacets[facetIndex + 2]].x -
			gXformedVertices[gaiFacets[facetIndex + 1]].x;
		vector2.y = gXformedVertices[gaiFacets[facetIndex + 2]].y -
			gXformedVertices[gaiFacets[facetIndex + 1]].y;
		
		for (numPoints = 0; gaiFacets[facetIndex] != -1; numPoints++, facetIndex++)
		{
			polygn[numPoints].x = gXformedVertices[gaiFacets[facetIndex]].x;
			polygn[numPoints].y = gXformedVertices[gaiFacets[facetIndex]].y;
		}
		
		facetIndex++; /* skip over the -1's in the facets list */
		if ((vector1.x*vector2.y - vector1.y*vector2.x) > 0)
		{
			hBrush = CreateSolidBrush(acrColor[i]);
			hBrushSave = (HBRUSH) SelectObject(pSCI->hdcCompat, hBrush);
			
			Polygon(pSCI->hdcCompat, &polygn[0], numPoints);
			
			SelectObject(pSCI->hdcCompat, hBrushSave);
			DeleteObject(hBrush);
		}
	}

⌨️ 快捷键说明

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