You are on page 1of 136

Win32 API System Programming

GDI & GDI+

Computer Vision & Pattern Recognition Lab


5

Contents
GDI

Device Context

GDI+

GDI
GDI ( Graphic Device Interface )

Window OS

( GDI + Graphic Device Driver )

GDI : Gdi.exe , Gdi32.dll

Application

GDI

Virtual
Device
Driver

Graphic
Hardware

GDI Object

Pen, Brush , Bitmap , Region, Font , Palette

GDI Object

Device Context GDI Object DeleteObject

GDI
GDI

Device Context

Text

Mapping mode

DC( Device Context )

GDI

GDI Parameter .

: + +

Device Context
DC

Simple Method
CDC * pDC = GetDC();
// Drawing
ReleaseDC( pDC );

OnPaint Handler

PAINTSTRUCT ps;
CDC * pDC = BeginPaint( &ps );
//Drawing
EndPaint( &ps );

Device Context Class


Motive

DC

DC

PAINTSTRUCT ps;
CDC * pDC = BeginPaint( &ps );
//Drawing
EndPaint ???

Device Context Class


CDC

CPaintDC

OnPaint

CWnd::BeginPaint() ~ CWnd::EndPaint();

BeginPaint() EndPaint() ????

CPaintDC::m_ps PAINTSTRUCT rcPaint

Device Context Class


CDC

CWindowDC
CWindowDC dc(this) : ( Client Area + Frame )
CWindowDC dc(NULL) : Screen Area
CWnd::GetWindowDC() ~ CWnd::ReleaseDC();

NonClient Area
CWindowDC WM_NCPAINT

CClientDC
CClientDC dc(this) : Client Area
CClientDC dc(NULL) : Screen Area
CWnd::GetClientDC() ~ CWnd::ReleaseDC();

CMetaFileDC

Construct : Create() ~ Destructor : DeleteMetaFile()

Drawing Function
CDC Draw Function
Function

Description

LineTo

Current Position .

Rectangle

RoundRect

Ellipse

Pie

Polygon

PolyBezier

DC Property

Black

CDC::SetTextColor

CDC::GetTextColor

White

CDC::SetBkColor

CDC::GetBkColor

OPAQUE

CDC::SetBkMode

CDC::GetBkMode

MM_TEXT

CDC::SetMapMode

CDC::GetMapMode

R2_COPYPEN

CDC::SetROP2

CDC::GetROP2

(0,0)

CDC::MoveTo

CDC::GetCurrentPosition

BLACK_PEN

CDC::SelectObject

CDC::SelectObject

WHITE_BRUSH

CDC::SelectObject

CDC::SelectObject

SYSTEM_FONT

CDC::SelectObject

CDC::SelectObject

CDC::SelectStockObject

10

Mapping Mode
Logical Coordinate

MoveTo , LineTo :

Device Context

CDC::SetWindowOrg

Device Coordinate

GDI : ,
(Device Coordinate)

: Device Context Display (0,0)

CDC::SetViewPortOrg

(0,0)

11

Mapping Mode
CDC::SetViewPortOrg

Logical Coordinate (0,0) => Mapping to Device Coordinate(x,y)

(0,0)
(0,0) Logical Coordinate Origin
(x,y) Device Unit

(x,y) Device Unit

CDC::SetWindowOrg

Logical coordinate(x,y) => Mapping to Device Coordinate(0,0)

(0,0)

(0,0)
(x,y) Logical coordinate
(x,y) Logical coordinate

12

Mapping Mode
CDC::SetMapMode

13

GDI+
GDI+

For Window XP Graphic Device Interface

GDI+ API provide C++ Class for GDI+

GDI+

2D Vector Graphics

Image processing

Typography

14

GDI+
GDI+

2D Vector Graphics

Drawing Primitives

Drawing Primitives Class

Rect , Point , Pen , Brush , Graphics

Image processing

Vector Image Processing

Image ( CachedBitmap )

Typography

, , TEXT

Font Antialiasing

15

GDI+
GDI+

Gradient Brushes

Cardinal Splines

Independent Path Objects

Transformations and the Matrix Object

Scalable Regions

Alpha Blending

Antialiasing

Support for Multiple Image Formats

Etc..

16

GDI+
Gradient Brushes

Brush : , (Path) , (Region)

Linear gradient brush

Path gradient brush

17

GDI+
Cardinal Splines

GDI Cardinal Spline

Independent Path Objects ( Path Objects Durability )

GDI

DC Path

GDI+

Graphics Path

Path .

18

GDI+
Transformation & Matrix Object

Matrix Object

Transformation (Translate , Rotate, etc)

Matrix Object Transform .


GraphicsPath Transform .

Region + Matrix Object

19

GDI+
Scalable Region

GDI

Device Coordinate

Translation

GDI+

World coordinate ( )

Scaling , Translation , Rotation

20

GDI+
Alpha Blending

Transparency

Antialiasing

21

GDI+
Recoloring

Image Color Adjusting Process

changing one color to another

adjusting a color's intensity relative to another color

adjusting the brightness or contrast of all colors

converting colors to shades of gray

22

GDI+
Graphics Container

Graphics Object : Container

Graphics State

Outer
Container
Inner Container
Antialiasing mode

23

GDI+
Various Image format

GDI+ Image, Bitmap, Metafile .

BMP

GIF

JEPG

Exif

PNG

TIFF

ICON

WMF

EMF

24

GDI+ Programming Model


GDI

Device Context Handle

SelectObject Function .

Current Position

Brush

Resion Path

GDI+

Graphics

Pen , Brush , Bitmap , Font

Overloading

Current Position

Region Path

25

GDI+ Programming Model


In MFC

StdAfx.h

#ifndef ULONG_PTR

#define ULONG_PTR unsigned long *

#endif

#include <Gdiplus.h>

#include <GdiplusBase.h>

#include <GdiplusColor.h>

#include <GdiplusPen.h>

#include <GdiplusBrush.h>

#include <GdiplusPath.h>

#include <Gdiplusgraphics.h>

using namespace Gdiplus;

#pragma comment(lib, "gdiplus.lib")

26

GDI+ Programming Model


In MFC

CWinApp

Member Variable
ULONG_PTR m_gdiplusToken;

InitInstance()

GdiplusStartupInput gdiplusStartupInput;

// Initialize GDI+

GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

ExitInstance()
GdiplusShutdown(m_gdiplusToken);

27

GDI+ Coordinate Systems


Types of Coordinate Systems

World Coordinate System

Page Coordinate System

Device Coordinate System

Transformation Sequences of Coordinate

Before GDI+ can draw the line on screen

World Coordinate

Page Coordinate

Device Coordinate

28

GDI+ Coordinate Systems


GDI+

World Coordinate System

Transform .

GDI+ Function Call : graphics.DrawLine( &penBlack , 0 , 0 , 160 , 80 );

Page Coordinate System

(0,0) . ( )

: ( Page Coordinate System = Device Coordinate System )

Device Coordinate System

(0,0) . ( )

29

GDI+ Coordinate Systems


GDI+

( 100 , 50 )

30

GDI+ Coordinate Systems


Mapping

World Transformation

Map World Coordinates to Page Coordinates

Graphics .

World Coordinate

Page Coordinate

World Transformmation

TranslateTransform .

graphics.TranslateTransform( 100.0f , 50.0f );


graphics.DrawLine( &myPen , 0 , 0 , 160 , 80 );

31

GDI+ Coordinate Systems


Mapping

Page Transformation

Map Page Coordinates to Device Coordinates

Graphics .

Page Coordinate

Device Coordinate

Page Transformmation

SetPageUnit, GetPageUnit , SetPageScale, GetPageScale .

graphics.SetPageUnit( UnitInch );
graphics.DrawLine( &myPen , 0 , 0 , 2, 1);

32

GDI+ Coordinate Systems


Mapping

Page Transformation

Pen GetDpiX , GetDpiY .

GetDpiX , GetDpiY : Pixel per Inch .

Pen myPen(Color(255,0,0,0) , 1 / graphics.GetDpiX() );

graphics.DrawLine( &myPen , 0 , 0 , 2, 1); in 96 dots per inch

33

GDI+ Coordinate Systems


Mapping
graphics.TranslateTransform( 2.0f , 0.5f );
graphics.SetPageUnit( UnitInch );
graphics.DrawLine( &myPen , 0 , 0 , 2, 1);

34

GDI+ Global and Local Transformation


Matrix Class

Multiply , Invert , Rotate , RotateAt , Scale , Shear , OffsetX OffsetY

Clone, Equals .

Geometric Transformations
cos
sin

sin
cos
0

Rotate

0
1

x scale

y scale 0
0
1

x translate

Scale

0
0
1
0
y translate 1

Translate

35

GDI+ Global and Local Transformation


Matrix Class
// Create the path.
GraphicsPath myGraphicsPath;
Rect myRect(0, 0, 60, 60);
myGraphicsPath.AddRectangle(myRect);
// Fill the path on the new coordinate system.
// No local transformation
myGraphics.FillPath(&mySolidBrush1, &myGraphicsPath);
// Transform the path.
Matrix myPathMatrix;
myPathMatrix.Scale(2, 1);
myPathMatrix.Rotate(30, MatrixOrderAppend);
myGraphicsPath.Transform(&myPathMatrix);
myGraphics.FillPath(&mySolidBrush2, &myGraphicsPath);

36

GDI+ Global and Local Transformation


Graphics class

MultiplyTransform , RotateTransform ,

ScaleTransform , TranslateTransform

graphics.DrawEllipse( &penBlue , 0 , 0 , 100 , 50 );


