wrl.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. #pragma once
  2. #include <winstring.h>
  3. #include <stdio.h>
  4. #include <tchar.h>
  5. #include <crtdbg.h>
  6. #include <array>
  7. #include <vector>
  8. #include <wrl\implements.h>
  9. #include <wrl\event.h>
  10. #include <inspectable.h>
  11. #ifndef __cplusplus_winrt
  12. #include <windows.foundation.h>
  13. __declspec(noreturn) void __stdcall __abi_WinRTraiseException(long);
  14. inline void __abi_ThrowIfFailed(long __hrArg)
  15. {
  16. if (__hrArg < 0)
  17. {
  18. __abi_WinRTraiseException(__hrArg);
  19. }
  20. }
  21. struct Guid
  22. {
  23. public:
  24. Guid();
  25. Guid(__rcGUID_t);
  26. operator ::__rcGUID_t();
  27. bool Equals(Guid __guidArg);
  28. bool Equals(__rcGUID_t __guidArg);
  29. Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, unsigned __int8 __dArg,
  30. unsigned __int8 __eArg, unsigned __int8 __fArg, unsigned __int8 __gArg, unsigned __int8 __hArg,
  31. unsigned __int8 __iArg, unsigned __int8 __jArg, unsigned __int8 __kArg);
  32. Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, const unsigned __int8* __dArg);
  33. private:
  34. unsigned long __a;
  35. unsigned short __b;
  36. unsigned short __c;
  37. unsigned char __d;
  38. unsigned char __e;
  39. unsigned char __f;
  40. unsigned char __g;
  41. unsigned char __h;
  42. unsigned char __i;
  43. unsigned char __j;
  44. unsigned char __k;
  45. };
  46. static_assert(sizeof(Guid) == sizeof(::_GUID), "Incorrect size for Guid");
  47. static_assert(sizeof(__rcGUID_t) == sizeof(::_GUID), "Incorrect size for __rcGUID_t");
  48. ////////////////////////////////////////////////////////////////////////////////
  49. inline Guid::Guid() : __a(0), __b(0), __c(0), __d(0), __e(0), __f(0), __g(0), __h(0), __i(0), __j(0), __k(0)
  50. {
  51. }
  52. inline Guid::Guid(__rcGUID_t __guid) :
  53. __a(reinterpret_cast<const __s_GUID&>(__guid).Data1),
  54. __b(reinterpret_cast<const __s_GUID&>(__guid).Data2),
  55. __c(reinterpret_cast<const __s_GUID&>(__guid).Data3),
  56. __d(reinterpret_cast<const __s_GUID&>(__guid).Data4[0]),
  57. __e(reinterpret_cast<const __s_GUID&>(__guid).Data4[1]),
  58. __f(reinterpret_cast<const __s_GUID&>(__guid).Data4[2]),
  59. __g(reinterpret_cast<const __s_GUID&>(__guid).Data4[3]),
  60. __h(reinterpret_cast<const __s_GUID&>(__guid).Data4[4]),
  61. __i(reinterpret_cast<const __s_GUID&>(__guid).Data4[5]),
  62. __j(reinterpret_cast<const __s_GUID&>(__guid).Data4[6]),
  63. __k(reinterpret_cast<const __s_GUID&>(__guid).Data4[7])
  64. {
  65. }
  66. inline Guid::operator ::__rcGUID_t()
  67. {
  68. return reinterpret_cast<__rcGUID_t>(*this);
  69. }
  70. inline bool Guid::Equals(Guid __guidArg)
  71. {
  72. return *this == __guidArg;
  73. }
  74. inline bool Guid::Equals(__rcGUID_t __guidArg)
  75. {
  76. return *this == static_cast< Guid>(__guidArg);
  77. }
  78. inline bool operator==(Guid __aArg, Guid __bArg)
  79. {
  80. auto __a = reinterpret_cast<unsigned long*>(&__aArg);
  81. auto __b = reinterpret_cast<unsigned long*>(&__bArg);
  82. return (__a[0] == __b[0] && __a[1] == __b[1] && __a[2] == __b[2] && __a[3] == __b[3]);
  83. }
  84. inline bool operator!=(Guid __aArg, Guid __bArg)
  85. {
  86. return !(__aArg == __bArg);
  87. }
  88. inline bool operator<(Guid __aArg, Guid __bArg)
  89. {
  90. auto __a = reinterpret_cast<unsigned long*>(&__aArg);
  91. auto __b = reinterpret_cast<unsigned long*>(&__bArg);
  92. if (__a[0] != __b[0])
  93. {
  94. return __a[0] < __b[0];
  95. }
  96. if (__a[1] != __b[1])
  97. {
  98. return __a[1] < __b[1];
  99. }
  100. if (__a[2] != __b[2])
  101. {
  102. return __a[2] < __b[2];
  103. }
  104. if (__a[3] != __b[3])
  105. {
  106. return __a[3] < __b[3];
  107. }
  108. return false;
  109. }
  110. inline Guid::Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, unsigned __int8 __dArg,
  111. unsigned __int8 __eArg, unsigned __int8 __fArg, unsigned __int8 __gArg, unsigned __int8 __hArg,
  112. unsigned __int8 __iArg, unsigned __int8 __jArg, unsigned __int8 __kArg) :
  113. __a(__aArg), __b(__bArg), __c(__cArg), __d(__dArg), __e(__eArg), __f(__fArg), __g(__gArg), __h(__hArg), __i(__iArg), __j(__jArg), __k(__kArg)
  114. {
  115. }
  116. inline Guid::Guid(unsigned int __aArg, unsigned short __bArg, unsigned short __cArg, const unsigned __int8 __dArg[8]) :
  117. __a(__aArg), __b(__bArg), __c(__cArg)
  118. {
  119. __d = __dArg[0];
  120. __e = __dArg[1];
  121. __f = __dArg[2];
  122. __g = __dArg[3];
  123. __h = __dArg[4];
  124. __i = __dArg[5];
  125. __j = __dArg[6];
  126. __k = __dArg[7];
  127. }
  128. __declspec(selectany) Guid __winrt_GUID_NULL(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
  129. //
  130. //// Don't want to define the real IUnknown from unknown.h here. That would means if the user has
  131. //// any broken code that uses it, compile errors will take the form of e.g.:
  132. //// predefined C++ WinRT types (compiler internal)(41) : see declaration of 'IUnknown::QueryInterface'
  133. //// This is not helpful. If they use IUnknown, we still need to point them to the actual unknown.h so
  134. //// that they can see the original definition.
  135. ////
  136. //// For WinRT, we'll instead have a parallel COM interface hierarchy for basic interfaces starting with _.
  137. //// The type mismatch is not an issue. COM passes types through GUID / void* combos - the original type
  138. //// doesn't come into play unless the user static_casts an implementation type to one of these, but
  139. //// the WinRT implementation types are hidden.
  140. __interface __declspec(uuid("00000000-0000-0000-C000-000000000046")) __abi_IUnknown
  141. {
  142. public:
  143. virtual long __stdcall __abi_QueryInterface(Guid&, void**) = 0;
  144. virtual unsigned long __stdcall __abi_AddRef() = 0;
  145. virtual unsigned long __stdcall __abi_Release() = 0;
  146. };
  147. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseNotImplementedException();
  148. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseInvalidCastException();
  149. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseNullReferenceException();
  150. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseOperationCanceledException();
  151. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseFailureException();
  152. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseAccessDeniedException();
  153. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseOutOfMemoryException();
  154. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseInvalidArgumentException();
  155. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseOutOfBoundsException();
  156. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseChangedStateException();
  157. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseClassNotRegisteredException();
  158. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseWrongThreadException();
  159. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseDisconnectedException();
  160. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseObjectDisposedException();
  161. __declspec(dllexport) __declspec(noreturn) void __stdcall __abi_WinRTraiseCOMException(long);
  162. __declspec(noreturn) inline void __stdcall __abi_WinRTraiseException(long __hrArg)
  163. {
  164. switch (__hrArg)
  165. {
  166. case 0x80004001L: // E_NOTIMPL
  167. __abi_WinRTraiseNotImplementedException();
  168. case 0x80004002L: // E_NOINTERFACE
  169. __abi_WinRTraiseInvalidCastException();
  170. case 0x80004003L: // E_POINTER
  171. __abi_WinRTraiseNullReferenceException();
  172. case 0x80004004L: // E_ABORT
  173. __abi_WinRTraiseOperationCanceledException();
  174. case 0x80004005L: // E_FAIL
  175. __abi_WinRTraiseFailureException();
  176. case 0x80070005L: // E_ACCESSDENIED
  177. __abi_WinRTraiseAccessDeniedException();
  178. case 0x8007000EL: // E_OUTOFMEMORY
  179. __abi_WinRTraiseOutOfMemoryException();
  180. case 0x80070057L: // E_INVALIDARG
  181. __abi_WinRTraiseInvalidArgumentException();
  182. case 0x8000000BL: // E_BOUNDS
  183. __abi_WinRTraiseOutOfBoundsException();
  184. case 0x8000000CL: // E_CHANGED_STATE
  185. __abi_WinRTraiseChangedStateException();
  186. case 0x80040154L: // REGDB_E_CLASSNOTREG
  187. __abi_WinRTraiseClassNotRegisteredException();
  188. case 0x8001010EL: // RPC_E_WRONG_THREAD
  189. __abi_WinRTraiseWrongThreadException();
  190. case 0x80010108L: // RPC_E_DISCONNECTED
  191. __abi_WinRTraiseDisconnectedException();
  192. case 0x80000013L: // RO_E_CLOSED
  193. __abi_WinRTraiseObjectDisposedException();
  194. default:
  195. __abi_WinRTraiseCOMException(__hrArg);
  196. break;
  197. }
  198. }
  199. struct __abi_CaptureBase
  200. {
  201. protected:
  202. virtual __stdcall ~__abi_CaptureBase() {}
  203. public:
  204. static const size_t __smallCaptureSize = 4 * sizeof(void*);
  205. void* operator new(size_t __sizeArg, void* __pSmallCaptureArg)
  206. {
  207. if (__sizeArg > __smallCaptureSize)
  208. {
  209. return reinterpret_cast<__abi_CaptureBase*>(HeapAlloc(GetProcessHeap(), 0, __sizeArg));
  210. }
  211. return __pSmallCaptureArg;
  212. }
  213. void operator delete(void* __ptrArg, void* __pSmallCaptureArg)
  214. {
  215. __abi_CaptureBase* __pThis = static_cast<__abi_CaptureBase*>(__ptrArg);
  216. __pThis->Delete(__pThis, __pSmallCaptureArg);
  217. }
  218. inline void* GetVFunction(int __slotArg)
  219. {
  220. return (*reinterpret_cast<void***>(this))[__slotArg];
  221. }
  222. void Delete(__abi_CaptureBase* __pThisArg, void* __pSmallCaptureArg)
  223. {
  224. __pThisArg->~__abi_CaptureBase();
  225. if (__pThisArg != __pSmallCaptureArg)
  226. {
  227. HeapFree(GetProcessHeap(), 0, __pThisArg);
  228. }
  229. }
  230. };
  231. struct __abi_CapturePtr
  232. {
  233. char* smallCapture[__abi_CaptureBase::__smallCaptureSize];
  234. __abi_CaptureBase* ptr;
  235. __abi_CapturePtr() : ptr(reinterpret_cast<__abi_CaptureBase*>(smallCapture)) {}
  236. ~__abi_CapturePtr()
  237. {
  238. ptr->Delete(ptr, smallCapture);
  239. }
  240. };
  241. template <typename __TFunctor, typename __TReturnType>
  242. struct __abi_FunctorCapture0 : public __abi_CaptureBase
  243. {
  244. __TFunctor functor;
  245. __abi_FunctorCapture0(__TFunctor __functor) : functor(__functor) {}
  246. virtual __TReturnType __stdcall Invoke() { return functor(); }
  247. };
  248. template <typename __TFunctor, typename __TReturnType, typename __TArg0>
  249. struct __abi_FunctorCapture1 : public __abi_CaptureBase
  250. {
  251. __TFunctor functor;
  252. __abi_FunctorCapture1(__TFunctor __functor) : functor(__functor) {}
  253. virtual __TReturnType __stdcall Invoke(__TArg0 __arg0) { return functor(__arg0); }
  254. };
  255. template <typename __TFunctor, typename __TReturnType, typename __TArg0, typename __TArg1>
  256. struct __abi_FunctorCapture2 : public __abi_CaptureBase
  257. {
  258. __TFunctor functor;
  259. __abi_FunctorCapture2(__TFunctor __functor) : functor(__functor) {}
  260. virtual __TReturnType __stdcall Invoke(__TArg0 __arg0, __TArg1 __arg1) { return functor(__arg0, __arg1); }
  261. };
  262. template <typename __TFunctor, typename __TReturnType, typename __TArg0, typename __TArg1, typename __TArg2>
  263. struct __abi_FunctorCapture3 : public __abi_CaptureBase
  264. {
  265. __TFunctor functor;
  266. __abi_FunctorCapture3(__TFunctor __functor) : functor(__functor) {}
  267. virtual __TReturnType __stdcall Invoke(__TArg0 __arg0, __TArg1 __arg1, __TArg2 __arg2) { return functor(__arg0, __arg1, __arg2); }
  268. };
  269. template <typename __TFunctor, typename __TReturnType, typename __TArg0, typename __TArg1, typename __TArg2, typename __TArg3>
  270. struct __abi_FunctorCapture4 : public __abi_CaptureBase
  271. {
  272. __TFunctor functor;
  273. __abi_FunctorCapture4(__TFunctor __functor) : functor(__functor) {}
  274. virtual __TReturnType __stdcall Invoke(__TArg0 __arg0, __TArg1 __arg1, __TArg2 __arg2, __TArg3 __arg3) { return functor(__arg0, __arg1, __arg2, __arg3); }
  275. };
  276. template <typename __TFunctor, typename __TReturnType, typename __TArg0, typename __TArg1, typename __TArg2, typename __TArg3, typename __TArg4>
  277. struct __abi_FunctorCapture5 : public __abi_CaptureBase
  278. {
  279. __TFunctor functor;
  280. __abi_FunctorCapture5(__TFunctor __functor) : functor(__functor) {}
  281. virtual __TReturnType __stdcall Invoke(__TArg0 __arg0, __TArg1 __arg1, __TArg2 __arg2, __TArg3 __arg3, __TArg4 __arg4) { return functor(__arg0, __arg1, __arg2, __arg3, __arg4); }
  282. };
  283. template <typename __TFunctor, typename __TReturnType, typename __TArg0, typename __TArg1, typename __TArg2, typename __TArg3, typename __TArg4, typename __TArg5>
  284. struct __abi_FunctorCapture6 : public __abi_CaptureBase
  285. {
  286. __TFunctor functor;
  287. __abi_FunctorCapture6(__TFunctor __functor) : functor(__functor) {}
  288. virtual __TReturnType __stdcall Invoke(__TArg0 __arg0, __TArg1 __arg1, __TArg2 __arg2, __TArg3 __arg3, __TArg4 __arg4, __TArg5 __arg5) { return functor(__arg0, __arg1, __arg2, __arg3, __arg4, __arg5); }
  289. };
  290. template <typename __TFunctor, typename __TReturnType, typename __TArg0, typename __TArg1, typename __TArg2, typename __TArg3, typename __TArg4, typename __TArg5, typename __TArg6>
  291. struct __abi_FunctorCapture7 : public __abi_CaptureBase
  292. {
  293. __TFunctor functor;
  294. __abi_FunctorCapture7(__TFunctor __functor) : functor(__functor) {}
  295. virtual __TReturnType __stdcall Invoke(__TArg0 __arg0, __TArg1 __arg1, __TArg2 __arg2, __TArg3 __arg3, __TArg4 __arg4, __TArg5 __arg5, __TArg6 __arg6) { return functor(__arg0, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6); }
  296. };
  297. template <typename __TFunctor, typename __TReturnType, typename __TArg0, typename __TArg1, typename __TArg2, typename __TArg3, typename __TArg4, typename __TArg5, typename __TArg6, typename __TArg7>
  298. struct __abi_FunctorCapture8 : public __abi_CaptureBase
  299. {
  300. __TFunctor functor;
  301. __abi_FunctorCapture8(__TFunctor __functor) : functor(__functor) {}
  302. virtual __TReturnType __stdcall Invoke(__TArg0 __arg0, __TArg1 __arg1, __TArg2 __arg2, __TArg3 __arg3, __TArg4 __arg4, __TArg5 __arg5, __TArg6 __arg6, __TArg7 __arg7) { return functor(__arg0, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7); }
  303. };
  304. template <typename __TFunctor, typename __TReturnType, typename __TArg0, typename __TArg1, typename __TArg2, typename __TArg3, typename __TArg4, typename __TArg5, typename __TArg6, typename __TArg7, typename __TArg8>
  305. struct __abi_FunctorCapture9 : public __abi_CaptureBase
  306. {
  307. __TFunctor functor;
  308. __abi_FunctorCapture9(__TFunctor __functor) : functor(__functor) {}
  309. virtual __TReturnType __stdcall Invoke(__TArg0 __arg0, __TArg1 __arg1, __TArg2 __arg2, __TArg3 __arg3, __TArg4 __arg4, __TArg5 __arg5, __TArg6 __arg6, __TArg7 __arg7, __TArg8 __arg8) { return functor(__arg0, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, __arg8); }
  310. };
  311. template <typename __TFunctor, typename __TReturnType, typename __TArg0, typename __TArg1, typename __TArg2, typename __TArg3, typename __TArg4, typename __TArg5, typename __TArg6, typename __TArg7, typename __TArg8, typename __TArg9>
  312. struct __abi_FunctorCapture10 : public __abi_CaptureBase
  313. {
  314. __TFunctor functor;
  315. __abi_FunctorCapture10(__TFunctor __functor) : functor(__functor) {}
  316. virtual __TReturnType __stdcall Invoke(__TArg0 __arg0, __TArg1 __arg1, __TArg2 __arg2, __TArg3 __arg3, __TArg4 __arg4, __TArg5 __arg5, __TArg6 __arg6, __TArg7 __arg7, __TArg8 __arg8, __TArg9 __arg9) { return functor(__arg0, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6, __arg7, __arg8, __arg9); }
  317. };
  318. #define __is_winrt_array(type) (type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt8Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_Int16Array ||\
  319. type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt16Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_Int32Array ||\
  320. type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt32Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_Int64Array ||\
  321. type == ABI::Windows::Foundation::PropertyType::PropertyType_UInt64Array || type == ABI::Windows::Foundation::PropertyType::PropertyType_SingleArray ||\
  322. type == ABI::Windows::Foundation::PropertyType::PropertyType_DoubleArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_Char16Array ||\
  323. type == ABI::Windows::Foundation::PropertyType::PropertyType_BooleanArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_StringArray ||\
  324. type == ABI::Windows::Foundation::PropertyType::PropertyType_InspectableArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_DateTimeArray ||\
  325. type == ABI::Windows::Foundation::PropertyType::PropertyType_TimeSpanArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_GuidArray ||\
  326. type == ABI::Windows::Foundation::PropertyType::PropertyType_PointArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_SizeArray ||\
  327. type == ABI::Windows::Foundation::PropertyType::PropertyType_RectArray || type == ABI::Windows::Foundation::PropertyType::PropertyType_OtherTypeArray)
  328. template<typename _Type, bool bUnknown = std::is_base_of<IUnknown, _Type>::value>
  329. struct winrt_type
  330. {
  331. };
  332. template<typename _Type>
  333. struct winrt_type<_Type, true>
  334. {
  335. static IUnknown* create(_Type* _ObjInCtx) {
  336. return reinterpret_cast<IUnknown*>(_ObjInCtx);
  337. }
  338. static IID getuuid() { return __uuidof(_Type); }
  339. static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_OtherType;
  340. };
  341. template <typename _Type>
  342. struct winrt_type<_Type, false>
  343. {
  344. static IUnknown* create(_Type* _ObjInCtx) {
  345. Microsoft::WRL::ComPtr<IInspectable> _PObj;
  346. Microsoft::WRL::ComPtr<IActivationFactory> objFactory;
  347. HRESULT hr = Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), objFactory.ReleaseAndGetAddressOf());
  348. if (FAILED(hr)) return nullptr;
  349. Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValueStatics> spPropVal;
  350. if (SUCCEEDED(hr))
  351. hr = objFactory.As(&spPropVal);
  352. if (SUCCEEDED(hr)) {
  353. hr = winrt_type<_Type>::create(spPropVal.Get(), _ObjInCtx, _PObj.GetAddressOf());
  354. if (SUCCEEDED(hr))
  355. return reinterpret_cast<IUnknown*>(_PObj.Detach());
  356. }
  357. return nullptr;
  358. }
  359. static IID getuuid() { return __uuidof(ABI::Windows::Foundation::IPropertyValue); }
  360. static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_OtherType;
  361. };
  362. template<>
  363. struct winrt_type<void>
  364. {
  365. static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, void* _ObjInCtx, IInspectable** ppInsp) {
  366. (void)_ObjInCtx;
  367. return spPropVal->CreateEmpty(ppInsp);
  368. }
  369. static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
  370. };
  371. #define MAKE_TYPE(Type, Name) template<>\
  372. struct winrt_type<Type>\
  373. {\
  374. static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, Type* _ObjInCtx, IInspectable** ppInsp) {\
  375. return spPropVal->Create##Name(*_ObjInCtx, ppInsp);\
  376. }\
  377. static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_##Name;\
  378. };
  379. template<typename _Type>
  380. struct winrt_array_type
  381. {
  382. static IUnknown* create(_Type* _ObjInCtx, size_t N) {
  383. Microsoft::WRL::ComPtr<IInspectable> _PObj;
  384. Microsoft::WRL::ComPtr<IActivationFactory> objFactory;
  385. HRESULT hr = Windows::Foundation::GetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(), objFactory.ReleaseAndGetAddressOf());
  386. if (FAILED(hr)) return nullptr;
  387. Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IPropertyValueStatics> spPropVal;
  388. if (SUCCEEDED(hr))
  389. hr = objFactory.As(&spPropVal);
  390. if (SUCCEEDED(hr)) {
  391. hr = winrt_array_type<_Type>::create(spPropVal.Get(), N, _ObjInCtx, _PObj.GetAddressOf());
  392. if (SUCCEEDED(hr))
  393. return reinterpret_cast<IUnknown*>(_PObj.Detach());
  394. }
  395. return nullptr;
  396. }
  397. static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_OtherTypeArray;
  398. };
  399. template<int>
  400. struct winrt_prop_type {};
  401. template <>
  402. struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_Empty> {
  403. typedef void _Type;
  404. };
  405. template <>
  406. struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_OtherType> {
  407. typedef void _Type;
  408. };
  409. template <>
  410. struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_OtherTypeArray> {
  411. typedef void _Type;
  412. };
  413. #define MAKE_PROP(Prop, Type) template <>\
  414. struct winrt_prop_type<ABI::Windows::Foundation::PropertyType_##Prop> {\
  415. typedef Type _Type;\
  416. };
  417. #define MAKE_ARRAY_TYPE(Type, Name) MAKE_PROP(Name, Type)\
  418. MAKE_PROP(Name##Array, Type*)\
  419. MAKE_TYPE(Type, Name)\
  420. template<>\
  421. struct winrt_array_type<Type*>\
  422. {\
  423. static HRESULT create(ABI::Windows::Foundation::IPropertyValueStatics* spPropVal, UINT32 __valueSize, Type** _ObjInCtx, IInspectable** ppInsp) {\
  424. return spPropVal->Create##Name##Array(__valueSize, *_ObjInCtx, ppInsp);\
  425. }\
  426. static const ABI::Windows::Foundation::PropertyType _PropType = ABI::Windows::Foundation::PropertyType::PropertyType_##Name##Array;\
  427. static std::vector<Type> PropertyValueToVector(ABI::Windows::Foundation::IPropertyValue* propValue)\
  428. {\
  429. UINT32 uLen = 0;\
  430. Type* pArray = nullptr;\
  431. propValue->Get##Name##Array(&uLen, &pArray);\
  432. return std::vector<Type>(pArray, pArray + uLen);\
  433. }\
  434. };
  435. MAKE_ARRAY_TYPE(BYTE, UInt8)
  436. MAKE_ARRAY_TYPE(INT16, Int16)
  437. MAKE_ARRAY_TYPE(UINT16, UInt16)
  438. MAKE_ARRAY_TYPE(INT32, Int32)
  439. MAKE_ARRAY_TYPE(UINT32, UInt32)
  440. MAKE_ARRAY_TYPE(INT64, Int64)
  441. MAKE_ARRAY_TYPE(UINT64, UInt64)
  442. MAKE_ARRAY_TYPE(FLOAT, Single)
  443. MAKE_ARRAY_TYPE(DOUBLE, Double)
  444. MAKE_ARRAY_TYPE(WCHAR, Char16)
  445. //MAKE_ARRAY_TYPE(boolean, Boolean) //conflict with identical type in C++ of BYTE/UInt8
  446. MAKE_ARRAY_TYPE(HSTRING, String)
  447. MAKE_ARRAY_TYPE(IInspectable*, Inspectable)
  448. MAKE_ARRAY_TYPE(GUID, Guid)
  449. MAKE_ARRAY_TYPE(ABI::Windows::Foundation::DateTime, DateTime)
  450. MAKE_ARRAY_TYPE(ABI::Windows::Foundation::TimeSpan, TimeSpan)
  451. MAKE_ARRAY_TYPE(ABI::Windows::Foundation::Point, Point)
  452. MAKE_ARRAY_TYPE(ABI::Windows::Foundation::Size, Size)
  453. MAKE_ARRAY_TYPE(ABI::Windows::Foundation::Rect, Rect)
  454. template < typename T >
  455. struct DerefHelper
  456. {
  457. typedef T DerefType;
  458. };
  459. template < typename T >
  460. struct DerefHelper<T*>
  461. {
  462. typedef T DerefType;
  463. };
  464. #define __is_valid_winrt_type(_Type) (std::is_void<_Type>::value || \
  465. std::is_same<_Type, BYTE>::value || \
  466. std::is_same<_Type, INT16>::value || \
  467. std::is_same<_Type, UINT16>::value || \
  468. std::is_same<_Type, INT32>::value || \
  469. std::is_same<_Type, UINT32>::value || \
  470. std::is_same<_Type, INT64>::value || \
  471. std::is_same<_Type, UINT64>::value || \
  472. std::is_same<_Type, FLOAT>::value || \
  473. std::is_same<_Type, DOUBLE>::value || \
  474. std::is_same<_Type, WCHAR>::value || \
  475. std::is_same<_Type, boolean>::value || \
  476. std::is_same<_Type, HSTRING>::value || \
  477. std::is_same<_Type, IInspectable *>::value || \
  478. std::is_base_of<Microsoft::WRL::Details::RuntimeClassBase, _Type>::value || \
  479. std::is_base_of<IInspectable, typename DerefHelper<_Type>::DerefType>::value || \
  480. std::is_same<_Type, GUID>::value || \
  481. std::is_same<_Type, ABI::Windows::Foundation::DateTime>::value || \
  482. std::is_same<_Type, ABI::Windows::Foundation::TimeSpan>::value || \
  483. std::is_same<_Type, ABI::Windows::Foundation::Point>::value || \
  484. std::is_same<_Type, ABI::Windows::Foundation::Size>::value || \
  485. std::is_same<_Type, ABI::Windows::Foundation::Rect>::value || \
  486. std::is_same<_Type, BYTE*>::value || \
  487. std::is_same<_Type, INT16*>::value || \
  488. std::is_same<_Type, UINT16*>::value || \
  489. std::is_same<_Type, INT32*>::value || \
  490. std::is_same<_Type, UINT32*>::value || \
  491. std::is_same<_Type, INT64*>::value || \
  492. std::is_same<_Type, UINT64*>::value || \
  493. std::is_same<_Type, FLOAT*>::value || \
  494. std::is_same<_Type, DOUBLE*>::value || \
  495. std::is_same<_Type, WCHAR*>::value || \
  496. std::is_same<_Type, boolean*>::value || \
  497. std::is_same<_Type, HSTRING*>::value || \
  498. std::is_same<_Type, IInspectable **>::value || \
  499. std::is_same<_Type, GUID*>::value || \
  500. std::is_same<_Type, ABI::Windows::Foundation::DateTime*>::value || \
  501. std::is_same<_Type, ABI::Windows::Foundation::TimeSpan*>::value || \
  502. std::is_same<_Type, ABI::Windows::Foundation::Point*>::value || \
  503. std::is_same<_Type, ABI::Windows::Foundation::Size*>::value || \
  504. std::is_same<_Type, ABI::Windows::Foundation::Rect*>::value)
  505. #endif