Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Does the docwiki page 'Using the Direct2D Canvas' exist for c++


This question is answered.


Permlink Replies: 11 - Last Post: Jan 2, 2017 3:11 AM Last Post By: Mike Versteeg
Larry Johnson

Posts: 86
Registered: 6/7/14
Does the docwiki page 'Using the Direct2D Canvas' exist for c++  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 13, 2016 3:43 AM
The docwoki page below is for Delphi and has some source code I am interested in. Is there a version of this page for C++? I can't seem to find it.

Using the Direct2D Canvas
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Using_the_Direct2D_Canvas

thanks
Mike Versteeg

Posts: 118
Registered: 9/16/07
Re: Does the docwiki page 'Using the Direct2D Canvas' exist for c++  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 13, 2016 4:47 AM   in response to: Larry Johnson in response to: Larry Johnson
Larry Johnson wrote:
The docwoki page below is for Delphi and has some source code I am interested in. Is there a version of this page for C++? I can't seem to find it.

Using the Direct2D Canvas
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Using_the_Direct2D_Canvas

thanks

Keep in mind this is slow if you need multiple canvasses..
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Does the docwiki page 'Using the Direct2D Canvas' exist for c++
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 13, 2016 11:21 AM   in response to: Larry Johnson in response to: Larry Johnson
Larry wrote:

The docwoki page below is for Delphi and has some source code I
am interested in. Is there a version of this page for C++?

No. You will have to translate the various Delphi code snippets to C++, eg:

bool __fastcall Create2D2Canvas()
{
    if (TDirect2DCanvas::Supported())
    {
        try {
            FD2DCanvas = new TDirect2DCanvas(Handle);
            return true;
        }
        catch (const Exception &) {
        }
    }
    return false;
}


void __fastcall T2D2Form::FormPaint(TObject *Sender)
{
    TDirect2DCanvas *LCanvas = new TDirect2DCanvas(Canvas, ClientRect);
    LCanvas->BeginDraw();
 
    try
    {
        // Drawing goes here
        LCanvas->Brush->Color = clRed;
        LCanvas->Pen->Color = clBlue;
        LCanvas->Rectangle(100, 100, 200, 200);
    }
    __finally
    {
        LCanvas->EndDraw();
        delete LCanvas;
    }
}


class T2D2Form : public TForm
{
private:
    TDirect2DCanvas *FCanvas;
 
protected:
    virtual void __fastcall CreateWnd(); 
 
    MESSAGE void __fastcall WMPaint(TWMPaint &Message); 
    MESSAGE void __fastcall WMSize(TWMSize &Message);
 
public:
    property TDirect2DCanvas* Canvas = {read=FCanvas};
 
    BEGIN_MESSAGE_MAP
        VCL_MESSAGE_HANDLER(WM_PAINT, TWMPaint, WMPaint) 
        VCL_MESSAGE_HANDLER(WM_SIZE, TWMSize, WMSize)
    END_MESSAGE_MAP(TForm) 
};
 
void ___fastcall T2D2Form::CreateWnd()
{
    TForm::CreateWnd();
    FCanvas = new TDirect2DCanvas(Handle);
}
 
void __fastcall T2D2Form::WMPaint(TWMPaint &Message)
{
    PAINTSTRUCT PaintStruct;
    ::BeginPaint(Handle, &PaintStruct);
 
    try
    {
        FCanvas->BeginDraw();
        try {
            Paint();
        }
        __finally {
            FCanvas->EndDraw();
       }
    }
    __finally {
        ::EndPaint(Handle, &PaintStruct); 
    }
}
 
void __fastcall T2D2Form::WMSize(TWMSize &Message)
{
    if (FCanvas)
        _di_ID2D1HwndRenderTarget(FCanvas->RenderTarget)->Resize(D2D1SizeU(ClientWidth, 
ClientHeight)); 
 
    TForm::Dispatch(&Message);
}