graphics.ScaleTransform( 1.0f , 0.5f );
graphics.TranslateTransform( 50.0f , 0.0f , MatrixOrderAppend );
graphics.RotateTransform( 30.0f , MatrixOrderAppend );
graphics.DrawEllipse( &penBlue , 0 , 0 , 100 , 50 );

37

GDI+ : Pen
Pen

DrawLine , DrawRectangle , DrawEllipse , DrawPolygon , DrawArc ,


DrawCurve , DrawBezier
CClientDC dc(this);
Graphics graphics( dc.GetSafeHdc() );
Pen penBlack( Color(255,0,0) , 5 );
Status state = graphics.DrawRectangle( &penBlack , 10 , 10 , 100 , 50 );

38

GDI+ : Pen
Pen

Width & Alignment

Status SetWidth ( REAL width );

Status SetAlignment( PenAlignment penAlignment );


PenAlignmentCenter = 0
PenAlignmentInset = 1

Pen penBlack( Color(255,0,0,0) , 1 );


Pen penGreen( Color(255,0,255,0) , 10 );
Status state = penGreen.SetAlignment(PenAlignmentCenter);
state = graphics.DrawLine( &penGreen, 10 , 100 , 100 , 50 );
state = graphics.DrawLine( &penBlack, 10 , 100, 100, 50 );

39

GDI+ : Pen
Pen

Width & Alignment


Pen penBlack( Color(255,0,0,0) , 1 );
Pen penGreen( Color(255,0,255,0) , 10 );
Status state = penGreen.SetAlignment(PenAlignmentInset);
state = graphics.DrawRectangle( &penGreen, 10 , 100 , 50 , 50 );
state = graphics.DrawRectangle( &penBlack, 10 , 100, 50, 50 );

40

GDI+ : Pen
Pen

Line Caps

SetStartCap , SetEndCap

Cap Type

LineCapFlat = 0

LineCapSquare = 1

LineCapRound = 2

LineCapTriangle = 3

LineCapNoAnchor = 0x10

LineCapSquareAnchor = 0x11

LineCapRoundAnchor = 0x12

LineCapDiamondAnchor = 0x13

LineCapArrowAnchor = 0x14

LineCapCustom = 0xff

41

GDI+ : Pen
Pen

LineCapArrowAnchor

Status state;
Pen penBlack( Color(255,0,0,0) , 5 );
state = penBlack.SetStartCap( LineCapArrowAnchor );
state = penBlack.SetEndCap( LineCapRoundAnchor );
state = graphics.DrawLine( &penBlack , 20 , 175 , 300 , 175 );

42

GDI+ : Pen
Pen

LineCapCustom

Pen member function


Status SetCustomStartCap( const CustomLineCap * customCap );
Status SetCustomEndCap( const CustomLineCap * customCap );

Class CustomLineCap
GraphicsPath .

CustomLineCap( const GraphicsPath * fillPath, const GraphicsPath * strokePath,

LineCap baseCap, REAL baseInset);

fillPath strokePath .

fillPath strokePath fillPath .

43

GDI+ : Pen
Pen

LineCapCustom

Class CustomLineCap
Graphics graphics(hdc);
Point points[3] = {Point(-15, -15), Point(0, 0), Point(15, -15)};
GraphicsPath capPath;
capPath.AddLines(points, 3);
CustomLineCap custCap(NULL, &capPath);
custCap.SetStrokeCaps(LineCapTriangle, LineCapRound);
Pen strokeCapPen(Color(255, 255, 0, 255), 5.0f);
strokeCapPen.SetCustomEndCap(&custCap);
graphics.DrawLine(&strokeCapPen, Point(100, 100), Point(300, 100));

44

GDI+ : Pen
Pen

LineCapCustom

Class CustomLineCap
Based Vertical Line

LineCapTriangle

LineCapRound
-15

45

GDI+ : Pen
Pen

LineCapCustom

CustomLineCap

BaseClass

AdjustableArrowCap

SubClass

Class AdjustableArrowCap
.

AdjustableArrowCap( REAL height, REAL width, BOOL isFilled );

width
height

46

GDI+ : Pen
Pen

LineCapCustom

Class AdjustableArrowCap
Graphics graphics(hdc);
AdjustableArrowCap myArrow(10, 10, true);
Pen arrowPen(Color(255, 0, 0, 0));
arrowPen.SetCustomEndCap(&myArrow);
graphics.DrawLine(&arrowPen, Point(0, 20), Point(100, 20));
AdjustableArrowCap otherArrow(myArrow.GetHeight(), 20, true);
arrowPen.SetCustomEndCap(&otherArrow);
graphics.DrawLine(&arrowPen, Point(0, 55), Point(100, 55));

47

GDI+ : Pen
Pen

Dash Line

REAL dashValues[4] = {5, 2, 15, 4};


Pen blackPen(Color(255, 0, 0, 0), 5);
blackPen.SetDashPattern(dashValues, 4);
Status stat = graphics.DrawLine(&blackPen, Point(5, 5),
Point(405, 5));

48

GDI+ : Pen
Pen

Join Line
GraphicsPath path;
Pen penJoin(Color(255, 0, 0, 255), 8);
Status stat = path.StartFigure();
stat = path.AddLine(Point(50, 200), Point(100, 200));
stat = path.AddLine(Point(100, 200), Point(100, 250));
stat = penJoin.SetLineJoin(LineJoinBevel);
stat = graphics.DrawPath(&penJoin, &path);

49

GDI+ : Pen
Pen

Texture Image .
Status state;
Image image(LTexture.jpg);
TextureBrush brTexture(&image)
Pen penTexture(&brTexture , 10 );
state = graphics.DrawImage( &image , 0 , 0 ,
image.GetWidth(), image.GetHeight() );
state = graphics.DrawEllipse( &penTexture ,100,20,200,100);

50

GDI+ : Brush
Brush

Type : solid , hatch pattern , image texture , color gradient

Function : FillRectangle , FillEllipse , FillRegion , FillPolygon ,


FillClosedCurve

SolidBrush brSolid(Color(255,255,0,0));
Status state = graphics.FillEllipse( &brSolid , 0 , 0 , 100 , 50 );

51

GDI+ : Brush
Brush

Hatch Style

HatchStyleHorizontal , HatchStyleVertical , HatchStyleForwardDiagonal

HatchStyleBackwardDiagonal , HatchStyleCross , HatchStyleDiagonalCross

HatchBrush brHatch( HatchStyleHorizontal , Color(255,255,0,0)


, Color(255,128,255,255));
Status state = graphics.FillEllipse( &brHatch , 0 , 0 , 100 , 50 );

52

GDI+ : Brush
Gradient Brush

LinearGradientBrush

Rect rect( 0 , 0 , 140 , 70 );


LinearGradientBrush brLGradient( rect ,
Color(255,255,0,0) ,
Color(255,0,0,255) ,
LinearGradientModeHorizontal );
graphics.FillEllipse( &brLGradient , rect );

53

GDI+ : Brush
Gradient Brush

LinearGradientBrush

Point point1(0, 0);


Point point2(100, 80);
LinearGradientBrush brLGradient( point1, point2, Color(255, 255,
0, 0),
Color(255, 0, 0,
255));
graphics. FillRectangle( &brLGradient , 0 , 0 , 100 , 80 );

54

GDI+ : Brush
Path Gradient Brush

PathGradientBrush
GraphicsPath pathEllipse;
pathEllipse.AddEllipse(0,0,140,70);
PathGradientBrush brPathBrush( &pathEllipse );
Color clrCenter( 255 , 0 , 0 , 255 );
Color clrSurround( 255 , 200 , 255 , 255 );
int nColor = 1;
brPathBrush.SetCenterColor( clrCenter );
brPathBrush.SetSurroundColors( &clrSurround , &nColor );
graphics.FillPath( &brPathBrush , &pathEllipse );

55

GDI+ : Brush
Path Gradient Brush

PathGradientBrush
PointF ptsF[] = {PointF(0, 0),
PointF(160, 0),
PointF(160, 200),
PointF(80, 150),
PointF(0, 200)};
PathGradientBrush pBrush(ptsF, 5);
Color colors[] = {Color(255, 255, 0, 0), // (0, 0) red
Color(255, 0, 255, 0), // (160, 0) green
Color(255, 0, 255, 0), // (160, 200) green
Color(255, 0, 0, 255), // (80, 150) blue
Color(255, 255, 0, 0)}; // (0, 200) red
int count = 5;
Status stat = pBrush.SetSurroundColors(colors, &count);
stat = pBrush.SetCenterColor(Color(255, 255, 255, 255));
stat = graphics.FillRectangle(&pBrush, Rect(0, 0, 180, 220));

56

GDI+ : Brush
Applying Gamma Correction to a Gradient

SetGammaCorrection .

LinearGradientBrush brLGradient( Point(0 , 10 ), Point(200, 10),


Color(255,255,0,0) , Color(255,0,0,255));
graphics.FillRectangle( &brLGradient , 0,0,200,50);
graphics.SetGammaCorrection(TRUE);
graphics.FillRectangle( &brLGradient, 0 ,60,200,50);

57

GDI+ : Brush
Applying Gamma Correction to a Gradient

