92 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			92 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);
 | 