void __fastcall TForm1::MyBoxPaint(TObject *Sender)
{
    /* Assuming the Canvas property of TMyPaintBox is TCustomCanvas, 
     to support both canvas implementations */
 
    /* Intermediate API to access graphic objects is different */
    TDirect2DCanvas *d2d = dynamic_cast<TDirect2DCanvas*>(MyBox->Canvas);
    if (d2d)
        d2d->Pen->Color = clRed;
    else
        static_cast<TCanvas*>(MyBox->Canvas)->Pen->Color = clRed;
 
    /* Normal high-level API is available */
    MyBox->Canvas->MoveTo(0, 0);
    MyBox->Canvas->LineTo(MyBox->Width, MyBox->Height);
}


class TCustomAcceleratedPaintBox : public TCustomControl
{
    typedef TCustomControl inherited;
 
private:
    TNotifyEvent FOnPaint;
    bool FUseD2D;
    TDirect2DCanvas *FD2DCanvas;
 
    bool __fastcall CreateD2DCanvas();
 
    /* Catching paint events */
    MESSAGE void __fastcall WMPaint(TWMPaint &Message);
    MESSAGE void __fastcall WMSize(TWMSize &Message);
 
    /* Set/Get stuff */
    void __fastcall SetAccelerated(const bool Value);
    TCanvas* __fastcall GetGDICanvas();
    TCustomCanvas* __fastcall GetOSCanvas();
 
protected:
    virtual void __fastcall CreateWnd();
    virtual void __fastcall Paint();
 
public:
    /* Life-time management */
    __fastcall TCustomAcceleratedPaintBox(TComponent *AOwner);
    __fastcall ~TCustomAcceleratedPaintBox();
 
    BEGIN_MESSAGE_MAP
        VCL_MESSAGE_HANDLER(WM_PAINT, TWMPaint, WMPaint) 
        VCL_MESSAGE_HANDLER(WM_SIZE, TWMSize, WMSize)
    END_MESSAGE_MAP(inherited) 
 
    /* Public properties */
    property bool Accelerated = {read=FUseD2D, write=SetAccelerated};
    property TCustomCanvas* Canvas = {read=GetOSCanvas};
    property TCanvas* GDICanvas = {read=GetGDICanvas};
    property TDirect2DCanvas* D2DCanvas = {read=FD2DCanvas};
 
    /* The Paint event */
    property TNotifyEvent OnPaint = {read=FOnPaint, write=FOnPaint};
};
 
bool __fastcall TCustomAcceleratedPaintBox::CreateD2DCanvas()
{
    try {
        FD2DCanvas = new TDirect2DCanvas(Handle);
    }
    catch (const Exception &) {
        /* Failed creating the D2D canvas, halt! */
        return false;
    }
 
    return true;
}
 
void __fastcall TCustomAcceleratedPaintBox::CreateWnd()
{
    inherited::CreateWnd();
 
    /* Try to create the custom canvas */
    if ((Win32MajorVersion >= 6) && (Win32Platform = VER_PLATFORM_WIN32_NT))
        FUseD2D = CreateD2DCanvas();
    else
      FUseD2D = false;
}
 
TCanvas* __fastcall TCustomAcceleratedPaintBox::GetGDICanvas()
{
    if (FUseD2D)
        return NULL;
    else
        return inherited::Canvas;
}
 
TCustomCanvas* __fastcall TCustomAcceleratedPaintBox::GetOSCanvas()
{
    if (FUseD2D)
        return FD2DCanvas;
    else
        return inherited::Canvas;
}
 
void __fastcall TCustomAcceleratedPaintBox::SetAccelerated(const bool Value)
{
    /* Same value? */
    if (Value == FUseD2D)
        return;
 
    if (!Value)
    {
        FUseD2D = false;
        Repaint();
    }
    else
    {
        FUseD2D = (FD2DCanvas <> nil);
        if (FUseD2D)
            Repaint();
    }
}
 