SetGammaCorrection .
Point points[] = {Point(75, 0), Point(100, 50), Point(150, 50), Point(112, 75), Point(150, 150),
Point(75, 100), Point(0, 150), Point(37, 75), Point(0, 50), Point(50, 50)};
GraphicsPath path;
path.AddLines(points, 10);
PathGradientBrush pthGrBrush(&path);
pthGrBrush.SetCenterColor(Color(255, 255, 0, 0));
Color colors[] = {Color(255, 0, 0, 0), Color(255, 0, 255, 0), Color(255, 0, 0, 255), Color(255, 255, 255, 255),
Color(255, 0, 0, 0), Color(255, 0, 255, 0), Color(255, 0, 0, 255), Color(255, 255, 255, 255),
Color(255, 0, 0, 0), Color(255, 0, 255, 0)};
int count = 10;
pthGrBrush.SetSurroundColors(colors, &count);
graphics.FillPath(&pthGrBrush, &path);
pthGrBrush.SetGammaCorrection(TRUE);
graphics.TranslateTransform(200.0f, 0.0f);
graphics.FillPath(&pthGrBrush, &path);

58

GDI+ : Brush
Applying Gamma Correction to a Gradient

SetGammaCorrection .

59

GDI+ : Brush
Tiling a Shape with an Image

TextureBrush .
Image image(LHouseAndTree.gif);
TextureBrush brTexture(&image);
Pen penBlack(Color(255,0,0,0));
state = graphics.FillRectangle( &brTexture , Rect( 0,0,200,200));
state = graphics. DrawRectangle( &penBlack , Rect( 0,0,200,200));

60

GDI+ : Brush
Tiling a Shape with an Image

TextureBrush .
Image image(LHouseAndTree.gif);
TextureBrush brTexture(&image);
Pen penBlack(Color(255,0,0,0));
state = brTexture.SetWrapMode( WarpModeTileFlipX);
state = graphics.FillRectangle( &brTexture , Rect( 0,0,200,200));
state = graphics. DrawRectangle( &penBlack , Rect( 0,0,200,200));

61

GDI+ : Path
GraphicsPaths Building Blocks

Lines , Rectangles , Ellipses , Arcs , Polygons

Cardinal Splines , Bzier Splines


GraphicsPath path;
FontFamily fontFamily(L"Times New Roman");
StringFormat stringFormat;
stringFormat.SetLineAlignment(StringAlignmentCenter);
Font font(LTimes New Roman", 20);
SolidBrush solidBrush(Color::Blask);
graphics.DrawString( string1, wcslen(string1), &font, PointF(10, 10), &solidBrush);
path.AddArc(0, 0, 30, 20, -90, 180);
path.AddString(La string in a path" , 18 , &fontFamily , 0 , 50 , PointF(20,30) , &stringFormat );
path.AddPie(230, 50, 40,40,40,110);
Pen pen(Color(255,0,0,255), 1);
graphics.DrawPath(&pen, &path);

62

GDI+ : Path
Filling Open Figures

GraphicsPath path;
path.AddArc(0, 0, 150, 120, 30, 120);
path.AddEllipse(50, 50, 50, 100);
Pen pen(Color(128, 0, 0, 255), 5);
SolidBrush brush(Color(255, 255, 0, 0));
graphics.FillPath(&brush, &path);
graphics.DrawPath(&pen, &path);

63

GDI+ : Regions
Region

Simple : a single rectangle

Complex : a combination of polygons and closed curves

Region Class

Intersection

Union

Xor

Exclude

Complement

64

GDI+ : Regions
Region Class

Complement example
Graphics graphics(hdc);
SolidBrush solidBrush(Color(255, 255, 0, 0));
Point points[] = { Point(110, 20), Point(120, 30), Point(100, 60),
Point(120, 70), Point(150, 60), Point(140, 10)};
Rect rect(65, 15, 70, 45);
GraphicsPath path;
path.AddClosedCurve(points, 6);
Region region(rect);
region.Complement(&path); graphics.FillRegion(&solidBrush, &region);

65

GDI+ : Regions
Hit Testing with a Region

Region::IsVisible
Point point(60, 10);
SolidBrush solidBrush(Color());
Region region1(Rect(50, 0, 50, 150));
Region region2(Rect(0, 50, 150, 50));
region1.Union(&region2);
if(region1.IsVisible(point, &graphics))
solidBrush.SetColor(Color(255, 255, 0, 0));
else
solidBrush.SetColor(Color(64, 255, 0, 0));
graphics.FillRegion(&solidBrush, &region1);

66

GDI+ : Regions
Clipping with a Region

Graphics::SetClip Region
Point polyPoints[] = {Point(10, 10), Point(150, 10), Point(100, 75), Point(100, 150)};
GraphicsPath path;
path.AddPolygon(polyPoints, 4);
Region region(&path);
Pen pen(Color(255, 0, 0, 0));
graphics.DrawPath(&pen, &path);
graphics.SetClip(&region);
FontFamily fontFamily(L"Arial");
Font font(&fontFamily, 36, FontStyleBold, UnitPixel);
SolidBrush solidBrush(Color(255, 255, 0, 0));
graphics.DrawString(L"A Clipping Region", 20, &font, PointF(15, 25), &solidBrush);
graphics.DrawString(L"A Clipping Region", 20, &font, PointF(15, 68), &solidBrush);

67

GDI+ : Image
Image Class

Low Level Image Class


Image image(LLena.bmp);
graphics.DrawImage(&image , 60 , 10 );

68

GDI+ : Image
Image Class

Meta file
Image image(LSampleMetaFile.emf);
graphics.DrawImage(&image , 60 , 10 );

69

GDI+ : Image
Bitmap Class

High Level Image Class


Bitmap image(LLena.bmp);
graphics.DrawImage(&image , 60 , 10 );

70

GDI+ : Image
Image Display Code

View Class Member Variable

View Class Constructor

m_pImage = NULL;

View Class Destructor

Bitmap* m_pImage;

if( m_pImage != NULL )


Delete m_pImage;

OnDraw

Graphics graphics( pDC->GetSafeHdc() );

graphics.DrawImage(m_pImage , 60 , 10 );

71

GDI+ : Image
Image Display Code

Image Load Function


bool CImage::SetFileName(CString strImage)
{
m_strImage = strImage;
if( m_pImage != NULL )
{
delete m_pImage;
m_pImage = NULL;
}
int nSizeCount = MultiByteToWideChar( CP_ACP, 0, m_strImage , -1, NULL, 0 );
WCHAR * pWString = new WCHAR[nSizeCount];
MultiByteToWideChar( CP_ACP, 0, m_strImage , -1 , pWString , nSizeCount );
m_pImage = Bitmap::FromFile( pWString );
delete[] pWString;
if( m_pImage == NULL )
return false;
return true;
}

72

GDI+ : Image
Translation , Rotation , Distortion , Scaling

: , ,

(0,0)

(50,0)
(200,20)
(250,30)

(0,50
)

(110,100
)

Point destPoints[] = { Point(200,20) , Point(250 , 30) , Point(110, 100) };


Image image(LLena.bmp);
graphics.DrawImage(&image , 0 , 0 );
graphics.DrawImage(&image , destPoints , 3 );

73

GDI+ : Image
Interpolation Mode to Control Image Quality During Scaling

Graphics::SetInterpolationMode

Graphics::GetInterpolationMode

Interpolation Mode

InterpolationModeNearestNeighbor

InterpolationModeBilinear

InterpolationModeHighQualityBilinear

InterpolationModeBicubic

InterpolationModeHighQualityBicubic

Etc..

74

GDI+ : Image
Interpolation Mode to Control Image Quality During Scaling
Image image(L"GrapeBunch.bmp");
UINT width = image.GetWidth();
UINT height = image.GetHeight();
graphics.DrawImage( &image, Rect(10, 10, width, height), 0, 0, width, height,
UnitPixel);
graphics.SetInterpolationMode(InterpolationModeNearestNeighbor);
graphics.DrawImage( &image, Rect(10, 250, 0.6*width, 0.6*height), 0, 0, width, height,
UnitPixel);
graphics.SetInterpolationMode(InterpolationModeHighQualityBilinear);
graphics.DrawImage( &image, Rect(150, 250, 0.6 * width, 0.6 * height), 0, 0, width,
height, UnitPixel);
graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);
graphics.DrawImage( &image, Rect(290, 250, 0.6 * width, 0.6 * height), 0, 0, width,
height, UnitPixel);

75

GDI+ : Image
Interpolation Mode to Control Image Quality During Scaling

76

GDI+ : Image
Thumbnail Image
Image image(LCompass.bmp);
Image * pThumbnail = image.GetThumbnailImage(100,100,NULL,NULL);
graphics.DrawImage(pThumbnail , 10 , 10 ,
pThumnail->GetWidth() ,
pThumbnail->GetHeight() );

77

GDI+ : Image
Cached Image

Drawing

Device Independent Image => Display Device dependent Image

Bitmap bitmap(LTexture.jpg);
CachedBitmap cbitmap(&bitmap , &graphics );
graphics.DrawImage( &bitmap , 0 , 0 ,
bitmap.GetWidth() ,
bitmap.GetHeight() );
graphics.DrawCachedBitmap(&cBitmap , 0 , 150 );

78

GDI+ : Image
Improving Performance by Automatic Scaling

DrawImage Upper-Left corner

Graphics.DrawImage( &image, 50 , 30 ); // upper-left cornet at (50, 30)


GDI+
.

Image image(LTexture.jpg);
graphics.DrawImage( &image , 10 , 10 );
graphics.DrawImage( &image , 120 , 10,
image.GetWidth() ,
image.GetHeight() );

79

GDI+ : Image Codec


Image Codec

BMP , JPEG , PNG , TIFF , EMF

Codec : GDI+ .

Codec : MIME type

Codecs MIME Type

image/bmp

image/gif

image/tiff

image/jpeg

image/emf

image/png

Etc..

80

GDI+ : Image Codec


Listing Installed Encoders
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;
INT main() {
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
UINT num; // number of image encoders
UINT size; // size, in bytes, of the image encoder array
ImageCodecInfo* pImageCodecInfo;
GetImageEncodersSize(&num, &size);

81

GDI+ : Image Codec


Listing Installed Encoders
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
wprintf(L"%s\n", pImageCodecInfo[j].MimeType);
free(pImageCodecInfo);
GdiplusShutdown(gdiplusToken);
return 0;
}

82

GDI+ : Image Codec


Listing Installed Decoders
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;
INT main() {
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
UINT num; // number of image encoders
UINT size; // size, in bytes, of the image encoder array
ImageCodecInfo* pImageCodecInfo;
GetImageDecodersSize(&num, &size);

83

GDI+ : Image Codec


Listing Installed Decoders
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
GetImageDecoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
wprintf(L"%s\n", pImageCodecInfo[j].MimeType);
free(pImageCodecInfo);
GdiplusShutdown(gdiplusToken);
return 0;
}

84

GDI+ : Image Codec


Retrieving the Class Identifier for an Encoder
int GetCodecClsid( const WCHAR * format , CLSID* pClsid )
{
UINT nCodecNum = 0;
UINT nCodecInfoSize = 0;
ImageCodecInfo * pImageCodecInfo = NULL;
GetImageEncodersSize(&nCodecNum , &nCodecInfoSize );
if( nCodecInfoSize == 0 )
return -1;
pImageCodecInfo = (ImageCodecInfo*)new BYTE[nCodecInfoSize];
if( pImageCodecInfo == NULL )
return -1;
GetImageEncoders( nCodecNum , nCodecInfoSize , pImageCodecInfo );

85

GDI+ : Image Codec


Retrieving the Class Identifier for an Encoder
for( int nIndex = 0 ; nIndex < nCodecNum ; nIndex++ )
{
if( wcscmp(pImageCodecInfo[nIndex].MimeType , format ) == 0 )
{
* pClsid = pImageCodecInfo[nIndex].Clsid;
delete[] pImageCodecInfo;
return nIndex;
}
}
delete[] pImageCodecInfo;
return -1;
}

86

GDI+ : Image Codec


Converting a BMP Image to a JPEG Image
CLSID
EncoderParameters
long
Status

clsidCodec;
encoderParams;
lQuality;
state;

Image image(L"lena.bmp");
if( GetCodecClsid(L"image/jpeg", &clsidCodec ) == -1) return false
encoderParams.Count = 1;
encoderParams.Parameter[0].Guid = EncoderQuality;
encoderParams.Parameter[0].Type =EncoderParameterValueTypeLong;
encoderParams.Parameter[0].NumberOfValues = 1;
lQuality = 100;
encoderParams.Parameter[0].Value = &lQuality;
state = image.Save(L"lena.jpg", &clsidCodec , &encoderParams );
if( state != OK ) return false;
return true;

87

GDI+ : Image Codec


Creating and Saving a Multiple-Frame Image
#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;
INT GetEncoderClsid(const WCHAR* format, CLSID* pClsid);
INT main()
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
EncoderParameters encoderParameters;
ULONG parameterValue;
Status stat;
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderSaveFlag;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
encoderParameters.Parameter[0].Value = &parameterValue;

88

GDI+ : Image Codec


Creating and Saving a Multiple-Frame Image
CLSID encoderClsid;
if( GetEncoderClsid(L"image/tiff", &encoderClsid) == -1 ) return 1;
Image* multi = new Image(L"Shapes.bmp");
Image* page2 = new Image(L"Cereal.gif");
Image* page3 = new Image(L"Iron.jpg");
Image* page4 = new Image(L"House.png");
parameterValue = EncoderValueMultiFrame;
stat = multi->Save(L"MultiFrame.tif", &encoderClsid, &encoderParameters);
if(stat == Ok) printf("Page 1 saved successfully.\n");
parameterValue = EncoderValueFrameDimensionPage;
stat = multi->SaveAdd(page2, &encoderParameters);
if(stat == Ok) printf("Page 2 saved successfully.\n");
parameterValue = EncoderValueFrameDimensionPage;
stat = multi->SaveAdd(page3, &encoderParameters);
if(stat == Ok) printf("Page 3 saved successfully.\n");

89

GDI+ : Image Codec


Creating and Saving a Multiple-Frame Image
parameterValue = EncoderValueFrameDimensionPage;
stat = multi->SaveAdd(page4, &encoderParameters);
if(stat == Ok) printf("Page 4 saved successfully.\n");
parameterValue = EncoderValueFlush;
stat = multi->SaveAdd(&encoderParameters);
if(stat == Ok) printf("File closed successfully.\n");
delete multi;
delete page2;
delete page3;
delete page4;
GdiplusShutdown(gdiplusToken);
return 0;
}

