在 Windows 系统中,要使用 C++ 获取系统通知消息列表,我们可以借助 Windows API 与相关的 COM 接口来实现。系统通知消息一般是通过操作中心进行管理的,而操作中心使用了用户活动平台(User Activity Platform)的相关接口。下面为你详细介绍实现步骤和示例代码。
实现步骤
- 初始化 COM 库:使用 COM 接口前,需要对 COM 库进行初始化。
- 获取操作中心的通知管理器:借助
IUserNotificationListener
接口获取系统通知的相关信息。 - 枚举通知消息:通过遍历通知列表,获取每条通知的详细信息,如标题、内容等。
- 释放资源:完成操作后,释放 COM 对象并取消 COM 库的初始化。
示例代码
#include <iostream>
#include <windows.h>
#include <wrl/client.h>
#include <windows.ui.notifications.management.h>
using namespace Microsoft::WRL;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::UI::Notifications::Management;
// 初始化COM库
bool InitializeCOM() {
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (FAILED(hr)) {
std::cerr << "Failed to initialize COM library. Error code: 0x" << std::hex << hr << std::endl;
return false;
}
return true;
}
// 获取通知列表
void GetNotificationList() {
ComPtr<IUserNotificationListenerStatics> listenerStatics;
HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Notifications_Management_UserNotificationListener).Get(), &listenerStatics);
if (FAILED(hr)) {
std::cerr << "Failed to get UserNotificationListener factory. Error code: 0x" << std::hex << hr << std::endl;
return;
}
ComPtr<IUserNotificationListener> listener;
hr = listenerStatics->GetDefault(&listener);
if (FAILED(hr)) {
std::cerr << "Failed to get default UserNotificationListener. Error code: 0x" << std::hex << hr << std::endl;
return;
}
ComPtr<IVectorView<IUserNotification*>> notifications;
hr = listener->GetNotificationsAsync(NotificationKinds_Toast, ¬ifications);
if (FAILED(hr)) {
std::cerr << "Failed to get notifications. Error code: 0x" << std::hex << hr << std::endl;
return;
}
UINT32 count;
hr = notifications->get_Size(&count);
if (FAILED(hr)) {
std::cerr << "Failed to get notification count. Error code: 0x" << std::hex << hr << std::endl;
return;
}
std::cout << "Found " << count << " notifications:" << std::endl;
for (UINT32 i = 0; i < count; ++i) {
ComPtr<IUserNotification> notification;
hr = notifications->GetAt(i, ¬ification);
if (FAILED(hr)) {
std::cerr << "Failed to get notification at index " << i << ". Error code: 0x" << std::hex << hr << std::endl;
continue;
}
ComPtr<IToastNotification> toastNotification;
hr = notification->get_Notification(reinterpret_cast<INotification**>(&toastNotification));
if (FAILED(hr)) {
std::cerr << "Failed to get toast notification. Error code: 0x" << std::hex << hr << std::endl;
continue;
}
ComPtr<INotificationVisual> visual;
hr = toastNotification->get_Visual(&visual);
if (FAILED(hr)) {
std::cerr << "Failed to get notification visual. Error code: 0x" << std::hex << hr << std::endl;
continue;
}
ComPtr<INotificationBinding> binding;
hr = visual->GetBinding(HStringReference(L"ToastGeneric").Get(), &binding);
if (FAILED(hr)) {
std::cerr << "Failed to get notification binding. Error code: 0x" << std::hex << hr << std::endl;
continue;
}
ComPtr<IVectorView<INotificationText*>> texts;
hr = binding->get_TextElements(&texts);
if (FAILED(hr)) {
std::cerr << "Failed to get notification text elements. Error code: 0x" << std::hex << hr << std::endl;
continue;
}
UINT32 textCount;
hr = texts->get_Size(&textCount);
if (FAILED(hr)) {
std::cerr << "Failed to get text element count. Error code: 0x" << std::hex << hr << std::endl;
continue;
}
std::wcout << L"Notification " << i << L":" << std::endl;
for (UINT32 j = 0; j < textCount; ++j) {
ComPtr<INotificationText> textElement;
hr = texts->GetAt(j, &textElement);
if (FAILED(hr)) {
std::cerr << "Failed to get text element at index " << j << ". Error code: 0x" << std::hex << hr << std::endl;
continue;
}
HString textValue;
hr = textElement->get_Text(textValue.GetAddressOf());
if (FAILED(hr)) {
std::cerr << "Failed to get text value. Error code: 0x" << std::hex << hr << std::endl;
continue;
}
std::wcout << L" Text " << j << L": " << textValue.GetRawBuffer(nullptr) << std::endl;
}
}
}
// 释放COM库
void UninitializeCOM() {
CoUninitialize();
}
int main() {
if (!InitializeCOM()) {
return 1;
}
GetNotificationList();
UninitializeCOM();
return 0;
}
代码解释
InitializeCOM
函数:调用CoInitializeEx
对 COM 库进行初始化,若初始化失败则输出错误信息。GetNotificationList
函数:- 获取
IUserNotificationListenerStatics
工厂接口。 - 获取默认的
IUserNotificationListener
实例。 - 调用
GetNotificationsAsync
方法获取通知列表。 - 遍历通知列表,获取每条通知的详细信息,包括标题和内容。
- 获取
UninitializeCOM
函数:调用CoUninitialize
取消 COM 库的初始化。main
函数:依次调用InitializeCOM
、GetNotificationList
和UninitializeCOM
完成操作。
编译和运行
编译时需要链接 windowsapp.lib
库,以下是使用 Visual Studio IDE工具编译即可。
运行编译生成的可执行文件 NotificationList.exe
,即可看到系统通知消息列表。
注意事项
- 此代码仅能获取 Toast 类型的通知,若要获取其他类型的通知,需修改
NotificationKinds
参数。 - 代码中涉及的 COM 接口和方法可能会因 Windows 系统版本的不同而有所差异。