Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

85 linhas
3.5KB

  1. //*********************************************************
  2. //
  3. // Copyright (c) Microsoft. All rights reserved.
  4. // This code is licensed under the MIT License.
  5. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
  6. // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  7. // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  8. // PARTICULAR PURPOSE AND NONINFRINGEMENT.
  9. //
  10. //*********************************************************
  11. #ifndef __WIL_WRL_INCLUDED
  12. #define __WIL_WRL_INCLUDED
  13. #include <wrl.h>
  14. #include "result.h"
  15. #include "common.h" // wistd type_traits helpers
  16. namespace wil
  17. {
  18. #ifdef WIL_ENABLE_EXCEPTIONS
  19. #pragma region Object construction helpers that throw exceptions
  20. /** Used to construct a RuntimeClass based object that uses 2 phase construction.
  21. Construct a RuntimeClass based object that uses 2 phase construction (by implementing
  22. RuntimeClassInitialize() and returning error codes for failures.
  23. ~~~~
  24. // SomeClass uses 2 phase initialization by implementing RuntimeClassInitialize()
  25. auto someClass = MakeAndInitializeOrThrow<SomeClass>(L"input", true);
  26. ~~~~ */
  27. template <typename T, typename... TArgs>
  28. Microsoft::WRL::ComPtr<T> MakeAndInitializeOrThrow(TArgs&&... args)
  29. {
  30. Microsoft::WRL::ComPtr<T> obj;
  31. THROW_IF_FAILED(Microsoft::WRL::MakeAndInitialize<T>(&obj, Microsoft::WRL::Details::Forward<TArgs>(args)...));
  32. return obj;
  33. }
  34. /** Used to construct an RuntimeClass based object that uses exceptions in its constructor (and does
  35. not require 2 phase construction).
  36. ~~~~
  37. // SomeClass uses exceptions for error handling in its constructor.
  38. auto someClass = MakeOrThrow<SomeClass>(L"input", true);
  39. ~~~~ */
  40. template <typename T, typename... TArgs>
  41. Microsoft::WRL::ComPtr<T> MakeOrThrow(TArgs&&... args)
  42. {
  43. // This is how you can detect the presence of RuntimeClassInitialize() and find dangerous use.
  44. // Unfortunately this produces false positives as all RuntimeClass derived classes have
  45. // a RuntimeClassInitialize() method from their base class.
  46. // static_assert(!std::is_member_function_pointer<decltype(&T::RuntimeClassInitialize)>::value,
  47. // "class has a RuntimeClassInitialize member, use MakeAndInitializeOrThrow instead");
  48. auto obj = Microsoft::WRL::Make<T>(Microsoft::WRL::Details::Forward<TArgs>(args)...);
  49. THROW_IF_NULL_ALLOC(obj.Get());
  50. return obj;
  51. }
  52. #pragma endregion
  53. #endif // WIL_ENABLE_EXCEPTIONS
  54. /** By default WRL Callback objects are not agile, use this to make an agile one. Replace use of Callback<> with MakeAgileCallback<>.
  55. Will return null on failure, translate that into E_OUTOFMEMORY using XXX_IF_NULL_ALLOC()
  56. from wil\result.h to test the result. */
  57. template<typename TDelegateInterface, typename ...Args>
  58. ::Microsoft::WRL::ComPtr<TDelegateInterface> MakeAgileCallbackNoThrow(Args&&... args) WI_NOEXCEPT
  59. {
  60. using namespace Microsoft::WRL;
  61. return Callback<Implements<RuntimeClassFlags<ClassicCom>, TDelegateInterface, FtmBase>>(wistd::forward<Args>(args)...);
  62. }
  63. #ifdef WIL_ENABLE_EXCEPTIONS
  64. template<typename TDelegateInterface, typename ...Args>
  65. ::Microsoft::WRL::ComPtr<TDelegateInterface> MakeAgileCallback(Args&&... args)
  66. {
  67. auto result = MakeAgileCallbackNoThrow<TDelegateInterface, Args...>(wistd::forward<Args>(args)...);
  68. THROW_IF_NULL_ALLOC(result);
  69. return result;
  70. }
  71. #endif // WIL_ENABLE_EXCEPTIONS
  72. } // namespace wil
  73. #endif // __WIL_WRL_INCLUDED