228 lines
6.4 KiB
C++
228 lines
6.4 KiB
C++
// ==========================================================================
|
|
// Class Implementation : COXShape
|
|
// ==========================================================================
|
|
|
|
// Source file : OXShape.cpp
|
|
|
|
// Version: 9.3
|
|
|
|
// This software along with its related components, documentation and files ("The Libraries")
|
|
// is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
|
|
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
|
|
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
|
|
// to obtain this file, or directly from our office. For a copy of the license governing
|
|
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
|
|
|
|
// //////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "oxshape.h"
|
|
|
|
#include <math.h>
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
// Constructor
|
|
COXShape::COXShape()
|
|
{
|
|
}
|
|
|
|
// Destructor
|
|
COXShape::~COXShape()
|
|
{
|
|
}
|
|
|
|
const CArray<CPoint, CPoint>* COXShape::GetShapePoints() const
|
|
{
|
|
return &m_ShapePointsArray;
|
|
}
|
|
|
|
// Private method to get the size of the visible region
|
|
CRect& COXShape::GetShapeRect(LPRECT lpRect)
|
|
{
|
|
static CRect rect;
|
|
|
|
if(lpRect == NULL)
|
|
::GetClientRect(m_hShapeWnd, &rect);
|
|
else
|
|
rect = *lpRect;
|
|
|
|
return rect;
|
|
}
|
|
|
|
// Multi-purpose method to calculate shapes based on line segments.
|
|
// This method is used to generate the various line based shapes
|
|
// in COXShape such as stars, hexagons and triangles. It can easily be
|
|
// extended by experimenting with various combinations fo the point,
|
|
// radius and rotation parameters.
|
|
//
|
|
// (thanks to Michael Hatton for this method)
|
|
void COXShape::CalcLines(RECT& rect, double dbNumberOfPoints,
|
|
double dbInnerRadius, double dbRotation)
|
|
{
|
|
#define PI 3.14159
|
|
|
|
short x = 0;
|
|
short y = 0;
|
|
|
|
// Declare line segment work area
|
|
POINT aptKey[MAX_SHAPELINES];
|
|
|
|
// Normalize the rotation factor
|
|
dbRotation += 1.5f;
|
|
|
|
// Initialize work variables
|
|
int xCenter = rect.right / 2;
|
|
int yCenter = rect.bottom / 2;
|
|
double dbRadius = xCenter;
|
|
double dbRadians = PI / dbNumberOfPoints;
|
|
|
|
// Iterate through each inner and outer points of the shape
|
|
for(int nSide = 0; nSide < (int)(2.0f * dbNumberOfPoints); nSide++ )
|
|
{
|
|
// Calculate the horizontal (x) and vertical (y) location
|
|
x = (short)(cos(nSide * dbRadians + dbRotation) * dbRadius);
|
|
y = (short)(sin(nSide * dbRadians + dbRotation) * dbRadius);
|
|
|
|
// If this is an inner point then base it off of the inner radius
|
|
if(nSide % 2)
|
|
{
|
|
x = (short) (x / dbInnerRadius);
|
|
y = (short) (y / dbInnerRadius);
|
|
}
|
|
|
|
// Save the point information
|
|
aptKey[nSide].x = xCenter + x;
|
|
aptKey[nSide].y = yCenter - y;
|
|
}
|
|
|
|
// Finished calculating the shape, lets set the visible region to it
|
|
SetPolyShape(aptKey, (int)(2.0f * dbNumberOfPoints));
|
|
}
|
|
|
|
// Sets the visible region a polygon
|
|
void COXShape::SetPolyShape(LPPOINT lpPoints, int nPoints)
|
|
{
|
|
// Do a quick sanity check
|
|
m_hShapeWnd = GetHWND();
|
|
ASSERT(m_hShapeWnd != NULL);
|
|
ASSERT(lpPoints != NULL);
|
|
ASSERT(nPoints != 0);
|
|
ASSERT(AfxIsValidAddress(lpPoints, nPoints * sizeof(POINT), FALSE));
|
|
|
|
// Create a polygon region
|
|
SetWindowRgn(m_hShapeWnd, NULL, FALSE);
|
|
m_rgnWnd.DeleteObject();
|
|
m_rgnWnd.CreatePolygonRgn(lpPoints, nPoints, ALTERNATE);
|
|
|
|
// copy the points of the region to the points array
|
|
m_ShapePointsArray.RemoveAll();
|
|
m_ShapePointsArray.SetSize(nPoints);
|
|
for (int i = 0; i < nPoints; i++)
|
|
m_ShapePointsArray.SetAt(i, CPoint(lpPoints[i]));
|
|
|
|
// Set the window's visible region to match it, then repaint it
|
|
SetWindowRgn(m_hShapeWnd, m_rgnWnd, TRUE);
|
|
}
|
|
|
|
// Sets the visible region to a rounded rectangle
|
|
void COXShape::SetRoundRectShape(LPRECT lpRect, LPPOINT lpptCorners)
|
|
{
|
|
// Do a quick sanity check
|
|
m_hShapeWnd = GetHWND();
|
|
ASSERT(m_hShapeWnd != NULL);
|
|
|
|
// Get the shape's rectangle
|
|
CRect rect = GetShapeRect(lpRect);
|
|
|
|
// If NULL was passed for the rounded corner size then just use 0
|
|
// this will make a normal rectangle
|
|
POINT ptCorners;
|
|
if(lpptCorners == NULL)
|
|
ptCorners.x = ptCorners.y = 0;
|
|
else ptCorners = *lpptCorners;
|
|
|
|
// Create a rounded rectangle region
|
|
SetWindowRgn(m_hShapeWnd, NULL, FALSE);
|
|
m_rgnWnd.DeleteObject();
|
|
m_rgnWnd.CreateRoundRectRgn(rect.left, rect.top, rect.right, rect.bottom,
|
|
ptCorners.x,ptCorners.y);
|
|
|
|
// Set the window's visible region to match it, the repaint it
|
|
SetWindowRgn(m_hShapeWnd, m_rgnWnd, TRUE);
|
|
}
|
|
|
|
// Sets the visible region to an ellipse
|
|
void COXShape::SetEllipseShape(LPRECT lpRect)
|
|
{
|
|
// Do a quick sanity check
|
|
m_hShapeWnd = GetHWND();
|
|
ASSERT(m_hShapeWnd != NULL);
|
|
|
|
CRect rect = GetShapeRect(lpRect);
|
|
|
|
// Create a rounded rectangle region
|
|
SetWindowRgn(m_hShapeWnd, NULL, FALSE);
|
|
m_rgnWnd.DeleteObject();
|
|
m_rgnWnd.CreateEllipticRgn(rect.left, rect.top, rect.right, rect.bottom);
|
|
|
|
// Set the window's visible region to match it, the repaint it
|
|
SetWindowRgn(m_hShapeWnd, m_rgnWnd, TRUE);
|
|
}
|
|
|
|
// Sets the visible region to a star -- the number of points, depth
|
|
// of each point and rotation can be specified in floating point
|
|
// numbers
|
|
void COXShape::SetStarShape(LPRECT lpRect, double dbNumberOfPoints,
|
|
double dbInnerRadius, double dbRotation)
|
|
{
|
|
m_hShapeWnd = GetHWND();
|
|
ASSERT(m_hShapeWnd != NULL);
|
|
|
|
// Get the shape's rectangle
|
|
CRect rect = GetShapeRect(lpRect);
|
|
|
|
CalcLines(rect, dbNumberOfPoints, dbInnerRadius, dbRotation);
|
|
}
|
|
|
|
// Sets the visible region to a pentagon -- the rotation can be specified
|
|
void COXShape::SetPentagonShape(LPRECT lpRect, double dbRotation)
|
|
{
|
|
m_hShapeWnd = GetHWND();
|
|
ASSERT(m_hShapeWnd != NULL);
|
|
|
|
// Get the shape's rectangle
|
|
CRect rect = GetShapeRect(lpRect);
|
|
|
|
CalcLines(rect, 2.5f, 1.0f, dbRotation);
|
|
}
|
|
|
|
// Sets the visible region to a hexagon -- the rotation can be specified
|
|
void COXShape::SetHexagonShape(LPRECT lpRect, double dbRotation)
|
|
{
|
|
m_hShapeWnd = GetHWND();
|
|
ASSERT(m_hShapeWnd != NULL);
|
|
|
|
// Get the shape's rectangle
|
|
CRect rect = GetShapeRect(lpRect);
|
|
|
|
CalcLines(rect, 4.0f, 1.0f, dbRotation);
|
|
}
|
|
|
|
// Sets the visible region to a triangle - the rotation can be specified
|
|
void COXShape::SetTriangleShape(LPRECT lpRect, double dbRotation)
|
|
{
|
|
m_hShapeWnd = GetHWND();
|
|
ASSERT(m_hShapeWnd != NULL);
|
|
|
|
// Get the shape's rectangle
|
|
CRect rect = GetShapeRect(lpRect);
|
|
|
|
CalcLines(rect, 1.5f, 1.0f, dbRotation);
|
|
}
|
|
|