Как Shell_NotifyIcon БЕЗ добавления значка в области уведомлений - PullRequest
6 голосов
/ 07 июня 2011

Документация MSDN о Уведомления и область уведомлений довольно ясно указывает на наличие значка в области уведомлений для отображения уведомления:

Чтобы отобразить уведомление, необходимо есть значок в уведомлении район . В определенных случаях, таких как Microsoft Communicator или аккумулятор уровень, этот значок уже будет подарок. Однако во многих других случаях Вы добавите значок к область уведомлений только до тех пор, пока необходимо показать уведомление.

Поскольку я не хочу добавлять какой-либо значок в область уведомлений, я подумывал о том, чтобы, возможно, «повторно» использовать существующий, который, скорее всего, будет там на типичном рабочем столе. Хорошим кандидатом могут быть системные часы.

Мои вопросы:

  1. Как мне найти / перечислить Структура NOTIFYICONDATA для Системные часы (АКА "Дата и время" Свойства "при восстановлении)?
  2. Есть ли лучший способ выполнение этого ( без добавления значок)?

1 Ответ

9 голосов
/ 05 июля 2011

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;
 }
...