Click here to Skip to main content
15,884,099 members
Articles / Desktop Programming / MFC

GDI+ Plot ActiveX Control

Rate me:
Please Sign up or sign in to vote.
4.89/5 (10 votes)
5 Sep 2013LGPL32 min read 90.8K   12.1K   65  
GDI+ 2D plot ActiveX control
/**************************************************************************\
* 
* Copyright (c) 1998-2000, Microsoft Corp.  All Rights Reserved.
*
* Module Name:
*
*   GdiplusMatrix.h
*
* Abstract:
*
*   GDI+ Matrix class
*
\**************************************************************************/

class Matrix : public GdiplusBase
{
public:
    friend class Graphics;
    friend class GraphicsPath;
    friend class TextureBrush;
    friend class LinearGradientBrush;
    friend class PathGradientBrush;
    friend class Pen;
    friend class Region;
    
    // Default constructor - set to identity matrix

    Matrix()
    {
        GpMatrix *matrix = NULL;

        lastResult = DllExports::GdipCreateMatrix(&matrix);
    
        SetNativeMatrix(matrix);
    }

    Matrix(IN REAL m11, 
           IN REAL m12,
           IN REAL m21, 
           IN REAL m22,
           IN REAL dx, 
           IN REAL dy)
    {
        GpMatrix *matrix = NULL;

        lastResult = DllExports::GdipCreateMatrix2(m11, m12, m21, m22, 
                                                      dx, dy, &matrix);
    
        SetNativeMatrix(matrix);
    }
    
    Matrix(IN const RectF& rect, 
           IN const PointF* dstplg)
    {
        GpMatrix *matrix = NULL;

        lastResult = DllExports::GdipCreateMatrix3(&rect, 
                                                   dstplg,
                                                   &matrix);

        SetNativeMatrix(matrix);
    }

    Matrix(IN const Rect& rect, 
           IN const Point* dstplg)
    {
        GpMatrix *matrix = NULL;

        lastResult = DllExports::GdipCreateMatrix3I(&rect, 
                                                    dstplg,
                                                    &matrix);

        SetNativeMatrix(matrix);
    }

    ~Matrix()
    {
        DllExports::GdipDeleteMatrix(nativeMatrix);
    }

    Matrix *Clone() const
    {
        GpMatrix *cloneMatrix = NULL;

        SetStatus(DllExports::GdipCloneMatrix(nativeMatrix,
                                                  &cloneMatrix));

        if (lastResult != Ok)
            return NULL;

        return new Matrix(cloneMatrix);
    }

    Status GetElements(OUT REAL *m) const 
    {
        return SetStatus(DllExports::GdipGetMatrixElements(nativeMatrix, m));
    }
    
    Status SetElements(IN REAL m11, 
                       IN REAL m12, 
                       IN REAL m21, 
                       IN REAL m22, 
                       IN REAL dx, 
                       IN REAL dy)
    {
        return SetStatus(DllExports::GdipSetMatrixElements(nativeMatrix,
                            m11, m12, m21, m22, dx, dy));
    }

    REAL OffsetX() const
    {
        REAL elements[6];

        if (GetElements(&elements[0]) == Ok)
            return elements[4];
        else 
            return 0.0f;
    }

    REAL OffsetY() const
    {
       REAL elements[6];

       if (GetElements(&elements[0]) == Ok)
           return elements[5];
       else 
           return 0.0f;
    }

    Status Reset()
    {
        // set identity matrix elements 
        return SetStatus(DllExports::GdipSetMatrixElements(nativeMatrix,
                                             1.0, 0.0, 0.0, 1.0, 0.0, 0.0));
    }

    Status Multiply(IN const Matrix *matrix, 
                    IN MatrixOrder order = MatrixOrderPrepend)
    {
        return SetStatus(DllExports::GdipMultiplyMatrix(nativeMatrix, 
                                          matrix->nativeMatrix,
                                          order));
    }

