Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A Win2D a Direct2D tetején rétegként van implementálva, és mindkét irányban támogatja az interopálást. Ha Win2D-objektummal rendelkezik, hozzáférhet a implementálásához használt natív Direct2D-objektumhoz. Ha Direct2D-objektummal rendelkezik, megkeresheti a burkoló Win2D objektumot, vagy létrehozhat egy új burkolót, ha még nem létezik.
Az interoperabilitás lehetővé teszi, hogy a Win2D-t natív DirectX API-kkal együtt használja. Írhat olyan alkalmazást, amely többnyire Win2D-t használ, de bármikor leugra a natív DirectX-hez – esetleg meghívhat egy másik API-t vagy külső összetevőt, amely natív felületeket igényel. Vagy az alkalmazás lehet többnyire natív DirectX, de átválthat a Win2D-re bizonyos helyeken, ahol extra kényelemre vagy C#-támogatásra van szüksége.
Interop API-k
A C++/CX interop API-k a Microsoft.Graphics.Canvas.native.h fejlécfájlban vannak definiálva:
#include <Microsoft.Graphics.Canvas.native.h>
using namespace Microsoft::Graphics::Canvas;
A Win2D-objektum által burkolt natív Direct2D-objektum lekérése:
template<typename T, typename U>
Microsoft::WRL::ComPtr<T> GetWrappedResource(U^ wrapper);
template<typename T, typename U>
Microsoft::WRL::ComPtr<T> GetWrappedResource(CanvasDevice^ device, U^ wrapper);
template<typename T, typename U>
Microsoft::WRL::ComPtr<T> GetWrappedResource(CanvasDevice^ device, U^ wrapper, float dpi);
A legtöbb típushoz GetWrappedResource csak Win2D burkolóobjektumot lehet meghívni paraméterként. Néhány típus esetében (lásd az alábbi táblázatot) azt is át kell adni egy eszköznek és/vagy DPI-értéknek. Nem hiba eszközt vagy DPI-t megadni a(z) GetWrappedResource használatakor olyan típusokkal, amelyek nem igénylik ezeket.
Natív Direct2D-objektumot burkoló Win2D-objektum beszerzéséhez:
template<typename WRAPPER>
WRAPPER^ GetOrCreate(IUnknown* resource);
template<typename WRAPPER>
WRAPPER^ GetOrCreate(CanvasDevice^ device, IUnknown* resource);
template<typename WRAPPER>
WRAPPER^ GetOrCreate(ID2D1Device1* device, IUnknown* resource);
template<typename WRAPPER>
WRAPPER^ GetOrCreate(CanvasDevice^ device, IUnknown* resource, float dpi);
template<typename WRAPPER>
WRAPPER^ GetOrCreate(ID2D1Device1* device, IUnknown* resource, float dpi);
GetOrCreate visszaad egy meglévő wrapperpéldányt, ha már létezik, vagy létrehoz egy újat, ha még nem létezik. Ha ugyanazon a natív objektumon ismételten hívja meg, minden alkalommal ugyanazt a burkolóobjektumot adja vissza, amíg az a burkolóobjektum-példány létezik. Ha a burkolóobjektumra mutató összes hivatkozás felszabadul, úgy hogy a referenciaszáma nullára csökken, és az objektum megsemmisül, akkor a(z) GetOrCreate bármely későbbi meghívásakor új burkolóobjektumot kell létrehozni.
Egyes típusok esetében a GetOrCreate meghívható úgy, hogy paraméterként csak egy Direct2D-erőforrásobjektumot ad meg, míg más típusoknál (lásd az alábbi táblázatot) az eszközt és a DPI-értéket is meg kell adni. Nem hiba eszközt vagy DPI-t megadni a(z) GetOrCreate használatakor olyan típusokkal, amelyek nem igénylik ezeket. Ha már létezik Win2D-burkolóobjektum, akkor az eszköz és a DPI még olyan típusok esetében is elhagyható, amelyekhez egyébként szükség lenne rájuk: ezeket a paramétereket csak új burkolóobjektum-példányok létrehozásakor használják.
GetOrCreate megérti az öröklési hierarchiákat, és mindig a megfelelő, leginkább származtatott burkolótípust hozza létre. Ha például a(z) GetOrCreate<CanvasBitmap>(ID2D1Bitmap1*) jelzővel rendelkező ID2D1Bitmap1 paraméterrel hívja meg a(z) D2D1_BITMAP_OPTIONS_TARGET elemet, akkor a visszaadott burkoló példány valójában egy CanvasRenderTarget lesz (amely a(z) CanvasBitmap leszármazottja). Fordítva, ha a GetOrCreate<CanvasRenderTarget>(ID2D1Bitmap1*) hívásakor olyan ID2D1Bitmap1-et ad át, amely nem rendelkezik D2D1_BITMAP_OPTIONS_TARGET-vel, a rendszer érvénytelen típuskonverziós kivételt dob.
Ha ezt a végletekig visszük, akkor érvényes meghívni a GetOrCreate<Object>(IUnknown*) és a GetWrappedResource<IUnknown>(Object^) elemet is.
Az interop-t támogató típusok
| Win2D-típus | Direct2D-típus |
GetOrCreate Paraméterek |
GetWrappedResource Paraméterek |
|---|---|---|---|
CanvasBitmap |
ID2D1Bitmap1 Nélkül D2D1_BITMAP_OPTIONS_TARGET |
Device | - |
CanvasCachedGeometry |
ID2D1GeometryRealization |
Device | - |
CanvasCommandList |
ID2D1CommandList |
Device | - |
CanvasDevice |
ID2D1Device1 |
- | - |
CanvasDrawingSession |
ID2D1DeviceContext1 |
- | - |
CanvasFontFace |
IDWriteFontFaceReference |
- | - |
CanvasFontSet |
IDWriteFontSet |
- | - |
CanvasGeometry |
ID2D1Geometry, vagy annak egyik származtatott felülete ID2D1PathGeometry, ID2D1RectangleGeometry, ID2D1RoundedRectangleGeometry, ID2D1EllipseGeometry, ID2D1TransformedGeometry vagy ID2D1GeometryGroup |
Device | - |
CanvasGradientMesh |
ID2D1GradientMesh |
Device | - |
CanvasImageBrush |
ID2D1BitmapBrush1 (ha a kép egy CanvasBitmap, és a(z) SourceRectanglenull) vagy ID2D1ImageBrush (ha ez bármilyen más típusú ICanvasImage, vagy ha SourceRectangle is set) |
Device | Opcionális DPI^1 |
CanvasLinearGradientBrush |
ID2D1LinearGradientBrush |
Device | - |
CanvasNumberSubstitution |
IDWriteNumberSubstitution |
- | - |
CanvasRadialGradientBrush |
ID2D1RadialGradientBrush |
Device | - |
CanvasRenderTarget |
ID2D1Bitmap1 és D2D1_BITMAP_OPTIONS_TARGET |
Device | - |
CanvasSolidColorBrush |
ID2D1SolidColorBrush |
Device | - |
CanvasStrokeStyle |
ID2D1StrokeStyle1 |
- | Device |
CanvasSvgDocument |
ID2D1SvgDocument^2 |
Device | - |
CanvasSwapChain |
IDXGISwapChain1 |
Eszköz, DPI | - |
CanvasTextFormat |
IDWriteTextFormat1 |
- | - |
CanvasTextLayout |
IDWriteTextLayout3 |
Device | - |
CanvasTextRenderingParameters |
IDWriteRenderingParams3 |
- | - |
CanvasTypography |
IDWriteTypography |
- | - |
CanvasVirtualBitmap |
ID2D1ImageSource vagy ID2D1TransformedImageSource |
Device | - |
ColorManagementProfile |
ID2D1ColorContext |
Device | Device |
EffectTransferTable3D |
ID2D1LookupTable3D |
Device | - |
Microsoft.Graphics.Canvas.Effects.* (több Win2D-osztály megfeleltetése ugyanarra a D2D-típusra) |
ID2D1Effect a megfelelő D2D1_PROPERTY_TYPE_CLSID |
Device | Eszköz, opcionális DPI^1 |
Note
^1: az opcionális DPI azt jelenti, hogy a DPI-érték megadása nélkül is érvényes erre a típusra meghívni GetWrappedResource , de ha a DPI-t adja meg, a Win2D hatékonyabban konfigurálhatja az effektusdiagramokat a redundáns DPI-kompenzációs csomópontok kihagyásával. Ez akkor alkalmazandó, amikor egy effektuson a(z) GetWrappedResource hívást végzi, vagy egy olyan CanvasImageBrush esetén, amelynek forrásképe egy effektus.
Note
^2: ha egy CanvasSvgDocument natív C++ interop használatával egy ID2D1SvgDocument-ből jön létre, a rendszer figyelmen kívül hagyja a ID2D1SvgDocument nézetablakának méretét.
Együttműködés a C++/CX használatával
Íme egy példa arra, hogy a Win2D hogyan tud együttműködni a Direct2D-vel a C++ használatával:
#include <Microsoft.Graphics.Canvas.native.h>
#include <d2d1_2.h>
using namespace Microsoft::Graphics::Canvas;
using namespace Microsoft::WRL;
// Interop Win2D -> Direct2D.
CanvasDevice^ canvasDevice = ...;
CanvasBitmap^ canvasBitmap = ...;
ComPtr<ID2D1Device> nativeDevice = GetWrappedResource<ID2D1Device>(canvasDevice);
ComPtr<ID2D1Bitmap1> nativeBitmap = GetWrappedResource<ID2D1Bitmap1>(canvasBitmap);
// Interop Direct2D -> Win2D.
canvasDevice = GetOrCreate<CanvasDevice>(nativeDevice.Get());
bitmap = GetOrCreate<CanvasBitmap>(canvasDevice, nativeBitmap.Get());
Note
Az interop is lehetséges C#-on keresztül, különböző eszközökkel (például beépített COM/WinRT interop használatával, a CsWinRT API-ján keresztül, vagy titkos kötések használatával). A C#-ban történő manuális interopról további információt a CsWinRT dokumentációjában talál.
Együttműködés a C++/WinRT használatával
A C++/WinRT használatával is elvégezheti az interopálást a fentiek módosításával. Vegye figyelembe, hogy a Win2D Windows-futtatókörnyezet-összetevők C++/WinRT fejléceit automatikusan létre kell hozni, amikor hozzáadja a Win2D NuGet-csomagot a C++/WinRT-projekthez. Az interop esetében azonban továbbra is használnia kell a fejlécfájlt Microsoft. Graphics.Canvas.native.h, amely tartalmazza az alacsony szintű ABI felületet ICanvasFactoryNative a névtérbenABI::Microsoft::Graphics::Canvas. Az interfész a következő függvényekkel rendelkezik, amelyekkel interopálást hajthat végre.
HRESULT GetOrCreate(ICanvasDevice* device, IUnknown* resource, float dpi, IInspectable** wrapper);
HRESULT GetNativeResource(ICanvasDevice* device, float dpi, REFIID iid, void** resource);
Íme egy példa, amely bemutatja, hogyan hozhat létre egy CanvasVirtualBitmap elemet egy IWICBitmapSource elemből a IWICBitmapSource és a megosztott CanvasDevice használatával.
#include "pch.h"
#include <wincodec.h>
#include <wincodecsdk.h>
#include <winrt/Microsoft.Graphics.Canvas.h> //This defines the C++/WinRT interfaces for the Win2D Windows Runtime Components
#include <Microsoft.Graphics.Canvas.h> //This defines the low-level ABI interfaces for the Win2D Windows Runtime Components
#include <Microsoft.Graphics.Canvas.native.h> //This is for interop
#include <d2d1_3.h>
using namespace winrt::Microsoft::Graphics::Canvas;
namespace abi {
using namespace ABI::Microsoft::Graphics::Canvas;
}
namespace winrt::Win2DInteropTest::implementation {
CanvasVirtualBitmap CreateVirtualBitmapFromBitmapSource(com_ptr<IWICBitmapSource> const& pBitmapSource){
CanvasDevice sharedDevice = CanvasDevice::GetSharedDevice();
//First we need to get an ID2D1Device1 pointer from the shared CanvasDevice
com_ptr<abi::ICanvasResourceWrapperNative> nativeDeviceWrapper = sharedDevice.as<abi::ICanvasResourceWrapperNative>();
com_ptr<ID2D1Device1> pDevice{ nullptr };
check_hresult(nativeDeviceWrapper->GetNativeResource(nullptr, 0.0f, guid_of<ID2D1Device1>(), pDevice.put_void()));
//Next we need to call some Direct2D functions to create the ID2D1ImageSourceFromWic object
com_ptr<ID2D1DeviceContext1> pContext{ nullptr };
check_hresult(pDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, pContext.put()));
com_ptr<ID2D1DeviceContext2> pContext2 = pContext.as<ID2D1DeviceContext2>();
com_ptr<ID2D1ImageSourceFromWic> pImage{ nullptr };
check_hresult(pContext2->CreateImageSourceFromWic(pBitmapSource.get(), D2D1_IMAGE_SOURCE_LOADING_OPTIONS_RELEASE_SOURCE, pImage.put()));
//Finally we need to wrap the ID2D1ImageSourceFromWic object inside
com_ptr<::IInspectable> pInspectable{ nullptr };
auto factory = winrt::get_activation_factory<CanvasDevice, abi::ICanvasFactoryNative>(); //abi::ICanvasFactoryNative is the activation factory for the CanvasDevice class
check_hresult(factory->GetOrCreate(sharedDevice.as<abi::ICanvasDevice>().get(), pImage.as<::IUnknown>().get(), 0.0f, pInspectable.put())); //Note abi::ICanvasDevice is defined in the header Microsoft.Graphics.Canvas.h
CanvasVirtualBitmap cvb = pInspectable.as<CanvasVirtualBitmap>();
return cvb;
}
}
Ne felejtse el felvenni a fejlécet <unknwn.h> a pch.h fájlba a WinRT-fejlécek előtt (az SDK 17763-ban és újabb verzióiban szükséges).
Windows developer