windows_toast_activator.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "platform/win/windows_toast_activator.h"
  8. #pragma warning(push)
  9. // class has virtual functions, but destructor is not virtual
  10. #pragma warning(disable:4265)
  11. #pragma warning(disable:5104)
  12. #include <wrl/module.h>
  13. #pragma warning(pop)
  14. namespace {
  15. rpl::event_stream<ToastActivation> GlobalToastActivations;
  16. } // namespace
  17. QString ToastActivation::String(LPCWSTR value) {
  18. const auto length = int(wcslen(value));
  19. auto result = value
  20. ? QString::fromWCharArray(value, std::min(length, 16384))
  21. : QString();
  22. if (result.indexOf(QChar('\n')) < 0) {
  23. result.replace(QChar('\r'), QChar('\n'));
  24. }
  25. return result;
  26. }
  27. HRESULT ToastActivator::Activate(
  28. _In_ LPCWSTR appUserModelId,
  29. _In_ LPCWSTR invokedArgs,
  30. _In_reads_(dataCount) const NOTIFICATION_USER_INPUT_DATA *data,
  31. ULONG dataCount) {
  32. DEBUG_LOG(("Toast Info: COM Activated \"%1\" with args \"%2\"."
  33. ).arg(QString::fromWCharArray(appUserModelId)
  34. ).arg(QString::fromWCharArray(invokedArgs)));
  35. const auto string = &ToastActivation::String;
  36. auto input = std::vector<ToastActivation::UserInput>();
  37. input.reserve(dataCount);
  38. for (auto i = 0; i != dataCount; ++i) {
  39. input.push_back({
  40. .key = string(data[i].Key),
  41. .value = string(data[i].Value),
  42. });
  43. }
  44. auto activation = ToastActivation{
  45. .args = string(invokedArgs),
  46. .input = std::move(input),
  47. };
  48. crl::on_main([activation = std::move(activation)]() mutable {
  49. GlobalToastActivations.fire(std::move(activation));
  50. });
  51. return S_OK;
  52. }
  53. HRESULT ToastActivator::QueryInterface(
  54. REFIID riid,
  55. void **ppObj) {
  56. if (riid == IID_IUnknown
  57. || riid == IID_INotificationActivationCallback) {
  58. *ppObj = static_cast<INotificationActivationCallback*>(this);
  59. AddRef();
  60. return S_OK;
  61. }
  62. *ppObj = NULL;
  63. return E_NOINTERFACE;
  64. }
  65. ULONG ToastActivator::AddRef() {
  66. return InterlockedIncrement(&_ref);
  67. }
  68. ULONG ToastActivator::Release() {
  69. long ref = 0;
  70. ref = InterlockedDecrement(&_ref);
  71. if (!ref) {
  72. delete this;
  73. }
  74. return ref;
  75. }
  76. rpl::producer<ToastActivation> ToastActivations() {
  77. return GlobalToastActivations.events();
  78. }
  79. CoCreatableClass(ToastActivator);