//--------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. // // D2D helper functions for effect authors. // // File name: D2D1EffectHelpers.h //--------------------------------------------------------------------------- #pragma once #ifndef _D2D1_EFFECT_HELPERS_H_ #define _D2D1_EFFECT_HELPERS_H_ /*#include */ /*#pragma region Application Family*/ /*#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)*/ #include //+----------------------------------------------------------------------------- // // Function: // DeducingValueSetter // // Synopsis: // Deduces the class and arguments and then calls a member-function property // setter callback for a value-type property. // // This should not be called directly. // //-------------------------------------------------------------------------------- template HRESULT DeducingValueSetter( _In_ HRESULT (C::*callback)(P), _In_ I *effect, _In_reads_(dataSize) const BYTE *data, UINT32 dataSize ) { // We must exactly match the value-type's size. if (dataSize != sizeof(P)) { return E_INVALIDARG; } return (static_cast(effect)->*callback)(*reinterpret_cast(data)); } //+----------------------------------------------------------------------------- // // Function: // ValueSetter // // Synopsis: // Calls a member-function property setter callback for a value-type property. // //-------------------------------------------------------------------------------- template HRESULT CALLBACK ValueSetter( _In_ IUnknown *effect, _In_reads_(dataSize) const BYTE *data, UINT32 dataSize ) { // Cast through I to resolve multiple-inheritance ambiguities. return DeducingValueSetter(P, static_cast(effect), data, dataSize); } //+----------------------------------------------------------------------------- // // Function: // DeducingValueGetter // // Synopsis: // Deduces the class and arguments and then calls a member-function property // getter callback for a value-type property. // // This should not be called directly. // //-------------------------------------------------------------------------------- template HRESULT DeducingValueGetter( _In_ P (C::*callback)() const, _In_ const I *effect, _Out_writes_opt_(dataSize) BYTE *data, UINT32 dataSize, _Out_opt_ UINT32 *actualSize ) { if (actualSize) { *actualSize = sizeof(P); } if (dataSize > 0 && data) { if (dataSize < sizeof(P)) { return E_NOT_SUFFICIENT_BUFFER; } *reinterpret_cast