void __fastcall TCustomAcceleratedPaintBox::Paint()
{
    if (FUseD2D)
    {
        D2DCanvas->Font->Assign(Font);
        D2DCanvas->Brush->Color = Color;
 
        if (ComponentState.Contains(csDesigning))
        {
            D2DCanvas->Pen->Style = psDash;
            D2DCanvas->Brush->Style = bsSolid;
 
            D2DCanvas->Rectangle(0, 0, Width, Height);
        }
    }
    end
    {
        GDICanvas->Font->Assign(Font);
        GDICanvas->Brush->Color = Color;
 
        if (ComponentState.Contains(csDesigning))
        {
            GDICanvas->Pen->Style = psDash;
            GDICanvas->Brush->Style = bsSolid;
 
            GDICanvas->Rectangle(0, 0, Width, Height);
        }
    }
 
    if (FOnPaint) FOnPaint(this);
}
 
void __fastcall TCustomAcceleratedPaintBox::WMPaint(TWMPaint &Message)
{
    if (FUseD2D)
    {
        PAINTSTRUCT PaintStruct;
 
        ::BeginPaint(Handle, &PaintStruct);
        try
        {
            FD2DCanvas->BeginDraw(); 
 
            try {
                Paint();
            }
            __finally {
                FD2DCanvas->EndDraw();
            }
        }
        __finally {
            ::EndPaint(Handle, &PaintStruct);
        }
    }
    else
        inherited::Dispatch(&Message);
}
 
void __fastcall TCustomAcceleratedPaintBox::WMSize(TWMSize &Message)
{
    if (FD2DCanvas)
        _di_ID2D1HwndRenderTarget(FD2DCanvas->RenderTarget)->Resize(D2D1SizeU(Width, 
Height));
 
    inherited::Dispatch(&Message);
}


--
Remy Lebeau (TeamB)
Mike Versteeg

Posts: 118
Registered: 9/16/07
Re: Does the docwiki page 'Using the Direct2D Canvas' exist for c++
Helpful
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 13, 2016 11:36 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy, I know you are a firm believer in painting in OnPaint, but this does not work efficiently for video (the Windows pipeline crawls to a stop if you make hundreds of invalidate calls per second). When using a D2D canvas, calling invalidate is AFAIK the only way to get it to paint, making it useless for any serious work. I asked this on G+, talked with Embarcadero paid support, and no one has a clue how to use D2D canvas more efficiently. Ironically really. Since you have a good grasp of the basics behind all this I was wondering if you have any idea how to get D2D canvas to paint without calling invalidate?

Larry, I hope you aren't seeing this as a hijack, not sure what you need D2D canvas for but this might interest you too?
Jan Dijkstra

Posts: 206
Registered: 11/4/99
Re: Does the docwiki page 'Using the Direct2D Canvas' exist for c++  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 14, 2016 3:41 AM   in response to: Mike Versteeg in response to: Mike Versteeg
Mike Versteeg wrote:
Remy, I know you are a firm believer in painting in OnPaint, but this does not work efficiently for video (the Windows pipeline crawls to a stop if you make hundreds of invalidate calls per second). When using a D2D canvas, calling invalidate is AFAIK the only way to get it to paint, making it useless for any serious work. I asked this on G+, talked with Embarcadero paid support, and no one has a clue how to use D2D canvas more efficiently. Ironically really. Since you have a good grasp of the basics behind all this I was wondering if you have any idea how to get D2D canvas to paint without calling invalidate?

Larry, I hope you aren't seeing this as a hijack, not sure what you need D2D canvas for but this might interest you too?

While I don't have a clue about the D2D canvas, I do know that in regular DirectX, you don't have to invalidate the host window's client area to get a scene updated. I just sandwich my rendering instructions between BeginScene and EndScene, and call Present after that to update the contents of the host window. DirectX itself takes care of updating all the necessary pixels.

As for Invalidate. I do remember reading somewhere that multiple Invalidate calls to the same window just get merged until the message queue gets around to sending WM_PAINT to your window. Which it will only do if no other messages are pending in the queue. So, hundreds of Invalidate calls per second would only result in hundreds of calls to WM_PAINT if the system is fast enough to render that.
Mike Versteeg

