如何在没有在通知区域中添加图标的情况下Shell_NotifyIcon

时间:2011-06-07 19:28:31

标签: winapi tooltip system-tray systray

MSDN关于Notifications and the Notification Area的文档非常明确,要求在通知区域中显示一个图标以显示通知:

  

要显示通知,您必须   在通知中有一个图标   区域即可。在某些情况下,例如   Microsoft Communicator或电池   等级,该图标已经存在   当下。然而,在许多其他情况下,   你将添加一个图标   通知区域只要是   需要显示通知。

由于我不想在通知区域添加任何图标,我想到的可能是“重用”现有的一个最常见的典型的桌面。一个好的候选人可能是系统时钟。

我的问题是:

  1. 我如何查找/枚举 NOTIFYICONDATA结构 系统时钟(AKA“日期和时间 属性“恢复时”?
  2. 有没有更好的方法 完成这个(没有添加 一个图标)?

1 个答案:

答案 0 :(得分:9)

Shell_NotifyIcon在引擎盖下使用IUserNotification。我玩了它并制作了utility out of it。我听说一个视力受损的系统管理员使用它来使他的脚本屏幕阅读器兼容。它是命令行,它没有消息循环。

它是自我意识的,这意味着发送给它的通知将排队(您可以控制它)。为此,我提供了一个IQueryContinue实现。该项目是C ++的,是开源的,帮助自己。

以下是它的内容:

 HRESULT NotifyUser(const NOTIFU_PARAM& params, IQueryContinue *querycontinue, IUserNotificationCallback *notifcallback)
 {
    HRESULT result = E_FAIL;

    IUserNotification *un = 0;
    IUserNotification2 *deux = 0; //French pun : "un" above stands for UserNotification but it also means 1 in French. deux means 2.

    //First try with the Vista/Windows 7 interface
    //(unless /xp flag is specified
    if (!params.mForceXP)
       result = CoCreateInstance(CLSID_UserNotification, 0, CLSCTX_ALL, IID_IUserNotification2, (void**)&deux);

    //Fall back to Windows XP
    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; //Rather ugly cast saves some code...
    }

    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;

       //Replace \n with actual CRLF pair
       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);

       //Looks like it controls what happends when the X button is
       //clicked on
       result = un->SetBalloonRetry(0, 250, 0);

       if (deux)
          result = deux->Show(querycontinue, 250, notifcallback);
       else
          result = un->Show(querycontinue, 250);

       un->Release();
    }

    return result;
 }