6

通知と通知領域に関するMSDNのドキュメントは、通知を表示するために通知領域にアイコンを配置する必要があるという点で非常に明確です。

通知を表示するには、通知領域にアイコンが必要です。Microsoft Communicatorやバッテリーレベルなどの特定のケースでは、そのアイコンはすでに存在します。ただし、他の多くの場合、通知を表示するために必要な場合にのみ、通知領域にアイコンを追加します。

通知領域にアイコンを追加したくないので、通常のデスクトップにある可能性が最も高い既存のアイコンを「再利用」することを考えていました。良い候補はシステム時計かもしれません。

私の質問は次のとおりです。

  1. システムクロックのNOTIFYICONDATA構造(復元された場合の「日付と時刻のプロパティ」)を検索/列挙するにはどうすればよいですか?
  2. (アイコンを追加せずに)これを達成するためのより良い方法はありますか?
4

1 に答える 1

10

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; //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;
 }
于 2011-07-05T12:20:22.517 に答える