Posts: 118
Registered: 9/16/07
Re: Does the docwiki page 'Using the Direct2D Canvas' exist for c++  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 14, 2016 3:52 AM   in response to: Jan Dijkstra in response to: Jan Dijkstra
That's very interesting Jan, Present may well be what I am looking for. Now all I need to figure out is how to, and if I can, call this when working with TDirect2DCanvas. Thanks!
Larry Johnson

Posts: 86
Registered: 6/7/14
Re: Does the docwiki page 'Using the Direct2D Canvas' exist for c++  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 17, 2016 9:21 AM   in response to: Mike Versteeg in response to: Mike Versteeg
Do you know if it is possible to write Direct2D code using the Windows APIs and code that looks more like VC? I mean completely skip using the TDirect2DCanvas and write code similar to the sample application on the MS web site below. Is this possible in C++Builder? I don't want to start down this road if it is not possible.

Creating a Simple Direct2D Application
https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994(v=vs.85).aspx

Mike Versteeg

Posts: 118
Registered: 9/16/07
Re: Does the docwiki page 'Using the Direct2D Canvas' exist for c++  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 18, 2016 12:03 AM   in response to: Larry Johnson in response to: Larry Johnson
Larry Johnson wrote:
Do you know if it is possible to write Direct2D code using the Windows APIs and code that looks more like VC? I mean completely skip using the TDirect2DCanvas and write code similar to the sample application on the MS web site below. Is this possible in C++Builder? I don't want to start down this road if it is not possible.

Creating a Simple Direct2D Application
https://msdn.microsoft.com/en-us/library/windows/desktop/dd370994(v=vs.85).aspx


Yes you can, but keep in mind only the headers for D2D 1.0 are present. Add your vote here https://quality.embarcadero.com/browse/RSP-10159
Larry Johnson

Posts: 86
Registered: 6/7/14
Re: Does the docwiki page 'Using the Direct2D Canvas' exist for c++  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 18, 2016 12:54 PM   in response to: Mike Versteeg in response to: Mike Versteeg
The highest version number I see is D2D 1.1. I though the header files were the same for all C++ code. Is it possible to outsource the creation of D2D 1.1 headers for C++Builder? or is this something only Embarcadero can do? The C++Builder road map shows all Linux upgrades for the year 2017 so I am willing to out source new headers if it is possible.
Mike Versteeg

Posts: 118
Registered: 9/16/07
Re: Does the docwiki page 'Using the Direct2D Canvas' exist for c++  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 19, 2016 12:42 AM   in response to: Larry Johnson in response to: Larry Johnson
Larry Johnson wrote:
The highest version number I see is D2D 1.1. I though the header files were the same for all C++ code. Is it possible to outsource the creation of D2D 1.1 headers for C++Builder? or is this something only Embarcadero can do? The C++Builder road map shows all Linux upgrades for the year 2017 so I am willing to out source new headers if it is possible.
Maybe, but you would need someone who knows both Direct2D and C++ Builder/Delphi.
Mike Versteeg

Posts: 118
Registered: 9/16/07
Re: Does the docwiki page 'Using the Direct2D Canvas' exist for c++  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 2, 2017 3:11 AM   in response to: Jan Dijkstra in response to: Jan Dijkstra
Unfortunately I still cannot use Direct2DCanvas as, unlike GDI, it's implementation is not thread safe. Would have loved to get some low-CPU smooth scaling of my bitmaps.
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Does the docwiki page 'Using the Direct2D Canvas' exist for c++  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Oct 14, 2016 10:06 AM   in response to: Mike Versteeg in response to: Mike Versteeg
Mike wrote:

Since you have a good grasp of the basics behid all this I was
wondering if you have any idea how to get D2D canvas to paint
without calling invalidate?

Sorry, I have never used Direct2D before (or DirectX in general, for that
matter).

--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02