Transformation


Introduction

This example is adapted from an example from the MSDN documentation.

The form and its menu:

 

The header file:

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
    TMainMenu *MainMenu1;
    TMenuItem *File1;
    TMenuItem *Exit1;
    TMenuItem *Transform1;
    TMenuItem *Scale1;
    TMenuItem *Translate1;
    TMenuItem *Rotate1;
    TMenuItem *Shear1;
    TMenuItem *Reflect1;
    TMenuItem *Normal1;
    void __fastcall Exit1Click(TObject *Sender);
    void __fastcall Scale1Click(TObject *Sender);
    void __fastcall Translate1Click(TObject *Sender);
    void __fastcall Rotate1Click(TObject *Sender);
    void __fastcall Shear1Click(TObject *Sender);
    void __fastcall Reflect1Click(TObject *Sender);
    void __fastcall Normal1Click(TObject *Sender);
private:
    HWND hWnd;	// User declarations
public:		// User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

 

 

The source file

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
enum Trans { SCALE = 0, TRANSLATE, ROTATE, SHEAR, REFLECT, NORMAL };
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{        
    hWnd = this->Handle;
}
//---------------------------------------------------------------------------
void TransformAndDraw(int iTransform, HWND hWnd)
{
    HDC hDC;
    XFORM xForm;
    RECT rect;

    // Retrieve a DC handle for the application's window.

    hDC = GetDC(hWnd);
 
    // Set the mapping mode to LOENGLISH. This moves the 
    // client area origin from the upper left corner of the 
    // window to the lower left corner (this also reorients 
    // the y-axis so that drawing operations occur in a true 
    // Cartesian space). It guarantees portability so that 
    // the object drawn retains its dimensions on any display. 

    SetGraphicsMode(hDC, GM_ADVANCED);
    SetMapMode(hDC, MM_LOENGLISH); 
 
    // Set the appropriate world transformation (based on the 
    // user's menu selection). 
 
    switch (iTransform) 
    { 
        case SCALE:        // Scale to 1/2 of the original size.
            xForm.eM11 = (FLOAT) 0.5; 
            xForm.eM12 = (FLOAT) 0.0; 
            xForm.eM21 = (FLOAT) 0.0; 
            xForm.eM22 = (FLOAT) 0.5; 
            xForm.eDx  = (FLOAT) 0.0; 
            xForm.eDy  = (FLOAT) 0.0; 
            SetWorldTransform(hDC, &xForm); 
            break; 
 
        case TRANSLATE:   // Translate right by 3/4 inch. 
            xForm.eM11 = (FLOAT) 1.0; 
            xForm.eM12 = (FLOAT) 0.0; 
            xForm.eM21 = (FLOAT) 0.0; 
            xForm.eM22 = (FLOAT) 1.0; 
            xForm.eDx  = (FLOAT) 75.0; 
            xForm.eDy  = (FLOAT) 0.0; 
            SetWorldTransform(hDC, &xForm); 
            break; 
 
        case ROTATE:      // Rotate 30 degrees counterclockwise. 
            xForm.eM11 = (FLOAT) 0.8660; 
            xForm.eM12 = (FLOAT) 0.5000; 
            xForm.eM21 = (FLOAT) -0.5000; 
            xForm.eM22 = (FLOAT) 0.8660; 
            xForm.eDx  = (FLOAT) 0.0; 
            xForm.eDy  = (FLOAT) 0.0; 
            SetWorldTransform(hDC, &xForm); 
            break; 
 
        case SHEAR:       // Shear along the x-axis with a 
                          // proportionality constant of 1.0. 
            xForm.eM11 = (FLOAT) 1.0; 
            xForm.eM12 = (FLOAT) 1.0; 
            xForm.eM21 = (FLOAT) 0.0; 
            xForm.eM22 = (FLOAT) 1.0; 
            xForm.eDx  = (FLOAT) 0.0; 
            xForm.eDy  = (FLOAT) 0.0; 
            SetWorldTransform(hDC, &xForm); 
            break; 
 
        case REFLECT:     // Reflect about a horizontal axis. 
            xForm.eM11 = (FLOAT) 1.0; 
            xForm.eM12 = (FLOAT) 0.0; 
            xForm.eM21 = (FLOAT) 0.0; 
            xForm.eM22 = (FLOAT) -1.0; 
            xForm.eDx  = (FLOAT) 0.0; 
            xForm.eDy  = (FLOAT) 0.0; 
            SetWorldTransform(hDC, &xForm); 
            break; 
 
        case NORMAL:      // Set the unity transformation. 
            xForm.eM11 = (FLOAT) 1.0; 
            xForm.eM12 = (FLOAT) 0.0; 
            xForm.eM21 = (FLOAT) 0.0; 
            xForm.eM22 = (FLOAT) 1.0; 
            xForm.eDx  = (FLOAT) 0.0; 
            xForm.eDy  = (FLOAT) 0.0; 
            SetWorldTransform(hDC, &xForm); 
            break; 
 
    } 
 
    // Find the midpoint of the client area. 
 
    GetClientRect(hWnd, (LPRECT) &rect);
    DPtoLP(hDC, (LPPOINT) &rect, 2); 
 
    // Select a hollow brush. 
 
    SelectObject(hDC, GetStockObject(HOLLOW_BRUSH)); 
 
    // Draw the exterior circle. 
 
    Ellipse(hDC, (rect.right / 2 - 100), (rect.bottom / 2 + 100), 
        (rect.right / 2 + 100), (rect.bottom / 2 - 100)); 
 
    // Draw the interior circle. 
 
    Ellipse(hDC, (rect.right / 2 -94), (rect.bottom / 2 + 94), 
        (rect.right / 2 + 94), (rect.bottom / 2 - 94)); 
 
    // Draw the key. 
 
    Rectangle(hDC, (rect.right / 2 - 13), (rect.bottom / 2 + 113), 
        (rect.right / 2 + 13), (rect.bottom / 2 + 50)); 
    Rectangle(hDC, (rect.right / 2 - 13), (rect.bottom / 2 + 96), 
        (rect.right / 2 + 13), (rect.bottom / 2 + 50)); 
 
    // Draw the horizontal lines. 
 
    MoveToEx(hDC, (rect.right/2 - 150), (rect.bottom / 2 + 0), NULL); 
    LineTo(hDC, (rect.right / 2 - 16), (rect.bottom / 2 + 0)); 
 
    MoveToEx(hDC, (rect.right / 2 - 13), (rect.bottom / 2 + 0), NULL); 
    LineTo(hDC, (rect.right / 2 + 13), (rect.bottom / 2 + 0)); 
 
    MoveToEx(hDC, (rect.right / 2 + 16), (rect.bottom / 2 + 0), NULL); 
    LineTo(hDC, (rect.right / 2 + 150), (rect.bottom / 2 + 0)); 
 
    // Draw the vertical lines. 
 
    MoveToEx(hDC, (rect.right/2 + 0), (rect.bottom / 2 - 150), NULL); 
    LineTo(hDC, (rect.right / 2 + 0), (rect.bottom / 2 - 16)); 
 
    MoveToEx(hDC, (rect.right / 2 + 0), (rect.bottom / 2 - 13), NULL); 
    LineTo(hDC, (rect.right / 2 + 0), (rect.bottom / 2 + 13)); 
 
    MoveToEx(hDC, (rect.right / 2 + 0), (rect.bottom / 2 + 16), NULL); 
    LineTo(hDC, (rect.right / 2 + 0), (rect.bottom / 2 + 150)); 
 
    ReleaseDC(hWnd, hDC); 
} 
//---------------------------------------------------------------------------
void __fastcall TForm1::Exit1Click(TObject *Sender)
{
    Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Scale1Click(TObject *Sender)
{
    Canvas->Rectangle(0, 0, Width, Height);
    TransformAndDraw(SCALE, hWnd);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Translate1Click(TObject *Sender)
{                           
    Canvas->Rectangle(0, 0, Width, Height);
    TransformAndDraw(TRANSLATE, hWnd);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Rotate1Click(TObject *Sender)
{                               
    Canvas->Rectangle(0, 0, Width, Height);
    TransformAndDraw(ROTATE, hWnd);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Shear1Click(TObject *Sender)
{                             
    Canvas->Rectangle(0, 0, Width, Height);
    TransformAndDraw(SHEAR, hWnd);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Reflect1Click(TObject *Sender)
{                              
    Canvas->Rectangle(0, 0, Width, Height);
    TransformAndDraw(REFLECT, hWnd);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Normal1Click(TObject *Sender)
{
    Canvas->Rectangle(0, 0, Width, Height);
    TransformAndDraw(NORMAL, hWnd);
}
//---------------------------------------------------------------------------

Copyright 2003 FunctionX, Inc.