Direct2D API
SDK用のエイリアス
C++ では、Direct2D API で定義されているすべての型、特に WinAPI.D2D1.hpp で宣言されている型で問題が発生します。 コンパイラ エラーやあいまいさのエラーを回避するには、このガイドに従ってください。
以前、WinAPI.D2D1.hpp では、次のような型を使用していました: D2D_SIZE_F、D2D_SIZE_U、D2D1_PIXEL_FORMAT、D2D1_GAMMA、および D2D1_EXTEND_MODE。 これらの型は、Windows SDK ヘッダーで定義されていました。 現在、RAD Studio では、TD2D1SizeF、TD2D1SizeU、TD2D1PixelFormat、TD2D1Gamma、TD2D1ExtendMode などの型を使用します。
これらの新しい型は古い型のエイリアスです。唯一の違いは、新しい型が 名前空間 Winapi.D2D1 に含まれている一方で、その 名前空間 が自動的には使用されないことです。 これは、通常 .hpp ファイルの末尾に出力される namespace の使用を削除することを意味しましたが、その結果、型を認識できないことによるコンパイラ エラー(using 文を追加することで修正できます)や、あいまいさのエラーが発生しました。 したがって、修飾名を使用するか、using 文を追加する必要があります。
例:</br>
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 ;
};
次の例は、以前のコードの記述方法と、新しい方式で動作させるために必要なリファクタリングを示しています。 たとえば、次のコードの場合:
#include <Direct2D.hpp>
Void test(unsigned cColorWidth,unsigned cColorHeight)
{
// Create a 2D 32-bit bitmap
D2D1_SIZE_U colorsize = D2D1SizeU(cColorWidth,cColorHeight);
}
上記のコードはコンパイルできなくなります。 これを修正するには、次の文を追加します:
Using namespace Winapi::D2d1;
D3D_SHADER_MACRO や D3D10_SHADER_MACRO のように、追加の変更が必要となる、より複雑なシナリオもあります。これらは、Delphi 変換に {$EXTERNALSYM} のタグが付かなくなったため、あいまいになる可能性があります。
名前空間の一致
RAD Studio は、using 文を 名前空間 Winapi::D2d1 用に自動的には出力しません。これは、SDK ヘッダーで宣言されている多数の 名前空間と重複するものが含まれているためです。 ただし、その 名前空間によって公開される API は、SDK ヘッダーで定義されている API と必ずしも一致しません。
ID2D1Bitmap インターフェイスを例に取ると、そのインターフェイスの Delphi 版(Winapi.D2D1.hpp に記述されているもの)は次のようになります:
__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 ;
SDK ヘッダーを詳しく見ると、同じインターフェイスについて、次に示す別の定義があることがわかります:
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;
これらのインターフェイスの SDK 版は struct/record を返すのに対し、Delphi 版は struct/record の参照を受け取ることに注意してください。 この違いは、Embarcadero のツールと Microsoft のツールで、this ポインタと structure の戻り値ポインタを渡す順序が異なることに関係しています。
両方のインターフェイスは、同じインターフェイス ID(GUID/IID)を使用しますが、公開する API は異なります。 したがって、ID2D1Bitmap のような型への参照があいまいになるため、RAD Studio はヘッダー Winapi.D2D1.hpp に using namespace Winapi::D2d1 を出力しません。
Embarcadero のツールでビルドするコードでは、SDK ヘッダーで定義されているインターフェイスではなく、
WinapiD2D1.hpp ヘッダー ファイルで定義されているインターフェイスを使用する必要があります。