Last time, we looked at conditionally supporting a COM interface in C++/WinRT. Today, we’ll solve the same problem for WRL.
For WRL, you directly override the QueryÂInterface
method. and GetÂIids
methods.
struct Widget : Microsoft::WRL::RuntimeClass< Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::WinRt>, ::ABI::Contoso::IWidget, ::Windows::Foundation::IStringable> { STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) { // If "Stringable" is not enabled, // then don't support IStringable. if (riid == __uuidof(::IStringable) && !is_stringable_enabled()) { *ppvObject = nullptr; return E_NOINTERFACE; } return RuntimeClass::QueryInterface(riid, ppvObject); } // Implement IWidget methods STDMETHOD(WidgetMethod)(); // Implement IStringable methods STDMETHOD(ToString)(HSTRING* result); };
This is basically the same as the C++/WinRT version: When a query comes in for IStringable
, we check whether IStringable
support is enabled. If not, then we set the result to nullptr
and return E_
. Otherwise, we forward the call to the base class to continue normally.
Bonus chatter: Commenter Euro Micelli points out that you should also read the previous entry on the requirement for stability of is_
.
I think it’s important to highlight (especially for people who find this post and don’t read yesterday’s about the WinRT version), that COM requires that the answer provide by is_stringable_enabled() must never change for a given object. Once a given COM object responds that it supports the requested interface, it must always support it; and once it responds that it doesn’t support it, it must never answer that it does.