    Status Translate(IN REAL offsetX, 
                     IN REAL offsetY, 
                     IN MatrixOrder order = MatrixOrderPrepend)
    {
        return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, offsetX, offsetY, order));
    }

    Status Scale(IN REAL scaleX, 
                 IN REAL scaleY, 
                 IN MatrixOrder order = MatrixOrderPrepend)
    {
        return SetStatus(DllExports::GdipScaleMatrix(nativeMatrix, scaleX, scaleY, order));
    }

    Status Rotate(IN REAL angle, 
                  IN MatrixOrder order = MatrixOrderPrepend)
    {
        return SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order));
    }
    
    Status RotateAt(IN REAL angle, 
                    IN const PointF& center, 
                    IN MatrixOrder order = MatrixOrderPrepend)
    {
        if(order == MatrixOrderPrepend)
        {
            SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, center.X, center.Y, order));
            SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order));
            return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, - center.X, - center.Y, order));
        }
        else
        {
            SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, - center.X, - center.Y, order));
            SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order));
            return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, center.X, center.Y, order));
        }
    }

    Status Shear(IN REAL shearX, 
                 IN REAL shearY,
                 IN MatrixOrder order = MatrixOrderPrepend)
    {
        return SetStatus(DllExports::GdipShearMatrix(nativeMatrix, shearX, shearY, order));
    }

    Status Invert()
    {
        return SetStatus(DllExports::GdipInvertMatrix(nativeMatrix));
    }

    // float version
    Status TransformPoints(IN OUT PointF* pts, 
                           IN INT count = 1) const
    {
        return SetStatus(DllExports::GdipTransformMatrixPoints(nativeMatrix, pts, count));
    }
    
    Status TransformPoints(IN OUT Point* pts, 
                           IN INT count = 1) const
    {
        return SetStatus(DllExports::GdipTransformMatrixPointsI(nativeMatrix, 
                                                                pts, 
                                                                count));
    }

    Status TransformVectors(IN OUT PointF* pts, 
                            IN INT count = 1) const
    { 
        return SetStatus(DllExports::GdipVectorTransformMatrixPoints(nativeMatrix, pts, count));
    }

    Status TransformVectors(IN OUT Point* pts, 
                            IN INT count = 1) const
    { 
       return SetStatus(DllExports::GdipVectorTransformMatrixPointsI(nativeMatrix, 
                                                                    pts, 
                                                                    count));
    }
    
    BOOL IsInvertible() const
    {
        BOOL result = FALSE;

        SetStatus(DllExports::GdipIsMatrixInvertible(nativeMatrix, &result));
    
        return result;
    }

    BOOL IsIdentity() const
    {
       BOOL result = FALSE;

       SetStatus(DllExports::GdipIsMatrixIdentity(nativeMatrix, &result));
    
       return result;
    }

    BOOL Equals(IN const Matrix *matrix) const
    {
       BOOL result = FALSE;

       SetStatus(DllExports::GdipIsMatrixEqual(nativeMatrix,
                                                 matrix->nativeMatrix, &result));
   
       return result;
    }
    
    Status GetLastStatus() const
    {
        Status lastStatus = lastResult;
        lastResult = Ok;
 
        return lastStatus;
    }

protected:

#ifdef DCR_USE_NEW_250932

private:
    Matrix(const Matrix &);
    Matrix& operator=(const Matrix &);
protected:

#else

    Matrix(const Matrix& matrix)
    {
        matrix;
        SetStatus(NotImplemented);
        SetNativeMatrix(NULL);
    }

    Matrix& operator=(const Matrix& matrix)
    {
        matrix;
        SetStatus(NotImplemented);
        return *this;
    }

#endif

    Matrix(GpMatrix *nativeMatrix)
    {
        lastResult = Ok;
        SetNativeMatrix(nativeMatrix);
    }
    
    VOID SetNativeMatrix(GpMatrix *nativeMatrix)
    {
        this->nativeMatrix = nativeMatrix;
    }

    Status SetStatus(Status status) const
    {
        if (status != Ok)
            return (lastResult = status);
        else
            return status;
    }

protected:
    GpMatrix *nativeMatrix;
    mutable Status lastResult;
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Engineer
China China
An individual human existence should be like a river - small at first, narrowly contained within its banks, and rushing passionately past boulders and over waterfalls. Gradually the river grows wider, the banks recede, the waters flow more quietly, and in the end, without any visible break, they become merged in the sea, and painlessly lose their individual being.

Comments and Discussions