Direct2D APIs
Go Up to C++ Header File (*.h, *.hpp)
Aliases for SDK
C++ encounters issues with all the types defined in the Direct2D API, particularly those declared in WinAPI.D2D1.hpp. Follow this guide to avoid getting compiler or ambiguity errors.
Previously, the WinAPI.D2D1.hpp used types such as: D2D_SIZE_F, D2D_SIZE_U, D2D1_PIXEL_FORMAT, D2D1_GAMMA, and D2D1_EXTEND_MODE. These types were defined in the Windows SDK headers. Now, RAD Studio uses types like TD2D1SizeF, TD2D1SizeU, TD2D1PixelFormat, TD2D1Gamma, and TD2D1ExtendMode.
These newer types are aliases of the older ones, with the only difference that the new types are in the namespace Winapi.D2D1, but the namespace is not automatically used. This meant removing the use of namespace that is typically emitted at the end of .hpp files, but this resulted in a compiler error because it does not know the type (this is fixed by adding a using statement), or in an ambiguity error. Therefore, it is necessary to use qualified names or add using statements.
Examples:
The following code shows what has changed in the Winapi.D2D1.hpp
__interface INTERFACE_UUID("{A2296057-EA42-4099-983B-539FB6505426}") ID2D1Bitmap : public ID2D1Resource
{
- virtual void __stdcall GetSize(/* out */ D2D_SIZE_F &size) = 0 ;
- virtual void __stdcall GetPixelSize(/* out */ D2D_SIZE_U &pixelSize) = 0 ;
- virtual void __stdcall GetPixelFormat(/* out */ D2D1_PIXEL_FORMAT &pixelFormat) = 0 ;
+ virtual void __stdcall GetSize(/* out */ TD2D1SizeF &size) = 0 ;
+ virtual void __stdcall GetPixelSize(/* out */ TD2D1SizeU &pixelSize) = 0 ;
+ virtual void __stdcall GetPixelFormat(/* out */ TD2D1PixelFormat &pixelFormat) = 0 ;
virtual void __stdcall GetDpi(/* out */ float &dpiX, /* out */ float &dpiY) = 0 ;
virtual HRESULT __stdcall CopyFromBitmap(D2D_POINT_2U &destPoint, const _di_ID2D1Bitmap bitmap, D2D_RECT_U &srcRect) = 0 ;
virtual HRESULT __stdcall CopyFromRenderTarget(D2D_POINT_2U &destPoint, const _di_ID2D1RenderTarget renderTarget, D2D_RECT_U &srcRect) = 0 ;
@@ -612,16 +614,16 @@
{
virtual unsigned __stdcall GetGradientStopCount() = 0 ;
virtual void __stdcall GetGradientStops(PD2D1GradientStop gradientStops, unsigned gradientStopsCount) = 0 ;
- virtual D2D1_GAMMA __stdcall GetColorInterpolationGamma() = 0 ;
- virtual D2D1_EXTEND_MODE __stdcall GetExtendMode() = 0 ;
+ virtual TD2D1Gamma __stdcall GetColorInterpolationGamma() = 0 ;
+ virtual TD2D1ExtendMode __stdcall GetExtendMode() = 0 ;
};
The next example shows how the code was written before, and how it must be refactored to work with the new way. For example, for the code given:
#include <Direct2D.hpp>
Void test(unsigned cColorWidth,unsigned cColorHeight)
{
// Create a 2D 32-bit bitmap
D2D1_SIZE_U colorsize = D2D1SizeU(cColorWidth,cColorHeight);
}
The code above will no longer compile. Fix it by adding:
Using namespace Winapi::D2d1;
There are more complex scenarios that will require additional changes, such as the D3D_SHADER_MACRO and D3D10_SHADER_MACRO, which can be ambiguous because the Delphi translation is no longer tagged with {$EXTERNALSYM}.
Matching namespaces
RAD Studio does not automatically emit a using statement for namespace Winapi::D2d1 because it contains duplicates of many namespaces declared in SDK headers. But the API exposed by the namespace does not always match the ones defined in the SDK headers.
Take the ID2D1Bitmap interface for example, the Delphi version of that interface (as seen in the Winapi.D2D1.hpp) is as follows:
__interface INTERFACE_UUID("{A2296057-EA42-4099-983B-539FB6505426}") ID2D1Bitmap : public ID2D1Resource
{
virtual void __stdcall GetSize(/* out */ TD2D1SizeF &size) = 0 ;
virtual void __stdcall GetPixelSize(/* out */ TD2D1SizeU &pixelSize) = 0 ;
virtual void __stdcall GetPixelFormat(/* out */ TD2D1PixelFormat &pixelFormat) = 0 ;
Taking a closer look at the SDK headers, another definition is shown for the same interface, as shown below:
interface DX_DECLARE_INTERFACE("a2296057-ea42-4099-983b-539fb6505426") ID2D1Bitmap : public ID2D1Image
{
/// <summary>
/// Returns the size of the bitmap in resolution-independent units.
/// </summary>
STDMETHOD_(D2D1_SIZE_F, GetSize)(
) CONST PURE;
/// <summary>
/// Returns the size of the bitmap in resolution-dependent units, (pixels).
/// </summary>
STDMETHOD_(D2D1_SIZE_U, GetPixelSize)(
) CONST PURE;
/// <summary>
/// Retrieve the format of the bitmap.
/// </summary>
STDMETHOD_(D2D1_PIXEL_FORMAT, GetPixelFormat)(
) CONST PURE;
Note that the SDK version of these interfaces returns a struct/record, while the Delphi version takes a struct/record reference. This difference is tied to the fact that Embarcadero tools and Microsoft tools pass the this pointer and the structure return pointer in different orders.
Both interfaces use the same safe interface ID (GUID/IID), but they expose different APIs. Therefore, RAD Studio does not emit a using namespace Winapi::D2d1 in the header Winapi.D2D1.hpp because a reference to a type like ID2D1Bitmap would be ambiguous.
Code built with Embarcadero tools must use the interface defined in the
WinapiD2D1.hpp header file, not the ones defined in the SDK header.