2 thoughts on “TDirect2DCanvas”

  1. That is very nice, but I tried to use TDirect2DCanvas as a replacement for TCanvas in some custom components, and it didn’t work very well. I tried to make it work together with a GDI based canvas so I could see my components in Design Time (TDirect2DCanvas based components seem to have a problem with Design Time). Could you give a look at my code and see what I’m doing wrong?

    D2DPanel.h:

    #ifndef D2DPanelH
    #define D2DPanelH
    #include
    #include
    #include
    #include
    #include

    class PACKAGE TD2DPanel : public TCustomPanel
    {
    private:
    bool FUseD2D;
    bool FAccelerated;
    bool FJustConstructed;

    bool __fastcall CreateD2DCanvas ();

    void __fastcall SetAccelerated (bool val)
    {
    FAccelerated = val;
    }

    protected:
    TDirect2DCanvas * FD2DCanvas;

    void __fastcall D2DDrawSolidRectangle (int width, int height, const TColor & color);

    inline void SetD2DCanvasFont (TDirect2DFont * d2dfont, TFont * font)
    {
    if (!TD2DPanel::FD2DCanvas)
    return;

    if (!d2dfont || !font)
    return;

    d2dfont->Color = font->Color;
    d2dfont->Height = font->Height;
    d2dfont->Size = font->Size;
    d2dfont->Style = font->Style;
    d2dfont->Pitch = font->Pitch;
    d2dfont->Orientation = font->Orientation;
    d2dfont->Name = font->Name;
    d2dfont->PixelsPerInch = font->PixelsPerInch;
    //d2dfont->Handle = (_di_IDWriteTextFormat) (font->Handle);
    }

    void __fastcall WMSize (TWMSize & Message);

    BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER (WM_SIZE, TWMSize, WMSize);
    END_MESSAGE_MAP (TCustomPanel)

    void __fastcall Paint ();

    virtual void __fastcall D2DPaint ();

    virtual void __fastcall GDIPaint ();

    DYNAMIC void __fastcall Resize ();

    public:
    bool __fastcall Use2D ();

    __fastcall TD2DPanel(TComponent* Owner);

    __fastcall ~TD2DPanel ();

    __published:
    __property bool Accelerated = {read = FAccelerated,
    write = SetAccelerated};

    __property BorderWidth;
    };
    #endif

    D2DPanel.cpp:

    //—————————————————————————

    #include

    #pragma hdrstop

    #include “D2DPanel.h”
    #pragma package(smart_init)
    //—————————————————————————
    // ValidCtrCheck is used to assure that the components created do not have
    // any pure virtual functions.
    //

    static inline void ValidCtrCheck(TD2DPanel *)
    {
    new TD2DPanel(NULL);
    }
    //—————————————————————————
    __fastcall TD2DPanel::TD2DPanel(TComponent* Owner)
    : TCustomPanel (Owner)
    {
    FJustConstructed = true;
    }
    //—————————————————————————
    namespace D2dpanel
    {
    void __fastcall PACKAGE Register()
    {
    TComponentClass classes[1] = {__classid(TD2DPanel)};
    RegisterComponents(L”Opto”, classes, 0);
    }
    }
    //—————————————————————————

    __fastcall TD2DPanel::~TD2DPanel ()
    {
    if (FD2DCanvas)
    FD2DCanvas->Free ();
    }

    void __fastcall TD2DPanel::WMSize (TWMSize & Message)
    {
    if (FUseD2D)
    {
    if (!this->ComponentState.Contains (csDesigning))
    {
    _di_ID2D1HwndRenderTarget HwndTarget;

    if (FD2DCanvas)
    {
    HwndTarget = FD2DCanvas->RenderTarget;
    if (HwndTarget)
    HwndTarget->Resize (D2D1SizeU (ClientWidth, ClientHeight));
    }
    }
    }
    else
    TWinControl::Dispatch (&Message);
    }

    bool __fastcall TD2DPanel::CreateD2DCanvas ()
    {
    if (FD2DCanvas)
    FD2DCanvas->Free ();

    FD2DCanvas = new TDirect2DCanvas (Handle);

    if (!FD2DCanvas->Supported ())
    return false;

    return true;
    }

    void __fastcall TD2DPanel::Paint ()
    {
    if (FUseD2D)
    D2DPaint ();
    else
    GDIPaint ();
    }

    void __fastcall TD2DPanel::D2DPaint ()
    {
    D2DDrawSolidRectangle (Width, Height, Color);
    }

    void __fastcall TD2DPanel::GDIPaint ()
    {
    Canvas->Brush->Color = Color;
    Canvas->Brush->Style = bsSolid;
    Canvas->Pen->Color = Color;
    Canvas->Rectangle (0, 0, Width, Height);
    }

    void __fastcall TD2DPanel::Resize ()
    {
    /* AfterConstruction won’t work – workaroung */
    if (FJustConstructed)
    {
    if ((Win32MajorVersion >= 6)
    && (Win32Platform == VER_PLATFORM_WIN32_NT)
    && (!this->ComponentState.Contains (csDesigning))
    && (Accelerated))
    FUseD2D = CreateD2DCanvas ();
    else
    FUseD2D = false;

    FJustConstructed = false;
    }

    TWinControl::Resize ();

    if (FUseD2D)
    FD2DCanvas->Refresh ();
    }

    bool __fastcall TD2DPanel::Use2D ()
    {
    if (FUseD2D)
    return true;
    else
    return false;
    }

  2. It looks fine but maybe you should setup FUseD2D already at the constructor to make sure that no paint events is executed before the resize event, because FUseD2D is initialized in resize().

Leave a Reply

Your email address will not be published.