90

GDI+ : Graphics Container


Graphics

Vector Image , Raster Image , String format .

Container

Graphics State

Device Context

Quality Information

Transformation

Clipping region

91

GDI+ : Nested Graphics Container


Graphics Container

Graphics Object : Container

Graphics State

BeginContainer , EndContainer
CClientDC dc(this)
Graphics
graphics(dc.GetSafeHdc() );
Pen
pen(Color(255,255,0,0));
graphics.TranslateTransform(100,80);

(100,80)

GraphicsContainer graphicContainer = graphics.BeginContainer();


graphics.RotateTransform(30);
grahpics.DrawRectangle(& pen , -60 , -30 , 120 , 60 );
graphics.EndContainer(graphicsContainer);
graphics. DrawRectangle(& pen , -60 , -30 , 120 , 60 );

92

GDI+ : Alpha Blending


Drawing Opaque and Semitransparent Lines

SetCompositingQuality Gamma correction


Blending .
Image image(L"Texture1.jpg");
graphics.DrawImage(&image, 10, 5, image.GetWidth(), image.GetHeight());
Pen penOpaque(Color(255, 0, 0, 255), 15);
Pen penSemiTrans( Color(128, 0 , 0, 255), 15);
graphics.DrawLine(&penOpaque, 0, 20, 100, 20 );
graphics.DrawLine(&penSemiTrans, 0, 40, 100, 40 );
graphics.SetCompositingQuality( CompositingQualityGammaCorrected );
graphics.DrawLine(&penSemiTrans, 0, 60, 100, 60 );

93

GDI+ : Alpha Blending


Color Matrix

Original
Bitmap bitmap(L"Texture1.jpg");
Status stat = graphics.DrawLine(&Pen(Color(255, 0, 0, 0), 25),
Point(10, 35),
Point(200, 35));
stat = graphics.DrawImage(&bitmap, Rect(30, 0,
bitmap.GetWidth(),
bitmap.GetHeight()));

94

GDI+ : Alpha Blending


Color Matrix

Alpha Blending
Bitmap bitmap(L"Texture1.jpg");
ColorMatrix colorMatrix = {1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 1, 0, 0,
0, 0, 0, 0.8, 0 ,
0, 0, 0, 0, 1};
ImageAttributes imageAtt;
Status stat = imageAtt.SetColorMatrix(&colorMatrix, ColorMatrixFlagsDefault,
ColorAdjustTypeBitmap);
stat = graphics.DrawLine(&Pen(Color(255, 0, 0, 0), 25), Point(10, 35), Point(200, 35));
int iWidth = bitmap.GetWidth();
int iHeight = bitmap.GetHeight();
graphics.DrawImage( &bitmap, Rect(30, 0, iWidth, iHeight), 0.0f, 0.0f, iWidth, iHeight,
UnitPixel, &imageAtt );

95

GDI+ : Alpha Blending


Setting the Alpha Values of Individual Pixel
INT iWidth = bitmap.GetWidth();
INT iHeight = bitmap.GetHeight();
Color color, colorTemp;
for(INT iRow = 0; iRow < iHeight; iRow++)
{
for(INT iColumn = 0; iColumn < iWidth; iColumn++)
{
bitmap.GetPixel(iColumn, iRow, &color);
colorTemp.SetValue(color.MakeARGB( (BYTE)(255 * iColumn / iWidth),
color.GetRed(), color.GetGreen(), color.GetBlue()));
bitmap.SetPixel(iColumn, iRow, colorTemp);
}
}
Pen pen(Color(255, 0, 0, 0), 25);
graphics.DrawLine(&pen, 10, 35, 200, 35);
graphics.DrawImage(&bitmap, 30, 0, iWidth, iHeight);

96

GDI+ : Text Antialiasing


Antialiasing with Text

SetTextRenderingHint
enum TextRenderingHint
{

TextRenderingHintSystemDefault = 0,
TextRenderingHintSingleBitPerPixelGridFit,
TextRenderingHintSingleBitPerPixel,
TextRenderingHintAntiAliasGridFit,
TextRenderingHintAntiAlias,
TextRenderingHintClearTypeGridFit

};

97

GDI+ : Text Antialiasing


Antialiasing with Text

SetTextRenderingHint
FontFamily fontFamily(L"Times New Roman");
Font font(&fontFamily, 32, FontStyleRegular, UnitPixel);
SolidBrush solidBrush(Color(255, 0, 0, 255));
WCHAR string1[] = L"SingleBitPerPixel";
WCHAR string2[] = L"AntiAlias";
WCHAR string3[] = L"ClearTypeGridFit";
graphics.SetTextRenderingHint(TextRenderingHintSingleBitPerPixel);
graphics.DrawString( string1, wcslen(string1), &font, PointF(10, 10),
&solidBrush);
graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
graphics.DrawString( string2, wcslen(string2), &font, PointF(10, 60),
&solidBrush);
graphics.SetTextRenderingHint(TextRenderingHintClearTypeGridFit);
graphics.DrawString( string3, wcslen(string3), &font, PointF(10, 110),
&solidBrush);

