-
Notifications
You must be signed in to change notification settings - Fork 249
Windows Runtime helpers
In the wil/winrt.h
and wil/wrl.h
header files,
WIL provides helpers to facilitate consumption of Windows Runtime APIs
at the ABI (unprojected) layer:
#include <wil/winrt.h>
#include <wil/wrl.h>
These helpers work well together with the smart pointers and other WinRT and COM wrappers in
wil/com.h
.
Note: These helpers have been superseded by the C++/WinRT projection. You should prefer C++/WinRT in new code, perhaps along with WIL's integration with C++/WinRT.
The time helpers require that <time.h>
be included before including wil/winrt.h
.
long long const SecondsToStartOf1970 = 0x2b6109100;
The number of seconds from the Windows Runtime epoch to January 1, 1970. The Windows Runtime epoch is January 1, 1601.
long long const HundredNanoSecondsInSecond = 10000000LL;
The number of Windows Runtime time units per second. One Windows Runtime time unit is 100ns.
__time64_t DateTime_to_time_t(DateTime dateTime);
Converts a Windows Runtime DateTime
to a 64-bit C runtime (Unix-style) time value. The 64-bit C runtime time format has a larger range than the Windows Runtime DateTime
format, but cannot represent fractional seconds. Fractional seconds are discarded in the conversion.
The C++/WinRT equivalent is
winrt::clock::to_time_t()
.
DateTime time_t_to_DateTime(__time64_t timeT);
Converts a 64-bit C runtime (Unix-style) time value to a Windows Runtime DateTime
.
The result is undefined if the 64-bit C runtime time value represents a point in time that cannot be represented by a DateTime
(approximate range 27,400 B.C.E to 29,000 C.E.).
The C++/WinRT equivalent is
winrt::clock::from_time_t()
.
bool HasEmbeddedNull(_In_opt_ HSTRING value);
Returns true
if the string contains an embedded null character.
The C++/WinRT equivalent is winrt::embedded_null(hstring const&)
.
The TwoPhaseHStringConstructor
is a helper class for constructing HSTRING
objects. It is movable but not copyable.
The C++/WinRT equivalent is to construct the string
using std::wstring
or any other convenient string container,
then construct an hstring
from it.
// Preallocate space for a string of a specific length.
// The length does not include the null terminator.
auto stringConstructor = wil::TwoPhaseHStringConstructor::Preallocate(length);
RETURN_IF_NULL_ALLOC(stringConstructor.Get());
// Fill the buffer with exactly length characters.
RETURN_IF_FAILED(stream->Read(stringConstructor.Get(),
stringConstructor.ByteSize(), &bytesRead));
// Validate stream contents: Sizes must match, and
// preallocated null terminator must still be present.
RETURN_IF_FAILED(stringConstructor.Validate(bytesRead));
Microsoft::WRL::Wrappers::HString string;
string.Attach(stringConstructor.Promote());
Constructors
-
static TwoPhaseHStringConstructor TwoPhaseHStringConstructor::Preallocate(UINT32 characterLength)
(factory)
Create a newTwoPhaseHStringConstructor
that will eventually hold a string ofcharacterLength
characters (not counting the null terminator). -
TwoPhaseHStringConstructor(TwoPhaseHStringConstructor&& other)
(move constructor)
Transfer the state of aTwoPhaseHStringConstructor
to a new object.
Destructor
-
~TwoPhaseHStringConstructor
It is acceptable to destruct the object without callingPromote
. In that case, the construction of theHSTRING
is abandoned.
Methods
-
wchar_t* Get()
Returns a pointer to the buffer into which the string should be generated. -
ULONG ByteSize() const
Returns the size of the buffer in bytes. -
HRESULT Validate(ULONG bytesRead) const
Validates that the number of bytes is equal to the size of the buffer, not including the null terminator. Also validates that the buffer's null terminator has not been corrupted.Calling
Validate()
is optional. -
HSTRING Promote()
Construct the Windows RuntimeHSTRING
object from the information in the buffer. The caller is responsible for the lifetime of the resultingHSTRING
. It is typically placed into an RAII type such aswil::unique_hstring
. Once the string is promoted, the only thing you can do with the object is destruct it.The
Promote()
method fails fast on usage error, such as if the null terminator has been corrupted, or if you attempt toPromote()
twice.
Operators
-
operator PCWSTR() const
Returns the buffer into which the string was generated.
The hstring_less
and hstring_insensitive_less
structures perform
case-sensitive or case-insensitive (respectively) ordinal string comparisons
on HSTRING
objects.
They are
transparent
comparators
which permit more efficient use of HSTRING
s as keys in associative
containers such as std::set
and std::map
.
Transparency permits looking up items using
any of the following:
HSTRING
const Microsoft::WRL::Wrappers::HString&
const Microsoft::WRL::Wrappers::HStringReference&
const wil::unique_hstring&
-
const wchar_t*
(null-terminated string, null pointer treated as empty string) -
const std::string&
(if exceptions are enabled)
Note that the const wchar_t*
version cannot be used to search for
strings with embedded nulls, because the embedded null will be
treated as a string terminator.
The hstring_less
structure is used as the default std::less
comparator for Microsoft::WRL::HString
and
wil::unique_hstring
.
Examples:
std::map<Microsoft::WRL::HString, int, wil::hstring_less> map;
Microsoft::WRL::HString str = ...;
wil::unique_hstring uniqueStr = ...;
wchar_t buffer[...];
map.find(str); // Traditional lookup via Microsoft::WRL::HString
map.find(str.Get()); // Transparent lookup accepts HSTRING
map.find(uniqueStr); // Transparent lookup accepts wil::unique_hstring
map.find(L"literal"); // Transparent lookup accepts const wchar_t*
map.find(buffer); // Transparent lookup accepts wchar_t*
map.find(std::wstring(buffer)); // Transparent lookup accepts std::wstring
The get_range
adapters permit use of
range-based for loops
to iterate over Windows Runtime collections.
Adapter | Error model |
---|---|
get_range |
Exceptions |
get_range_nothrow |
Error codes |
get_range_failfast |
Fail fast |
C++/WinRT does not require an adapter.
Range-based for loops are natively supported over C++/WinRT collections
(anything that supports Windows.Foundation.IIterable<T>
).
See Ad-hoc range helpers for other iterator helpers.
Examples
// assume collection is IVector<T>*, IVectorView<T>*, or IIterable<T>*
for (auto const& element : wil::get_range(collection)) ...
for (auto const& element : wil::get_range_failfast(collection)) ...
for (auto const& element : wil::get_range_nothrow(collection)) ...
for (auto const& element : wil::get_range_nothrow(collection, &hr)) ...
In the case of get_range_nothrow
, an optional HRESULT*
parameter
receives the HRESULT
that caused the iteration to stop.
If the iterator ran to completion successfully,
or if the loop was explicitly exited with a break
statement,
then the value will be S_OK
.
Warnings
- It is the caller's responsibility to ensure that the
collection lifetime extends to the completion of the
for
loop. - The collection's lifetime must encompass the
use of the iterators you obtain from the
get_range
functions. - The iterators obtained from
get_range
andget_range_failfast
are bidirectional iterators which also support constant-time bidirectional advance. - The iterators obtained from
get_range_nothrow
function are input iterators which also support constant-time bidirectional advance. However, only one iterator may be dereferenced.
extern Microsoft::WRL::ComPtr<IVector<T>> GetCollection();
// WRONG! The smart pointer returned by GetCollection() is temporary
// and will be destructed before the loop body runs.
for (auto const& element : wil::get_range(GetCollection().Get())) ...
// FIXED! Explicitly extend the lifetime of the collection.
auto collection = GetCollection();
for (auto const& element : wil::get_range(collection.Get())) ...
// WRONG! The smart pointer returned by GetCollections() is temporary
// and will be destructed while there are still active iterators.
auto range = wil::get_range(GetCollection().Get());
auto it = std::lower_bound(range.begin(), range.end(), value);
// FIXED! Explicitly extend the lifetime of the collection.
auto collection = GetCollection();
auto range = wil::get_range(collection.Get());
auto it = std::lower_bound(range.begin(), range.end(), value);
// WRONG! The iterators produced by get_range_nothrow
// are not forward iterators.
auto collection = GetCollection();
auto range = wil::get_range_nothrow(collection.Get());
auto it = std::adjacent_find(range.begin(), range.end());
These functions permit basic operations with Windows Runtime asynchronous operations, but they have been superseded by C++/WinRT.
For all the asynchronous operation helpers,
the operation
can be
- An "action", which has no result:
IAsyncAction*
orIAsyncActionWithProgress<TProgress>*
- An "operation":
IAsyncOperation<TResult>*
orIAsyncOperationWithProgress<TResult, TProgress>*
These functions have been superseded by
C++/WinRT.
Prefer to use C++/WinRT and co_await
to consume asynchronous operations.
Function | Error model |
---|---|
run_when_complete |
Exceptions |
run_when_complete_nothrow |
Error codes |
(no fail fast version) |
The general shape of the run_when_complete
family of functions is
template<typename TAgility>
run_when_complete(operation, functor)
The TAgility
can be explicitly specified as Microsoft::WRL::FtmBase
to specify that the functor can be called on any thread.
By default, the functor will be called back in the same apartment.
The functor's operator()
can take one of the following forms:
- For an action:
HRESULT func(HRESULT hr);
void func(HRESULT hr);
- For an operation whose result is an interface type
HRESULT func(HRESULT hr, TResult* result);
void func(HRESULT hr, TResult* result);
- For an operation whose result is a value type
HRESULT func(HRESULT hr, TResult result);
void func(HRESULT hr, TResult result);
The hr
reports whether the asynchronous operation completed successfully.
The result
is the result of the asynchronous operation.
If the asynchronous operation failed, then result
is meaningless.
If the functor returns an HRESULT
, then that HRESULT
is the return value
of the continuation.
If the functor returns void
, then exceptions thrown by THROW_IF_FAILED
are caught and treated as the return value of the continuation.
The run_when_complete
function throws an exception if the continuation
cannot be scheduled.
The run_when_complete_nothrow
function returns an HRESULT
specifying
whether the continuation was successfully scheduled.
template<typename TAgility = IUnknown, typename TFunc>
void run_when_complete(IAsyncAction* operation, TFunc&& func);
template<typename TAgility = IUnknown, typename TProgress, typename TFunc>
void run_when_complete(IAsyncActionWithProgress<TProgress>* operation, TFunc&& func);
template<typename TAgility = IUnknown, typename TResult, typename TFunc>
void run_when_complete(IAsyncOperation<TResult>* operation, TFunc&& func);
template<typename TAgility = IUnknown, typename TResult, typename TProgress, typename TFunc>
void run_when_complete(IAsyncOperationWithProgress<TResult, TProgress>* operation,
TFunc&& func);
template<typename TAgility = IUnknown, typename TFunc>
HRESULT run_when_complete_nothrow(IAsyncAction* operation, TFunc&& func) noexcept;
template<typename TAgility = IUnknown, typename TProgress, typename TFunc>
HRESULT run_when_complete_nothrow(IAsyncActionWithProgress<TProgress>* operation,
TFunc&& func) noexcept;
template<typename TAgility = IUnknown, typename TResult, typename TFunc>
HRESULT run_when_complete_nothrow(IAsyncOperation<TResult>* operation, TFunc&& func) noexcept;
template<typename TAgility = IUnknown, typename TResult, typename TProgress, typename TFunc>
HRESULT run_when_complete_nothrow(IAsyncOperationWithProgress<TResult, TProgress>* operation,
TFunc&& func) noexcept;
Examples:
void CopyToParentFolderFireAndForget(IStorageFile* file)
{
Microsoft::WRL::ComPtr<IAsyncOperation<StorageFolder>> fileOperation;
THROW_iF_FAILED(file->GetParentAsync(&fileOperation));
// Must extend lifetime of "file" into the lambda.
run_when_complete(fileOperation.Get(),
[file = wil::com_ptr<IStorageFile>(file)](HRESULT result, IStorageFolder* folder)
{
THROW_IF_FAILED(result);
Microsoft::WRL::ComPtr<IAsyncOperation<StorageFolder>> copyOperation;
THROW_IF_FAILED(file->CopyAsync(folder, ©Operation));
run_when_complete(copyOperation.Get(),
[](HRESULT result, IStorageFile* /* copiedFile */)
{
THROW_IF_FAILED(result);
});
});
}
// To permit the continuation to run in any thread, use FtmBase.
run_when_complete<FtmBase>(fileOperation.Get(), [](HRESULT result, IStorageFile* file)
{
THROW_IF_FAILED(result);
DoSomethingWith(file);
});
Note that the lambda must extend the lifetimes of any objects it needs, because its execution is deferred until the completion of the asynchronous operation. In particular, it must not capture by reference.
Preferred C++/WinRT alternative:
// "file" parameter is non-const because we use it in the continuation.
winrt::fire_and_forget CopyToParentFolder(StorageFile file)
{
auto folder = co_await file.GetParentAsync();
co_await file.CopyAsync(folder);
}
These functions have been superseded by
C++/WinRT.
Prefer to use C++/WinRT and get()
to consume asynchronous operations synchronously.
Function | Error model |
---|---|
wait_for_completion |
Exceptions |
wait_for_completion_nothrow |
Error codes |
(no fail fast version) | |
wait_for_completion_or_timeout_nothrow |
Error codes |
call_and_wait_for_completion |
Exceptions |
These functions wait for an asynchronous operation to complete or be canceled. Use them to wait synchronously from background threads. Do not use them from UI threads or STA threads as reentrancy will result.
The general shape of the wait_for_completion
family of functions is
HRESULT hr = wait_for_completion_nothrow(operation, &result);
auto result = wait_for_completion(operation);
If the operation
is an action, then wait_for_completion_nothrow
has no result
parameter, and wait_for_completion
returns void
.
An optional final parameter of type COWAIT_FLAGS
can be provided to customize how the thread waits
for the operation to complete.
The default is COWAIT_DISPATCH_CALLS
.
If the function is unable to wait for the operation,
or if the operation does not complete successfully,
the error code is thrown (wait_for_completion
)
or returned (wait_for_completion_nothrow
).
No value is placed into result
.
void wait_for_completion(IAsyncAction* operation,
COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS);
void wait_for_completion(IAsyncActionWithProgress<TProgress>* operation,
COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS);
details::MapToSmartType<TResult>
wait_for_completion(IAsyncOperation<TResult>* operation,
COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS);
details::MapToSmartType<TResult>
wait_for_completion(IAsyncOperationWithProgress<TResult, TProgress>* operation,
COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS);
HRESULT wait_for_completion_nothrow(
IAsyncAction* operation,
COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) noexcept;
HRESULT wait_for_completion_nothrow(
IAsyncActionWithProgress<TProgress>* operation,
COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) noexcept;
HRESULT wait_for_completion_nothrow(
IAsyncOperation<TResult>* operation,
details::MapAsyncOpResultType<TResult>::type* result,
COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) noexcept;
HRESULT wait_for_completion_nothrow(
IAsyncOperationWithProgress<TResult, TProgress>* operation,
details::MapAsyncOpResultType<TResult>::type* result,
COWAIT_FLAGS flags = COWAIT_DISPATCH_CALLS) noexcept;
details::MapToSmartType<TResult>
depends on the nature of TResult
:
- If
TResult
isHSTRING
, thendetails::MapToSmartType<TResult>
isMicrosoft::WRL::Wrappers::HString
, with an additional methodReleaseAndGetAddressOf
. - If
TResult
is an interface type, thendetails::MapToSmartType<TResult>
isMicrosoft::WRL::ComPtr<TResult>
. - If
TResult
is a value type, thendetails::MapToSmartType<TResult>
is a custom type which behaves similarly toMicrosoft::WRL::ComPtr
.-
operator TResult() const
(conversion operator)
returns the wrapped value. -
TResult Get() const
returns the wrapped value. -
TResult&& Get()
returns the wrapped value as an rvalue reference. -
HRESULT CopyTo(TResult* result) const
copies the wrapped value, always returnsS_OK
. -
TResult* GetAddressOf()
returns the address of the wrapped value. -
TResult* ReleaseAndGetAddressOf()
returns the address of the wrapped value. -
TResult* operator&()
returns the address of the wrapped value.
-
details::MapAsyncOpResultType<TResult>::type
also depends on the nature of TResult
:
- If
TResult
is an interface type, thendetails::MapAsyncOpResultType<TResult>::type
isTResult*
. - Otherwise,
details::MapAsyncOpResultType<TResult>::type
isTResult
.
Waiting for completion with a timeout is done with the
wait_for_completion_or_timeout_nothrow
function:
HRESULT hr = wait_for_completion_or_timeout_nothrow(operation, &result, timeout, &timedOut);
Again the result
is omitted if the operation
is an action.
The timeout is expressed in milliseconds.
If the operation fails to complete before the timeout elapses,
the wait_for_completion_or_timeout_nothrow
function
returns S_OK
and sets timedOut
to true
.
In all other cases, timedOut
is false
.
Aside from the timeout,
the function behaves the same as wait_for_completion_nothrow
.
HRESULT wait_for_completion_or_timeout_nothrow(
IAsyncAction* operation,
DWORD timeout,
bool* timedOut,
flags = COWAIT_DISPATCH_CALLS) noexcept;
HRESULT wait_for_completion_or_timeout_nothrow(
IAsyncActionWithProgress<TProgress>* operation,
DWORD timeout,
bool* timedOut,
flags = COWAIT_DISPATCH_CALLS) noexcept;
HRESULT wait_for_completion_or_timeout_nothrow(
IAsyncOperation<TResult>* operation,
details::MapAsyncOpResultType<TResult>::type* result,
DWORD timeout,
bool* timedOut,
flags = COWAIT_DISPATCH_CALLS) noexcept;
HRESULT wait_for_completion_or_timeout_nothrow(
IAsyncOperationWithProgress<TResult, TProgress>* operation,
details::MapAsyncOpResultType<TResult>::type* result,
DWORD timeout,
bool* timedOut,
flags = COWAIT_DISPATCH_CALLS) noexcept;
The call_and_wait_for_completion
variant
uses the following pattern:
auto result = call_and_wait_for_completion(object, &Object::Method, args...);
It invokes the method on the object with the args...
,
and then performs a wait_for_completion
on the operation.
template<typename I, typename ...P, typename ...Args>
auto call_and_wait_for_completion(I* object, HRESULT(STDMETHODCALLTYPE I::*func)(P...),
Args&&... args);
Examples:
IAsyncAction* action = ...;
IAsyncOperation<int> intOperation = ...;
IAsyncOperation<IInspectable> inspectableOperation = ...;
// Waits for the action to complete, or throws if the action fails.
wait_for_completion(action);
// Waits for the operation to complete and returns the result.
auto intResult = wait_for_completion(intOperation).Get();
auto result = wait_for_completion(inspectableOperation);
IInspectable* inspectable = result.Get(); // lifetime controlled by "result"
// Call an asynchronous method and wait for the result.
Microsoft::WRL::ComPtr<ILauncherStatics> launcherStatics = ...;
auto result = call_and_wait_for_completion(
launcherStatics.Get(), &ILauncherStatics::LaunchUriAsync, uri.Get());
bool succeeded = result.Get();
Preferred C++/WinRT alternative:
IAsyncAction action = ...;
IAsyncOperation<int32_t> intOperation = ...;
IAsyncOperation<IInspectable> inspectableOperation = ...;
// Waits for the action to complete, or throws if the action fails.
action.get();
// Waits for the operation to complete and returns the result.
auto intResult = intOperation.get();
IInspectable inspectable = inspectableOperation.get();
// Call an asynchronous method and wait for the result.
bool succeeded = winrt::Windows::System::Launcher::LaunchUriAsync(uri).get();
These functions have been superseded by
C++/WinRT.
Prefer to use C++/WinRT and co_return
to produce asynchronous operations.
The make_synchronous_async_...
functions
create asynchronous operations which have already completed
with a particular result.
They are primarily intended for testing and mocking purposes.
Function | Error model |
---|---|
make_synchronous_async_action |
Exceptions |
make_synchronous_async_operation |
Exceptions |
make_synchronous_async_action_nothrow |
Error codes |
make_synchronous_async_operation_nothrow |
Error codes |
(no fail fast version) |
void make_synchronous_async_action(IAsyncAction** result);
void make_synchronous_async_operation(IAsyncOperation<TResult>** result,
const TResult& value);
HRESULT make_synchronous_async_action_nothrow(IAsyncAction** result);
HRESULT make_synchronous_async_operation_nothrow(IAsyncOperation<TResult>** result,
const TResult& value);
The make_synchronous_async_action
and
make_synchronous_async_action_nothrow
functions create
an already-completed IAsyncAction
.
The make_synchronous_async_operation
and
make_synchronous_async_operation_nothrow
functions create
an already-completed IAsyncOperation<TResult>
,
with the specified value as the completion result.
These functions have been superseded by C++/WinRT. Prefer to use C++/WinRT to access static methods and construct objects.
template<typename TInterface>
com_ptr<TInterface> GetActivationFactory(PCWSTR runtimeClass);
The GetActivationFactory
function gets the activation factory
for the named Windows Runtime class.
The TInterface
is the desired factory interface,
usually a ISomethingStatics
interface.
If the factory could not be obtained, or the factory does not support the specified interface, then an exception is thrown.
Example:
// Invoking a static method.
using namespace ABI::Windows::Security::Cryptography;
auto statics = wil::GetActivationFactory<ICryptographicBufferStatics>(
RuntimeClass_Windows_Security_Cryptography_CryptographicBuffer);
uint32_t number;
THROW_IF_FAILED(statics->GenerateRandomNumber(&number));
// Constructing with parameters.
using namespace ABI::Windows::Security::Credentials;
auto factory = wil::GetActivationFactory<IPasswordCredentialFactory>(
RuntimeClass_Windows_Security_Credentials_PasswordCredential);
wil::unique_hstring resource = ...;
wil::unique_hstring userName = ...;
wil::unique_hstring password = ...;
wil::com_ptr<IPasswordCredential> credential;
THROW_IF_FAILED(factory->CreatePasswordCredential(
resource.get(), userName.get(), password.get(), &credential));
Preferred C++/WinRT alternative:
// Invoking a static method.
using namespace winrt::Windows::Security::Cryptography;
uint32_t number = CryptographicBuffer::GenerateRandomNumber();
// Constructing with parameters.
using namespace winrt::Windows::Security::Credentials;
winrt::hstring resource = ...;
winrt::hstring userName = ...;
winrt::hstring password = ...;
PasswordCredential credential{ resource, userName, password };
template <typename TInterface>
com_ptr<TInterface> ActivateInstance(PCWSTR runtimeClass);
The ActivateInstance
function activates an instance
of the named Windows Runtime class
with no parameters.
In projected languages, this is equivalent to
invoking the default constructor.
The TInterface
is the desired interface on the
resulting object.
It is usually the object's default interface.
If the object could not be activated, or the object does not support the specified interface, then an exception is thrown.
Example:
using namespace ABI::Windows::Security::Credentials;
wil::com_ptr<IPasswordCredential> credential =
wil::ActivationInstance<IPasswordCredential>();
Preferred C++/WinRT alternative:
using namespace winrt::Windows::Security::Credentials;
PasswordCredential credential;
These macros have been superseded by C++/WinRT. Prefer to use C++/WinRT to consume Windows Runtime events.
The unique_winrt_event_token
RAII types
manage the EventRegistrationToken
for Windows Runtime events
and unregister the event handler at destruction.
These types are often used in member variables.
The unique_winrt_event_token
types maintain a weak reference to the
event source.
The WI_MakeUniqueWinrtEventToken
macros will fail if the event source
does not support weak references.
-
WI_MakeUniqueWinRtEventToken(EventName, eventSource, handler, &token)
Registers for theeventSource::EventName
event with the specified handler. The token is stored in aunique_winrt_event_token<Source>
. Throws an exception on failure. -
WI_MakeUniqueWinRtEventTokenFailFast(EventName, eventSource, handler, &token)
Registers for theeventSource::EventName
event with the specified handler. The token is stored in aunique_winrt_event_token<Source>
. Fails fast on failure. -
WI_MakeUniqueWinRtEventTokenNoThrow(EventName, eventSource, handler, &token)
Registers for theeventSource::EventName
event with the specified handler. The token is stored in aunique_winrt_event_token<Source>
. Returns anHRESULT
to indicate whether the operation succeeded. -
WI_MakeUniqueWinRtEventTokenCx(EventName, eventSource, handler)
Registers for theeventSource::EventName
event with the specified handler. The token is returned as aunique_winrt_event_token_cx<Source>
. Throws an exception on failure. -
WI_MakeUniqueWinRtStaticEventTokenCx(EventName, Source, handler)
Registers for the staticSource::EventName
event with the specified handler. The token is returned as aunique_winrt_event_token_cx<Source>
. Throws an exception on failure.
Note that only WI_MakeUniqueWinRtStaticEventTokenCx
supports static events.
Example of ABI usage:
wil::com_ptr<Widget> widget = ...;
wil::com_ptr<TypedEventHandler<Widget, WidgetClosedEventArgs>> handler = ...;
wil::unique_winrt_event_token<Widget> token;
// Using exceptions.
WI_MakeUniqueWinRtEventToken(Closed, widget.get(), handler.get(), &token);
// Using fail-fast.
WI_MakeUniqueWinRtEventTokenFailFast(Closed, widget.get(), handler.get(), &token);
// Using HRESULTs.
RETURN_IF_FAILED(WI_MakeUniqueWinRtEventTokenNoThrow(Closed, widget.get(), handler.get(), &token));
Example of C++/CX usage:
Widget^ widget = ...;
TypedEventHandler<Widget, WidgetClosedEventArgs>^ handler = ...;
// Register an instance event, throws on failure.
wil::unique_winrt_event_token_cx<Widget> token =
WI_MakeUniqueWinRtEventTokenCx(Closed, widget, handler);
// Register a static event, throws on failure.
EventHandler<WidgetAddedEventArgs>^ handler = ...;
wil::unique_winrt_event_token_cx<Widget> token =
WI_MakeUniqueWinRtStaticEventTokenCx(WidgetAdded, Widget, handler);
The C++/WinRT equivalent is winrt::event_revoker
.