Shell_NotifyIcon在底层使用IUserNotification。我尝试过它,并将其制成了一个实用工具。我听说有个视障系统管理员使用它来使他的脚本与屏幕阅读器兼容。它是命令行的,没有消息循环。
它是自我感知的,这意味着发送到它的通知将被排队(您可以控制它)。为了使其工作,我提供了一个IQueryContinue实现。该项目使用C++编写,是开源的,请自行使用。
以下是其核心内容:
HRESULT NotifyUser(const NOTIFU_PARAM& params, IQueryContinue *querycontinue, IUserNotificationCallback *notifcallback)
{
HRESULT result = E_FAIL;
IUserNotification *un = 0;
IUserNotification2 *deux = 0;
if (!params.mForceXP)
result = CoCreateInstance(CLSID_UserNotification, 0, CLSCTX_ALL, IID_IUserNotification2, (void**)&deux);
if (!SUCCEEDED(result))
{
TRACE(eWARN, L"Using Windows XP interface IUserNotification\n");
result = CoCreateInstance(CLSID_UserNotification, 0, CLSCTX_ALL, IID_IUserNotification, (void**)&un);
}
else
{
TRACE(eINFO, L"Using Vista interface IUserNotification2\n");
un = (IUserNotification*)deux;
}
if (SUCCEEDED(result))
{
const std::basic_string<TCHAR> crlf_text(L"\\n");
const std::basic_string<TCHAR> crlf(L"\n");
std::basic_string<TCHAR> text(params.mText);
size_t look = 0;
size_t found;
while ((found = text.find(crlf_text, look)) != std::string::npos)
{
text.replace(found, crlf_text.size(), crlf);
look = found+1;
}
result = un->SetIconInfo(params.mIcon, params.mTitle.c_str());
result = un->SetBalloonInfo(params.mTitle.c_str(), text.c_str(), params.mType);
result = un->SetBalloonRetry(0, 250, 0);
if (deux)
result = deux->Show(querycontinue, 250, notifcallback);
else
result = un->Show(querycontinue, 250);
un->Release();
}
return result;
}