tdesktop/Telegram/SourceFiles/platform/win/windows_toast_activator.cpp

93 lines
2.3 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "platform/win/windows_toast_activator.h"
#pragma warning(push)
// class has virtual functions, but destructor is not virtual
#pragma warning(disable:4265)
#pragma warning(disable:5104)
#include <wrl/module.h>
#pragma warning(pop)
namespace {
rpl::event_stream<ToastActivation> GlobalToastActivations;
} // namespace
QString ToastActivation::String(LPCWSTR value) {
const auto length = int(wcslen(value));
auto result = value
? QString::fromWCharArray(value, std::min(length, 16384))
: QString();
if (result.indexOf(QChar('\n')) < 0) {
result.replace(QChar('\r'), QChar('\n'));
}
return result;
}
HRESULT ToastActivator::Activate(
_In_ LPCWSTR appUserModelId,
_In_ LPCWSTR invokedArgs,
_In_reads_(dataCount) const NOTIFICATION_USER_INPUT_DATA *data,
ULONG dataCount) {
DEBUG_LOG(("Toast Info: COM Activated \"%1\" with args \"%2\"."
).arg(QString::fromWCharArray(appUserModelId)
).arg(QString::fromWCharArray(invokedArgs)));
const auto string = &ToastActivation::String;
auto input = std::vector<ToastActivation::UserInput>();
input.reserve(dataCount);
for (auto i = 0; i != dataCount; ++i) {
input.push_back({
.key = string(data[i].Key),
.value = string(data[i].Value),
});
}
auto activation = ToastActivation{
.args = string(invokedArgs),
.input = std::move(input),
};
crl::on_main([activation = std::move(activation)]() mutable {
GlobalToastActivations.fire(std::move(activation));
});
return S_OK;
}
HRESULT ToastActivator::QueryInterface(
REFIID riid,
void **ppObj) {
if (riid == IID_IUnknown
|| riid == IID_INotificationActivationCallback) {
*ppObj = static_cast<INotificationActivationCallback*>(this);
AddRef();
return S_OK;
}
*ppObj = NULL;
return E_NOINTERFACE;
}
ULONG ToastActivator::AddRef() {
return InterlockedIncrement(&_ref);
}
ULONG ToastActivator::Release() {
long ref = 0;
ref = InterlockedDecrement(&_ref);
if (!ref) {
delete this;
}
return ref;
}
rpl::producer<ToastActivation> ToastActivations() {
return GlobalToastActivations.events();
}
CoCreatableClass(ToastActivator);