(data) = (static_cast(effect)->*callback)(); } return S_OK; } //+----------------------------------------------------------------------------- // // Function: // ValueGetter // // Synopsis: // Calls a member-function property setter callback for a value-type property. // //-------------------------------------------------------------------------------- template HRESULT CALLBACK ValueGetter( _In_ const IUnknown *effect, _Out_writes_opt_(dataSize) BYTE *data, UINT32 dataSize, _Out_opt_ UINT32 *actualSize ) { // Cast through I to resolve multiple-inheritance ambiguities. return DeducingValueGetter(P, static_cast(effect), data, dataSize, actualSize); } //+----------------------------------------------------------------------------- // // Function: // DeducingBlobSetter // // Synopsis: // Deduces the class and arguments and then calls a member-function property // setter callback for a blob-type property. // // This should not be called directly. // //-------------------------------------------------------------------------------- template HRESULT DeducingBlobSetter( _In_ HRESULT (C::*callback)(const BYTE *, UINT32), _In_ I *effect, _In_reads_(dataSize) const BYTE *data, UINT32 dataSize ) { return (static_cast(effect)->*callback)(data, dataSize); } //+----------------------------------------------------------------------------- // // Function: // BlobSetter // // Synopsis: // Calls a member-function property setter callback for a blob-type property. // //-------------------------------------------------------------------------------- template HRESULT CALLBACK BlobSetter( _In_ IUnknown *effect, _In_reads_(dataSize) const BYTE *data, UINT32 dataSize ) { // Cast through I to resolve multiple-inheritance ambiguities. return DeducingBlobSetter(P, static_cast(effect), data, dataSize); } //+----------------------------------------------------------------------------- // // Function: // DeducingBlobGetter // // Synopsis: // Deduces the class and arguments and then calls a member-function property // getter callback for a blob-type property. // // This should not be called directly. // //-------------------------------------------------------------------------------- template HRESULT DeducingBlobGetter( _In_ HRESULT (C::*callback)(BYTE *, UINT32, UINT32*) const, _In_ const I *effect, _Out_writes_opt_(dataSize) BYTE *data, UINT32 dataSize, _Out_opt_ UINT32 *actualSize ) { return (static_cast(effect)->*callback)(data, dataSize, actualSize); } //+----------------------------------------------------------------------------- // // Function: // BlobGetter // // Synopsis: // Calls a member-function property getter callback for a blob-type property. // //-------------------------------------------------------------------------------- template HRESULT CALLBACK BlobGetter( _In_ const IUnknown *effect, _Out_writes_opt_(dataSize) BYTE *data, UINT32 dataSize, _Out_opt_ UINT32 *actualSize ) { // Cast through I to resolve multiple-inheritance ambiguities. return DeducingBlobGetter(P, static_cast(effect), data, dataSize, actualSize); } //+----------------------------------------------------------------------------- // // Function: // DeducingStringSetter // // Synopsis: // Deduces the class and arguments and then calls a member-function property // setter callback for a string-type property. // // This should not be called directly. // //-------------------------------------------------------------------------------- template HRESULT DeducingStringSetter( _In_ HRESULT (C::*callback)(PCWSTR string), _In_ I *effect, _In_reads_(dataSize) const BYTE *data, UINT32 dataSize ) { dataSize; return (static_cast(effect)->*callback)(reinterpret_cast(data)); } //+----------------------------------------------------------------------------- // // Function: // StringSetter // // Synopsis: // Calls a member-function property setter callback for a string-type property. // //-------------------------------------------------------------------------------- template HRESULT CALLBACK StringSetter( _In_ IUnknown *effect, _In_reads_(dataSize) const BYTE *data, UINT32 dataSize ) { // Cast through I to resolve multiple-inheritance ambiguities. return DeducingStringSetter(P, static_cast(effect), data, dataSize); } //+----------------------------------------------------------------------------- // // Function: // DeducingStringGetter // // Synopsis: // Deduces the class and arguments and then calls a member-function property // getter callback for a string-type property. // // This should not be called directly. // //-------------------------------------------------------------------------------- template HRESULT DeducingStringGetter( _In_ HRESULT (C::*callback)(PWSTR, UINT32, UINT32*) const, _In_ const I *effect, _Out_writes_opt_(dataSize) BYTE *data, UINT32 dataSize, _Out_opt_ UINT32 *actualSize ) { UINT32 cchString = 0; HRESULT hr = (static_cast(effect)->*callback)(reinterpret_cast(data), dataSize / sizeof(WCHAR), &cchString); if ((SUCCEEDED(hr) || hr == E_NOT_SUFFICIENT_BUFFER) && actualSize) { *actualSize = cchString * sizeof(WCHAR); } return hr; } //+----------------------------------------------------------------------------- // // Function: // StringGetter // // Synopsis: // Calls a member-function property getter callback for a string-type property. // //-------------------------------------------------------------------------------- template HRESULT CALLBACK StringGetter( _In_ const IUnknown *effect, _Out_writes_opt_(dataSize) BYTE *data, UINT32 dataSize, _Out_opt_ UINT32 *actualSize ) { // Cast through I to resolve multiple-inheritance ambiguities. return DeducingStringGetter(P, static_cast(effect), data, dataSize, actualSize); } // // Simpler versions of the helpers can be declared if decltype is available: // #if _MSC_VER >= 1600 #define D2D1_SIMPLE_BINDING_MACROS #endif #ifdef D2D1_SIMPLE_BINDING_MACROS // // Helper to work around decltype issues: // template T GetType(T t) { return t; }; // // Helper macros for declaring a D2D1_PROPERTY_BINDING for value, blob, or string callbacks. // #define D2D1_VALUE_TYPE_BINDING(NAME, SETTER, GETTER) \ { NAME, &ValueSetter, &ValueGetter } #define D2D1_BLOB_TYPE_BINDING(NAME, SETTER, GETTER) \ { NAME, &BlobSetter, &BlobGetter } #define D2D1_STRING_TYPE_BINDING(NAME, SETTER, GETTER) \ { NAME, &StringSetter, &StringGetter } // // Read-only variants: // #define D2D1_READONLY_VALUE_TYPE_BINDING(NAME, GETTER) \ { NAME, NULL, &ValueGetter } #define D2D1_READONLY_BLOB_TYPE_BINDING(NAME, GETTER) \ { NAME, NULL, &BlobGetter } #define D2D1_READONLY_STRING_TYPE_BINDING(NAME, GETTER) \ { NAME, NULL, &StringGetter } #else // #ifdef D2D1_SIMPLE_BINDING_MACROS // // Helper macros for declaring a D2D1_PROPERTY_BINDING for value, blob, or string callbacks. // #define D2D1_VALUE_TYPE_BINDING(NAME, TYPE, CLASS, SETTER, GETTER) \ { \ NAME, \ &ValueSetter, \ &ValueGetter \ } #define D2D1_BLOB_TYPE_BINDING(NAME, CLASS, SETTER, GETTER) \ { \ NAME, \ &BlobSetter, \ &BlobGetter \ } #define D2D1_STRING_TYPE_BINDING(NAME, CLASS, SETTER, GETTER) \ { \ NAME, \ &StringSetter, \ &StringGetter \ } // // Read-only variants: // #define D2D1_READONLY_VALUE_TYPE_BINDING(NAME, TYPE, CLASS, GETTER) \ { \ NAME, \ NULL, \ &ValueGetter \ } #define D2D1_READONLY_BLOB_TYPE_BINDING(NAME, CLASS, GETTER) \ { \ NAME, \ NULL, \ &BlobGetter \ } #define D2D1_READONLY_STRING_TYPE_BINDING(NAME, CLASS, GETTER) \ { \ NAME, \ NULL, \ &StringGetter \ } #endif // #ifdef D2D1_SIMPLE_BINDING_MACROS /*#endif*/ /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */ /*#pragma endregion*/ #endif // #ifndef _D2D1_AUTHOR_H_