98

GDI+ : Antialiasing
Antialiasing with Lines and Curves

SetSmoothingMode
enum SmoothingMode
{

SmoothingModeInvalid = QualityModeInvalid,
SmoothingModeDefault = QualityModeDefault,
SmoothingModeHighSpeed = QualityModeLow,
SmoothingModeHighQuality = QualityModeHigh,
SmoothingModeNone,
SmoothingModeAntiAlias

};
myGraphics.SetSmoothingMode(SmoothingModeAntiAlias);
myGraphics.DrawLine(&myPen, 0, 0, 12, 8);

99

GDI+ : Recoloring
Color Remapping

Colormap Structure Old Color => New Color


Image image(L"RemapInput.bmp");
ImageAttributes imageAttributes;
UINT width = image.GetWidth();
UINT height = image.GetHeight();
ColorMap colorMap[1];
colorMap[0].oldColor = Color(255, 255, 0, 0);
colorMap[0].newColor = Color(255, 0, 0, 255);
imageAttributes.SetRemapTable(1, colorMap, ColorAdjustTypeBitmap);
graphics.DrawImage(&image, 10, 10, width, height);
graphics.DrawImage( &image, Rect(150, 10, width, height), 0, 0, width, height, UnitPixel,
&imageAttributes);

100

GDI+ : Recoloring
Translating Colors

ColorMatrix Color Component Translating


Image image(L"ColorBars.bmp");
ImageAttributes imageAttributes;
UINT width = image.GetWidth();
UINT height = image.GetHeight();
ColorMatrix colorMatrix = { 1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 1, 0,
0.75, 0, 0, 0, 1 };
imageAttributes.SetColorMatrix( &colorMatrix, ColorMatrixFlagsDefault,
ColorAdjustTypeBitmap);
graphics.DrawImage(&image, 10, 10, width, height);
graphics.DrawImage( &image, Rect(150, 10, width, height), 0, 0, width, height, UnitPixel,
&imageAttributes);

101

GDI+ : Recoloring
Translating Color

102

GDI+ : Recoloring
Scaling Color

ColorMatrix Color Component Scaling


Image image(L"ColorBars2.bmp");
ImageAttributes imageAttributes;
UINT width = image.GetWidth();
UINT height = image.GetHeight();
ColorMatrix colorMatrix = { 1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
0, 0, 2, 0, 0,
0, 0, 0, 1, 0,
0, 0, 0, 0, 1};
imageAttributes.SetColorMatrix( &colorMatrix, ColorMatrixFlagsDefault,
ColorAdjustTypeBitmap);
graphics.DrawImage(&image, 10, 10, width, height);
graphics.DrawImage( &image, Rect(150, 10, width, height), 0, 0, width, height,
UnitPixel, &imageAttributes);

103

GDI+ : Recoloring
Scaling Color

104

GDI+ : Recoloring
Rotating Color

Alpha Component 1

Rotating Color Matrix

105

GDI+ : Recoloring
Rotating Color
Image image(L"RotationInput.bmp");
ImageAttributes imageAttributes;
UINT width = image.GetWidth();
UINT height = image.GetHeight();
REAL degrees = 60;

REAL pi = acos(-1);

REAL r = degrees * pi / 180;

ColorMatrix colorMatrix = { cos(r), sin(r), 0.0f, 0.0f, 0.0f,


-sin(r), cos(r), 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f };
imageAttributes.SetColorMatrix( &colorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);
graphics.DrawImage(&image, 10, 10, width, height);
graphics.DrawImage( &image, Rect(130, 10, width, height), 0, 0, width, height,
UnitPixel, &imageAttributes);

106

GDI+ : Recoloring
Rotating Color

107

GDI+ : Spline
Cardinal Spline

DrawCurve
Point points[] = {Point(0, 100),
Point(50, 80),
Point(100, 20),
Point(150, 80),
Point(200, 100)};
Pen pen(Color(255, 0, 0, 255));
graphics.DrawCurve(&pen, points, 5);

108

GDI+ : Spline
Cardinal Spline

DrawClosedCurve
Point points[] = {Point(60, 60),
Point(150, 80),
Point(200, 40),
Point(180, 120),
Point(120, 100),
Point(80, 160)};
Pen pen(Color(255, 0, 0, 255));
graphics.DrawClosedCurve(&pen, points, 6);

109

GDI+ : Spline
Cardinal Spline

Tension
Point points[] = {Point(20, 50),
Point(100, 10),
Point(200, 100),
Point(300, 50),
Point(400, 80)};
Pen pen(Color(255, 0, 0, 255));
graphics.DrawCurve(&pen, points, 5, 0.0); // tension 0.0
graphics.DrawCurve(&pen, points, 5, 0.6); // tension 0.6
graphics.DrawCurve(&pen, points, 5, 1.0); // tension 1.0

110

GDI+ : Spline
Bzier Spline

DrawBezier
Point p1(10, 100); // start point
Point c1(100, 10); // first control point
Point c2(150, 150); // second control point
Point p2(200, 100); // end point
Pen pen(Color(255, 0, 0, 255));
graphics.DrawBezier(&pen, p1, c1, c2, p2);

111

GDI+ : Transform
Graphics Transform
Rect rect(0, 0, 50, 50);
Pen pen(Color(128, 200, 0, 200), 2);
stat = graphics.DrawRectangle(&pen, rect);
stat = graphics.ScaleTransform(1.75, 0.5);
stat = graphics.DrawRectangle(&pen, rect);
stat = graphics.ResetTransform();
stat = graphics.RotateTransform(28);
stat = graphics.DrawRectangle(&pen, rect);
stat = graphics.ResetTransform();
stat = graphics.TranslateTransform(150, 150);
stat = graphics.DrawRectangle(&pen, rect);

112

GDI+ Example
Bezier Spline Draw Program

113

GDI+ Example
Bezier Spline Draw Program

Bezier Control Point 3 .

114

GDI+ Example
Bezier Spline Draw Program

SDI .

115

GDI+ Example
CBezierSpline Class

Bezier Spline
class CBezierSpline
{
public:
CBezierSpline();
CBezierSpline(CPoint ptP1, CPoint ptP2, CPoint ptP3, CPoint ptP4);
virtual ~CBezierSpline();
protected:
CPoint m_ptStart;
CPoint m_ptEnd;
protected:
CPoint m_ptP1;
CPoint m_ptP2;
CPoint m_ptP3;
CPoint m_ptP4;
protected:
CPoint* m_pSelectedPoint;
public:
CPoint* GetSelectedPoint();
bool
PtInControlPoint(CPoint ptPos );
public:
CPoint GetP1();
void SetP1(CPoint ptP1);

116

GDI+ Example
Public:
CPoint GetP2();
void SetP2(CPoint ptP2);
CPoint GetP3();
void SetP3(CPoint ptP3);
CPoint GetP4();
void SetP4(CPoint ptP4);
public:
static CImageList
void InitImageList();

m_imglistPoint;

public:
void ComputeControlPos(double dRate = 0.6);
CRect GetBoundBox();
public:
virtual void Draw(CDC* pDC , int nLineWidth = 1 , COLORREF clrLine = RGB(0,0,0), bool bAntialiasing = true);
virtual void Draw(Graphics* pGraphics , int nLineWidth = 1 , COLORREF clrLine = RGB(0,0,0), bool bAntialiasing = true);
virtual void DrawSpline(CDC * pDC, int nLineWidth = 1 , COLORREF clrLine = RGB(0,0,0) , bool bAntialiasing = true);
virtual void DrawSpline(Graphics* pGraphics , int nLineWidth = 1 , COLORREF clrLine = RGB(0,0,0), bool bAntialiasing = true);
protected:
virtual void DrawControl(CDC * pDC);
public:
virtual bool LButtonDown(CWnd* pWnd, UINT nFlags, CPoint point, bool bControlMode = false);
virtual bool LButtonUp(CWnd* pWnd, UINT nFlags, CPoint point, bool bControlMode = false);
};

virtual bool MouseMove(CWnd* pWnd, UINT nFlags, CPoint point, bool bControlMode = false);

117

GDI+ Example
#include "stdafx.h"
#include "BezierSpline.h"
#include <math.h>
#include "resource.h"

