2025-11-28 00:35:46 +09:00

145 lines
4.4 KiB
C++

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This class handles manipulation of drawing object (rectangle) as a reaction
// to multi touch gestures
//
// Initially, we define rectangle to be in the center of the client area. So whenever
// user resize window the rectangle is placed in the middle of client window with
// a width set to half of width of client window and height set to half of the heights of
// client window. Rectangle is placed in the center of the client area.
//
// By using the fingers the user can zoom in, zoom out, move or rotate the rectangle.
//
#include "CDrawingObject.h"
// Default constructor
CDrawingObject::CDrawingObject()
{
// main window application is responsible to invoke ResetObject function to initialize variables.
// It shoudl be done whenever main window gets WM_SIZE message.
}
// Destructor
CDrawingObject::~CDrawingObject()
{
}
// This function resets rectangle object information and it's called by main app
// whenever a user resizes client area
// in:
// cxClient - new width of client window
// cyClient - new heights size of client window
void CDrawingObject::ResetObject(const int cxClient, const int cyClient)
{
// Initial positon of center point is the middle point of client window
_ptCenter.x = cxClient/2;
_ptCenter.y = cyClient/2;
// Initial width and height are half a size of client window
_szRect.cx = cxClient/2;
_szRect.cy = cyClient/2;
// Initial scaling factor is 1.0 (no scaling)
_dScalingFactor = 1.0;
// Initial rotation angle is 0.0 (no rotation)
_dRotationAngle = 0.0;
}
// This function will be called by the main app whenever WM_PAINT message is
// received. It is responsible to redraw the rectangle. Here we calculate the
// positon of the rectangle corners.
// in:
// hdc - handle to device context
void CDrawingObject::Paint(HDC hdc)
{
// create new blue pen with a width 1
HPEN hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
// select new pen for drawing
HGDIOBJ hPenOld = SelectObject(hdc, hPen);
// first create a polyline that describes the rectangle scaled by the
// scaling factor
POINT ptRect[5];
// upper left cofner
ptRect[0].x = -(LONG)(_dScalingFactor * _szRect.cx/2);
ptRect[0].y = -(LONG)(_dScalingFactor * _szRect.cy/2);
// upper right corner
ptRect[1].x = -ptRect[0].x;
ptRect[1].y = ptRect[0].y;
// lower right corner
ptRect[2].x = ptRect[1].x;
ptRect[2].y = -ptRect[0].y;
// lower left corner
ptRect[3].x = ptRect[0].x;
ptRect[3].y = ptRect[2].y;
// upper left corner, we are closing the rectangle
ptRect[4] = ptRect[0];
// now we should rotate and translate the rectangle
double dCos = cos(_dRotationAngle);
double dSin = sin(_dRotationAngle);
for (int i = 0; i < 5; i++)
{
LONG lDX = ptRect[i].x;
LONG lDY = ptRect[i].y;
// rotation
ptRect[i].x = (LONG)(lDX*dCos + lDY*dSin);
ptRect[i].y = (LONG)(lDY*dCos - lDX*dSin);
// translation
ptRect[i].x += _ptCenter.x;
ptRect[i].y += _ptCenter.y;
}
Polyline(hdc, ptRect,5);
// draw diagonals
MoveToEx(hdc, ptRect[0].x, ptRect[0].y, NULL);
LineTo(hdc, ptRect[2].x, ptRect[2].y);
MoveToEx(hdc, ptRect[1].x, ptRect[1].y, NULL);
LineTo(hdc, ptRect[3].x, ptRect[3].y);
// select old pen
SelectObject(hdc, hPenOld);
// destroy new pen
DeleteObject(hPen);
}
// This function is responsible for manipulation of the rectangle.
// It is called from CManipulationEventSink class.
// in:
// translationDeltaX - shift of the x-coordinate (1/100 of pixel units)
// translationDeltaY - shift of the y-coordinate (1/100 of pixel units)
// scaleDelta - scale factor (zoom in/out)
// rotationDelta - rotation angle in radians
void CDrawingObject::ApplyManipulationDelta(
const FLOAT translationDeltaX,
const FLOAT translationDeltaY,
const FLOAT scaleDelta,
const FLOAT rotationDelta)
{
_ptCenter.x += (LONG) (translationDeltaX / 100.0);
_ptCenter.y += (LONG) (translationDeltaY / 100.0);
_dScalingFactor *= scaleDelta;
_dRotationAngle -= rotationDelta; // we are substracting because Y-axis is down
}