//-------------------------------------------------------------------------// : .
//-------------------------------------------------------------------------CBezierSpline::CBezierSpline()
{
m_ptP1 = m_ptP4 = CPoint(-1, -1);
m_ptP2 = m_ptP3 = CPoint(-1, -1);
//----------------------------------------------------------------------// Control Point .
//----------------------------------------------------------------------m_pSelectedPoint = NULL;

#include "LineEquation.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//--------------------------------------------------------------------------// : Ascending Sorting .
//--------------------------------------------------------------------------int CompareInt(const void *pLeft, const void *pRight)
{
int* pL = (int *)pLeft;
int* pR = (int *)pRight;

if( *pL > *pR )


return 1;
else if( *pL < *pR )
return -1;
else
return 0;

//----------------------------------------------------------------------// Control Point .


//----------------------------------------------------------------------InitImageList();

CBezierSpline::CBezierSpline(CPoint ptP1, CPoint ptP2,


CPoint ptP3, CPoint ptP4 )
{
m_ptP1 = ptP1;
m_ptP2 = ptP2;
m_ptP3 = ptP3;
m_ptP4 = ptP4;
//----------------------------------------------------------------------// Control Point .
//----------------------------------------------------------------------m_pSelectedPoint = NULL;

CImageList CBezierSpline::m_imglistPoint;

//----------------------------------------------------------------------// Control Point .


//----------------------------------------------------------------------InitImageList();

118

GDI+ Example
CBezierSpline::~CBezierSpline()
{
}
//--------------------------------------------------------------------------// : BezierSpline Control Point .
//--------------------------------------------------------------------------void CBezierSpline::InitImageList()
{
if( !m_imglistPoint.GetSafeHandle() )
{
m_imglistPoint.Create(7 , 7 , ILC_COLOR4 | ILC_MASK , 0 , 3 );

m_imglistPoint.Add( AfxGetApp()->LoadIcon(IDI_FIRST_RECT) );
m_imglistPoint.Add( AfxGetApp()->LoadIcon(IDI_SECOND_RECT) );
m_imglistPoint.Add( AfxGetApp()->LoadIcon(IDI_RECT_TARGET) );

//--------------------------------------------------------------------------// : BezierSpline Start Point .


//--------------------------------------------------------------------------void CBezierSpline::SetP1(CPoint ptP1)
{
m_ptP1 = ptP1;
}
//--------------------------------------------------------------------------// : BezierSpline Start Point .
//--------------------------------------------------------------------------CPoint CBezierSpline::GetP1()
{
return m_ptP1;
}

119

GDI+ Example
//--------------------------------------------------------------------------// : BezierSpline Start Point .
//--------------------------------------------------------------------------CPoint CBezierSpline::GetP1()
{
return m_ptP1;
}
//--------------------------------------------------------------------------// : BezierSpline End Point .
//--------------------------------------------------------------------------void CBezierSpline::SetP2(CPoint ptP2)
{
m_ptP2 = ptP2;
}
//--------------------------------------------------------------------------// : BezierSpline End Point .
//--------------------------------------------------------------------------CPoint CBezierSpline::GetP2()
{
return m_ptP2;
}
//--------------------------------------------------------------------------// : BezierSpline End Point Start
// Point .
//--------------------------------------------------------------------------void CBezierSpline::SetP3(CPoint ptP3)
{
m_ptP3 = ptP3;
}

//--------------------------------------------------------------------------// : BezierSpline End Point Start


// Point .
//--------------------------------------------------------------------------CPoint CBezierSpline::GetP3()
{
return m_ptP3;
}
//--------------------------------------------------------------------------// : BezierSpline End Point End
// Point .
//--------------------------------------------------------------------------void CBezierSpline::SetP4(CPoint ptP4)
{
m_ptP4 = ptP4;
}
//--------------------------------------------------------------------------// : BezierSpline End Point
// End Point .
//--------------------------------------------------------------------------CPoint CBezierSpline::GetP4()
{
return m_ptP4;
}

120

GDI+ Example
//--------------------------------------------------------------------------// : Bezier Spline Control Point .
//--------------------------------------------------------------------------void CBezierSpline::DrawControl(CDC *pDC)
{
//----------------------------------------------------------------------// Start , End Point Control Point .
//----------------------------------------------------------------------CPen penNew(PS_DOT, 1 , RGB(128,128,128));

ptControl = m_ptP3 - CSize(3,3);


m_imglistPoint.Draw( pDC , 1 , ptControl ,
ILD_TRANSPARENT|ILD_NORMAL);
ptControl = m_ptP4 - CSize(3,3);
m_imglistPoint.Draw( pDC , 0 , ptControl ,
ILD_TRANSPARENT|ILD_NORMAL);
//----------------------------------------------------------------------// Control Point .
//----------------------------------------------------------------------if( m_pSelectedPoint != NULL )
{
ptControl = *m_pSelectedPoint - CSize(3,3);

CPen * pOldPen = pDC->SelectObject(&penNew);


pDC->MoveTo( m_ptP1 );
pDC->LineTo( m_ptP2 );
pDC->MoveTo( m_ptP3 );
pDC->LineTo( m_ptP4 );
pDC->SelectObject(pOldPen);

m_imglistPoint.Draw( pDC , 2 , ptControl ,


ILD_TRANSPARENT|ILD_NORMAL);

//----------------------------------------------------------------------// Start , End Point , Control Point Control Point .


//----------------------------------------------------------------------//----------------------------------------------------------------------// Control Point .
//----------------------------------------------------------------------CPoint ptControl;
ptControl = m_ptP1 - CSize(3,3);
m_imglistPoint.Draw( pDC , 0 , ptControl ,
ILD_TRANSPARENT|ILD_NORMAL);
ptControl = m_ptP2 - CSize(3,3);
m_imglistPoint.Draw( pDC , 1 , ptControl ,
ILD_TRANSPARENT|ILD_NORMAL);

121

GDI+ Example
//--------------------------------------------------------------------------// : Bezier Spline .
//--------------------------------------------------------------------------// : nLineWidth : Line
//
clrLine : Line
//--------------------------------------------------------------------------void CBezierSpline::Draw(CDC * pDC , int nLineWidth ,
COLORREF clrLine, bool bAntialiasing )
{
if( m_ptP1 == CPoint(-1,-1) || m_ptP4 == CPoint(-1,-1) )
return;
//---------------------------------------------------------------------// Control Line .
//---------------------------------------------------------------------DrawControl( pDC );

//--------------------------------------------------------------------------// : Bezier Spline .


//--------------------------------------------------------------------------// : nLineWidth : Line
//
clrLine : Line
//--------------------------------------------------------------------------void CBezierSpline::DrawSpline(Graphics* pGraphics , int nLineWidth ,
COLORREF clrLine, bool bAntialiasing)
{
Point ptControls[4];
ptControls[0].X = m_ptP1.x; ptControls[0].Y = m_ptP1.y;
ptControls[1].X = m_ptP2.x; ptControls[1].Y = m_ptP2.y;
ptControls[2].X = m_ptP3.x; ptControls[2].Y = m_ptP3.y;
ptControls[3].X = m_ptP4.x; ptControls[3].Y = m_ptP4.y;
//----------------------------------------------------------------------// GDI+ Point .
//----------------------------------------------------------------------Color colorLine;
colorLine.SetFromCOLORREF(clrLine);
//----------------------------------------------------------------------// .
//----------------------------------------------------------------------Pen penNew( colorLine , nLineWidth );
//----------------------------------------------------------------------// Antialiasing .
//----------------------------------------------------------------------SmoothingMode modeOld = pGraphics->GetSmoothingMode();

//---------------------------------------------------------------------// Spline .
//---------------------------------------------------------------------DrawSpline( pDC , nLineWidth , clrLine , bAntialiasing);

//--------------------------------------------------------------------------// : Bezier Spline .


//--------------------------------------------------------------------------// : nLineWidth : Line
//
clrLine : Line
//--------------------------------------------------------------------------void CBezierSpline::DrawSpline(CDC * pDC, int nLineWidth ,
COLORREF clrLine, bool bAntialiasing)
{
Graphics graphics(pDC->GetSafeHdc());
DrawSpline( &graphics , nLineWidth , clrLine , bAntialiasing);
}

if( bAntialiasing )
pGraphics->SetSmoothingMode(SmoothingModeAntiAlias);

pGraphics->DrawBeziers( &penNew, ptControls , 4 );


pGraphics->SetSmoothingMode(modeOld);

122

GDI+ Example
//--------------------------------------------------------------------------// : Control Point .
//--------------------------------------------------------------------------CPoint* CBezierSpline::GetSelectedPoint()
{
return m_pSelectedPoint;
}

rcControl = CRect( m_ptP3 - CSize(3,3) , m_ptP3 + CSize(3,3) );


if( rcControl.PtInRect(ptPos) )
{
m_pSelectedPoint = &m_ptP3;
return true;
}

//--------------------------------------------------------------------------//
: Control Point
.

rcControl = CRect( m_ptP4 - CSize(3,3) , m_ptP4 + CSize(3,3) );

//--------------------------------------------------------------------------bool CBezierSpline::PtInControlPoint(CPoint ptPos)


{
//----------------------------------------------------------------------// Control Point .
//----------------------------------------------------------------------m_pSelectedPoint = NULL;
//----------------------------------------------------------------------// Control Point .
//----------------------------------------------------------------------CRect rcControl = CRect( m_ptP1 - CSize(3,3) , m_ptP1 +
CSize(3,3) );

if( rcControl.PtInRect(ptPos) )
{
m_pSelectedPoint = &m_ptP4;
return true;
}
}

return false;

if( rcControl.PtInRect(ptPos) )
{
m_pSelectedPoint = &m_ptP1;
return true;
}
rcControl = CRect( m_ptP2 - CSize(3,3) , m_ptP2 + CSize(3,3) );
if( rcControl.PtInRect(ptPos) )
{
m_pSelectedPoint = &m_ptP2;
return true;
}

123

GDI+ Example
//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : pWnd :
//--------------------------------------------------------------------------// : LButtonDown .
//--------------------------------------------------------------------------bool CBezierSpline::LButtonDown(CWnd* pWnd , UINT nFlags,
CPoint point, bool bControlMode)
{
//----------------------------------------------------------------------// bControlMode == true Control Point
// .
//----------------------------------------------------------------------if( bControlMode )
{
if( PtInControlPoint(point) )
{
pWnd->SetCapture();
m_ptStart = m_ptEnd = point;
return true;
}
}
else
{
SetP1(point);
SetP4(point);

}
}

//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : pWnd :
//--------------------------------------------------------------------------// : LButtonUp .
//--------------------------------------------------------------------------bool CBezierSpline::LButtonUp(CWnd * pWnd, UINT nFlags,
CPoint point, bool bControlMode)
{
//----------------------------------------------------------------------// bControlMode == true Control Point .
//----------------------------------------------------------------------if( bControlMode )
{
if( m_pSelectedPoint != NULL )
{
if( pWnd == CWnd::GetCapture() )
{
*m_pSelectedPoint += (m_ptEnd - m_ptStart);
if( m_ptP1 == *m_pSelectedPoint )
{
m_ptP2 += (m_ptEnd - m_ptStart);
}
if( m_ptP4 == *m_pSelectedPoint )
{
m_ptP3 += (m_ptEnd - m_ptStart);
}

ComputeControlPos();
pWnd->SetCapture();
return true;

ReleaseCapture();
return true;

return false;
}

124

GDI+ Example
else
{

*m_pSelectedPoint += (m_ptEnd - m_ptStart);


if( pWnd == CWnd::GetCapture() )
{
SetP4(point);
ComputeControlPos();
ReleaseCapture();
}

if( m_ptP1 == *m_pSelectedPoint )


{
m_ptP2 += (m_ptEnd - m_ptStart);
}
if( m_ptP4 == *m_pSelectedPoint )
{
m_ptP3 += (m_ptEnd - m_ptStart);
}

return true;

}
}

return false;

//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : pWnd :
//--------------------------------------------------------------------------// : MouseMove .
//--------------------------------------------------------------------------bool CBezierSpline::MouseMove(CWnd * pWnd, UINT nFlags,
CPoint point, bool bControlMode)
{
//----------------------------------------------------------------------// bControlMode == true Control Point
// .
//----------------------------------------------------------------------if( bControlMode )
{
if( m_pSelectedPoint != NULL )
{
if( pWnd == CWnd::GetCapture() )
{
m_ptEnd = point;

m_ptStart = m_ptEnd;
return true;
}
else
{

if( pWnd == CWnd::GetCapture() )


{
SetP4(point);
ComputeControlPos();
return true;
}

}
}

return false;

125

GDI+ Example
//--------------------------------------------------------------------------// : Bezier Spline .
//--------------------------------------------------------------------------CRect CBezierSpline::GetBoundBox()
{
int X[4] , Y[4];
X[0] = m_ptP1.x; X[1] = m_ptP2.x; X[2] = m_ptP3.x;
X[3] = m_ptP4.x;
Y[0] = m_ptP1.y; Y[1] = m_ptP2.y; Y[2] = m_ptP3.y;
Y[3] = m_ptP4.y;
qsort(( void*)X , 4 , sizeof(int) , CompareInt);
qsort(( void*)Y , 4 , sizeof(int) , CompareInt);
CRect rcBox( X[0] , Y[0] , X[3] , Y[3] );
rcBox.NormalizeRect();
rcBox.InflateRect( 10 , 10 , 10 , 10 );
return rcBox;
}
//--------------------------------------------------------------------------//
: Bezier Spline P2 , P3 Control Point
//
.
//--------------------------------------------------------------------------// : dRate : ..
//--------------------------------------------------------------------------void CBezierSpline::ComputeControlPos(double dRate)
{
//----------------------------------------------------------------------// P1 , P4 .
//----------------------------------------------------------------------CPoint ptCenter;

ptCenter.x = int((m_ptP1.x + m_ptP4.x)/2.0 +0.5);


ptCenter.y = int((m_ptP1.y + m_ptP4.y)/2.0 +0.5);
//----------------------------------------------------------------------// P1 , P4 .
//----------------------------------------------------------------------CLineEquation lineA( m_ptP1 , m_ptP4 );
//----------------------------------------------------------------------// P1 , P4 .
//----------------------------------------------------------------------CLineEquation lineP;
lineP.ComputePerpendicularLine( lineA , ptCenter );
//----------------------------------------------------------------------// P1 , P4 .
//----------------------------------------------------------------------// P1 , P4 .
//----------------------------------------------------------------------double dLength = sqrt( pow(m_ptP1.x - m_ptP4.x, 2.0)
+ pow(m_ptP1.y - m_ptP4.y , 2.0 ) ) * sqrt(3) / 2.0;
//----------------------------------------------------------------------// Y .
//----------------------------------------------------------------------CPoint * pPoints = lineP.ComputeLengthPoint( ptCenter , dLength );
CPoint ptP5 = pPoints[0].y < pPoints[1].y ? pPoints[0] : pPoints[1];
delete[] pPoints;

126

GDI+ Example
//----------------------------------------------------------------------// P1, P5 P4, P5 .
//----------------------------------------------------------------------CLineEquation lineB( m_ptP1 , ptP5 );
CLineEquation lineC( m_ptP4 , ptP5 );
//----------------------------------------------------------------------// Y P2 , P3 .
//----------------------------------------------------------------------pPoints = lineB.ComputeLengthPoint( m_ptP1 , dLength*dRate );
m_ptP2 = pPoints[0].y < pPoints[1].y ? pPoints[0] : pPoints[1];
delete[] pPoints;
pPoints = lineC.ComputeLengthPoint( m_ptP4 , dLength*dRate );
m_ptP3 = pPoints[0].y < pPoints[1].y ? pPoints[0] : pPoints[1];
}

delete[] pPoints;

127

GDI+ Example
CLineEquation Class

Bezier Spline .

class CLineEquation
{
public:
CLineEquation();
CLineEquation(CPoint ptP1 , CPoint ptP2);
CLineEquation(double dSlop , CPoint ptP);
virtual ~CLineEquation();

public:
void ComputeLineEquation( CPoint ptP1 , CPoint ptP2 );
void ComputeLineEquation( double dSlop , CPoint ptP );
public:
void ComputePerpendicularLine( CLineEquation& lineA , CPoint ptP);
void ComputeDivideLine( CLineEquation lineA, CLineEquation lineB);
CPoint* ComputeLengthPoint(CPoint ptPos , double dLength);

private:
double m_dA;
double m_dB;
double m_dC;

public:
static CPoint ComputeCrossPoint(CLineEquation& lineA , CLineEquation lineB);

public:
void SetA(double dA);
void SetB(double dB);
void SetC(double dC);

public:
CPoint GetXPos( int nY);
CPoint GetYPos( int nX);
};

double GetA();
double GetB();
double GetC();

128

GDI+ Example
CLineEquation::CLineEquation()
{
m_dA = m_dB = m_dC = 0;
}
//-------------------------------------------------------------------------// : .
//-------------------------------------------------------------------------// : ptP1 , ptP2 :
//-------------------------------------------------------------------------CLineEquation::CLineEquation(CPoint ptP1 , CPoint ptP2)
{
ComputeLineEquation(ptP1 , ptP2);
}
//-------------------------------------------------------------------------// : .
//-------------------------------------------------------------------------// : dSlop :
ptP :
//-------------------------------------------------------------------------CLineEquation::CLineEquation(double dSlop , CPoint ptP)
{
ComputeLineEquation(dSlop , ptP);
}
CLineEquation::~CLineEquation()
{
}
//--------------------------------------------------------------------------// : ax + by + c = 0 a
//--------------------------------------------------------------------------double CLineEquation::GetA()
{
return m_dA;
}

//--------------------------------------------------------------------------// : ax + by + c = 0 b
//--------------------------------------------------------------------------double CLineEquation::GetB()
{
return m_dB;
}
//--------------------------------------------------------------------------// : ax + by + c = 0 c
//--------------------------------------------------------------------------double CLineEquation::GetC()
{
return m_dC;
}
//--------------------------------------------------------------------------// : ax + by + c = 0 a
//--------------------------------------------------------------------------void CLineEquation::SetA(double dA)
{
m_dA = dA;
}
//--------------------------------------------------------------------------// : ax + by + c = 0 b
//--------------------------------------------------------------------------void CLineEquation::SetB(double dB)
{
m_dB = dB;
}
//--------------------------------------------------------------------------// : ax + by + c = 0 c
//--------------------------------------------------------------------------void CLineEquation::SetC(double dC)
{
m_dC = dC;
}

129

GDI+ Example
//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : ptP1 , ptP2 :
//--------------------------------------------------------------------------// : (y1-y2)x + (x2-x1)y + x1y2 - x2y1 = 0
//--------------------------------------------------------------------------void CLineEquation::ComputeLineEquation(CPoint ptP1, CPoint ptP2)
{
m_dA = ptP1.y - ptP2.y;
m_dB = ptP2.x - ptP1.x;
m_dC = ptP1.x*ptP2.y - ptP2.x*ptP1.y;
double dNorm = sqrt(m_dA*m_dA + m_dB*m_dB);
m_dA /= dNorm;
m_dB /= dNorm;
m_dC /= dNorm;
}
//--------------------------------------------------------------------------// :
//
.
//--------------------------------------------------------------------------// : dSlop :
//
ptP :
//--------------------------------------------------------------------------// : -mx + y - b = 0 b .
//--------------------------------------------------------------------------void CLineEquation::ComputeLineEquation(double dSlop, CPoint ptP)
{
m_dA = -dSlop;
m_dB = 1;
}

m_dC = -dSlop* ptP.x + ptP.y;

//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : : ax + by + c = 0
//
: dx + ey + f = 0
//--------------------------------------------------------------------------CPoint CLineEquation::ComputeCrossPoint(CLineEquation &lineA,
CLineEquation lineB)
{
CPoint ptCross;
double a = lineA.GetA() , b = lineA.GetB() , c = lineA.GetC();
double d = lineB.GetA() , e = lineB.GetB() , f = lineB.GetC();
if( (( d*b - a*e ) == 0.0 ) || ( a == 0.0 && d == 0.0 ) ||
( b == 0.0 && e == 0.0 ))
{
return CPoint(-1,-1);
}
//----------------------------------------------------------------------// a d b e 0 .
//----------------------------------------------------------------------if( a == 0 )
{
ptCross.y = -1 * c / b;
ptCross.x = (-1*e*ptCross.y - f)/d;
return ptCross;
}else if( b == 0 )
{
ptCross.x = -1 * c / a;
ptCross.y = (-1*d*ptCross.x - f)/e;
}

return ptCross;

130

GDI+ Example
if( d == 0 )
{
ptCross.y = -1 * f / e;
ptCross.x = (-1*b*ptCross.y - c)/a;
return ptCross;
}else if( e == 0 )
{
ptCross.x = -1 * f / d;
ptCross.y = (-1*a*ptCross.x - c)/b;
return ptCross;

//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : lineA :
//
ptP : .
//--------------------------------------------------------------------------void CLineEquation::ComputePerpendicularLine(CLineEquation &lineA,
CPoint ptP)
{
//----------------------------------------------------------------------// lineA .
//----------------------------------------------------------------------double l = lineA.GetB();
double m = -lineA.GetA();

//----------------------------------------------------------------------// .
//----------------------------------------------------------------------double vl = -1*m;
double vm = l;

//----------------------------------------------------------------------// a,b,c,d,e,f 0
//----------------------------------------------------------------------ptCross.x = ( e*c - b*f ) / ( d*b - a*e );
ptCross.y = ( -1*a*ptCross.x - c )/b;
}

return ptCross;

//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : : ax + by + c = 0
//
: dx + ey + f = 0
//--------------------------------------------------------------------------void CLineEquation::ComputeDivideLine(CLineEquation lineA,
CLineEquation lineB)
{
}

//----------------------------------------------------------------------//
// .
//----------------------------------------------------------------------m_dA = vm;
m_dB = -vl;
m_dC = -vm*ptP.x + vl*ptP.y;

131

GDI+ Example
//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : nX : X ..
//--------------------------------------------------------------------------CPoint CLineEquation::GetYPos(int nX)
{
//----------------------------------------------------------------------// Y .
//----------------------------------------------------------------------if( m_dB == 0 )
return CPoint( int(-1*m_dC/m_dA) , 0 );
int nY = (int)( -1*(m_dC + m_dA*nX)/m_dB );
}

return CPoint( nX , nY );

//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : nY : Y ..
//--------------------------------------------------------------------------CPoint CLineEquation::GetXPos(int nY)
{
//----------------------------------------------------------------------// x .
//----------------------------------------------------------------------if( m_dA == 0 )
return CPoint( int(-1*m_dC/m_dB) , 0 );

//--------------------------------------------------------------------------// : .
//--------------------------------------------------------------------------// : ptPos : ..
(x1, y1 )
//
nLength :
//--------------------------------------------------------------------------// : dx + ey + f = 0
( m , n )
//
1....... n = -d/e*m - f/e
//
2....... (x1-m)^2 + (y1-n)^2 = L^2
//
3....... am^2 + bm + c = 0 m .
//
//
k = d/e l = f/e + y1
//
a = 1+k^2 b = 2(kl - x1) c = l^2 - L^2
//--------------------------------------------------------------------------// :
//
.
//--------------------------------------------------------------------------CPoint* CLineEquation::ComputeLengthPoint(CPoint ptPos, double dLength)
{
CPoint * pPoints = new CPoint[2];
//----------------------------------------------------------------------// x .
//----------------------------------------------------------------------if( m_dA == 0 )
{
pPoints[0].y = pPoints[1].y = ptPos.y;
pPoints[0].x = int(ptPos.x + dLength);
pPoints[1].x = int(ptPos.x - dLength);

int nX = (int)( -1*(m_dC + m_dB*nY)/m_dA );


}

return CPoint( nX , nY );

return pPoints;
}

132

GDI+ Example
//----------------------------------------------------------------------// y .
//----------------------------------------------------------------------if( m_dB == 0 )
{
pPoints[0].x = pPoints[1].x = ptPos.x;
pPoints[0].y = int(ptPos.y + dLength);
pPoints[1].y = int(ptPos.y - dLength);
return pPoints;
}
//----------------------------------------------------------------------// .. . dx + ey + f = 0
//----------------------------------------------------------------------double k = m_dA/m_dB;
double l = m_dC/m_dB + ptPos.y;
double a = 1+k*k;
double b = 2*(k*l - ptPos.x);
double c = ptPos.x*ptPos.x + l*l - dLength*dLength;
//----------------------------------------------------------------------// .
//----------------------------------------------------------------------double dX = (-1*b+sqrt(b*b - 4*a*c))/(2.0*a);
pPoints[0].x = (int)( dX );
pPoints[0].y = (int)( -1*(m_dC + m_dA*dX)/m_dB );
dX = (-1*b-sqrt(b*b - 4*a*c))/(2.0*a);
pPoints[1].x = (int)( dX );
pPoints[1].y = (int)( -1*(m_dC + m_dA*dX)/m_dB );
}

return pPoints;

133

GDI+ Example
CBezierView Class

Bezier Spline View

void CBezierView::OnDraw(CDC* pDC)


{
CBezierDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here

else
{

//---------------------------------------------------------------------// Cliping .
//---------------------------------------------------------------------CRect rcClipBox;
pDC->GetClipBox(rcClipBox);
}

if( bResult )
{
//-------------------------------------------------------------// Spline .
//-------------------------------------------------------------CClientDC dc(this);

Draw( pDC , rcClipBox );

CRect rcClipBox;
rcClipBox.UnionRect( rcOldBoundBox ,
m_splineBezier.GetBoundBox() );

void CBezierView::OnLButtonDown(UINT nFlags, CPoint point)


{
bool bResult;
CRect rcOldBoundBox = m_splineBezier.GetBoundBox();
if( m_nMode == ID_BEZIER_SPLINE_DRAW )
{
bResult =
m_splineBezier.LButtonDown( this , nFlags , point );
}

bResult =
m_splineBezier.LButtonDown( this , nFlags ,
point , true );

Draw( &dc , rcClipBox );

CView::OnLButtonDown(nFlags, point);
}

134

GDI+ Example
void CBezierView::OnMouseMove(UINT nFlags, CPoint point)
{
bool bResult;
CRect rcOldBoundBox = m_splineBezier.GetBoundBox();

CRect rcOldBoundBox = m_splineBezier.GetBoundBox();

if( m_nMode == ID_BEZIER_SPLINE_DRAW )


{
bResult =
m_splineBezier.MouseMove( this , nFlags , point );
}
else
{
bResult =
m_splineBezier.MouseMove( this , nFlags , point ,
true );
}

if( m_nMode == ID_BEZIER_SPLINE_DRAW )


{
bResult =
m_splineBezier.LButtonUp( this , nFlags , point );
}
else
{
bResult =
m_splineBezier.LButtonUp( this , nFlags , point , true );
}

if( bResult )
{
//-------------------------------------------------------------// Spline .
//-------------------------------------------------------------CClientDC dc(this);

if( bResult )
{
//-------------------------------------------------------------// Spline .
//-------------------------------------------------------------CClientDC dc(this);

CRect rcClipBox;
rcClipBox.UnionRect( rcOldBoundBox ,
m_splineBezier.GetBoundBox() );

CRect rcClipBox;
rcClipBox.UnionRect( rcOldBoundBox ,
m_splineBezier.GetBoundBox() );

}
}

void CBezierView::OnLButtonUp(UINT nFlags, CPoint point)


{
bool bResult;

Draw( &dc , rcClipBox );

Draw( &dc , rcClipBox );

CView::OnMouseMove(nFlags, point);

}
}

CView::OnLButtonUp(nFlags, point);

135

GDI+ Example
void CBezierView::OnBezierSplineDraw()
{
m_nMode = ID_BEZIER_SPLINE_DRAW;
}
void CBezierView::OnUpdateBezierSplineDraw(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck( m_nMode ==
ID_BEZIER_SPLINE_DRAW );
}

void CBezierView::Draw(CDC *pDC, CRect rcClipBox)


{
//---------------------------------------------------------------------// .
//---------------------------------------------------------------------CRect rcClient;
GetClientRect( rcClient );
//---------------------------------------------------------------------//
. Memory Device Context
//---------------------------------------------------------------------CDC dcMem;
dcMem.CreateCompatibleDC(pDC);

void CBezierView::OnBezierSplineControl()
{
m_nMode = ID_BEZIER_SPLINE_CONTROL;
}

CBitmap bmMem;
bmMem.CreateCompatibleBitmap(pDC, rcClient.Width() ,
rcClient.Height() );

void CBezierView::OnUpdateBezierSplineControl(CCmdUI* pCmdUI)


{
pCmdUI->SetCheck( m_nMode ==
ID_BEZIER_SPLINE_CONTROL );
}

CBitmap* pOldBitmap = (CBitmap *)dcMem.SelectObject(&bmMem);


dcMem.FillRect( rcClient , &CBrush(RGB(255,255,255)));
//--------------------------------------------------------------------// Bezier Spline Memory DC .
//--------------------------------------------------------------------m_splineBezier.Draw( &dcMem );
pDC->StretchBlt( rcClipBox.left, rcClipBox.top , rcClipBox.Width() ,
rcClipBox.Height() , &dcMem , rcClipBox.left,
rcClipBox.top , rcClipBox.Width() ,
rcClipBox.Height() , SRCCOPY );
dcMem.SelectObject( pOldBitmap );
}

136

You might also like