2

私が作成しているアプリには、Windows の Shell_Notify API を使用しようとしています。Shell_NotifyIcon を使用すると、次のコードを使用してアプリを起動したときにタスク バーにアイコンを追加できます。

注: 私のコードには、TruncateTooltipText 以外の以下のメソッドはありません。このように入力するので、すべてのコードを投稿する必要はありません。ただし、私のコードは、以下に入力したものとまったく同じです。私のコードは、必要なときに Shell_NotifyIcon が常に呼び出されるように記述されており、NOTIFYICONDATA 構造は、更新したい内容に応じて、構造のどの部分を埋める必要があるかをチェックする 1 つのメソッドから生成されます。その方法も参考になれば載せます。

void AddNotificationIcon()
{
   NOTIFYICONDATA data = {sizeof(data)};
   data.uFlags = NIF_TIP | NIF_SHOWTIP | NIF_MESSAGE | NIF_GUID | NIF_ICON
   data.guidItem = __uuidof(NotifyIconGuid);
   data.uCallbackMessage = WM_USER + NOTIFY_CALLBACK;
   data.hWnd = (HWND)this->winId();
   data.icon = LoadIcon(data.instance, MAKEINTRESOURCE(IDI_ICON1));
   TruncateTooltipText("Some tooltip text.", &data)
   Shell_NotifyIcon(NIM_ADD, &data);

   data.uVersion = NOTIFYICON_VERSION_4;
   Shell_NotifyIcon(NIM_SETVERSION, &data);
}

上記のコードは完全に機能します。さらに、コールバックも同様に機能するため、アイコンを左クリックまたは右クリックすると、Windows メッセージ ループでメッセージを受信します。ただし、バルーン メッセージを表示したり、ツールチップを変更したり、フラグとして NIM_MODIFY を使用して Shell_NotifyIcon を呼び出したりしようとすると、メソッドは失敗し、GetLastError は次のメッセージを返します。

This operation returned because the timeout period expired.

グーグルで調べたところ、Shell_NotifyIcon が SendMessageTimeout を使用していることがわかったので、この報告されたエラーはおそらくメソッドが失敗した理由とは関係ありません。ツールチップを変更するために使用するコードを次に示します。

void ChangeTooltip()
{
   NOTIFYICONDATA data = {sizeof(data)};
   data.uFlags = NIF_TIP | NIF_SHOWTIP | NIF_GUID;
   data.guidItem = __uuidof(NotifyIconGuid);
   TruncateTooltipText("Some more tooltip text.", &data)
   Shell_NotifyIcon(NIM_MODIFY, &data);
}

Microsoft が提供する Windows API 通知サンプルでは問題なく動作しますが、常に失敗します。以下の例のように、バルーンを表示しようとすると同じことが起こります。

void ShowBalloon()
{
   NOTIFYICONDATA data = {sizeof(data)};
   data.uFlags = NIF_GUID | NIF_INFO;
   data.dwInfoFlags = NIIF_INFO;
   data.guidItem = __uuidof(NotifyIconGuid);
   TruncateInfoText("This is some example text being displayed in a balloon.", &data)
   TruncateTitleText("This is the balloon title.", &data)
   Shell_NotifyIcon(NIF_MODIFY, &data);
}

繰り返しますが、このコードは Microsoft の例では完全に機能しますが、私のプログラムでは機能しません。上記のコードはすべて、Microsoft が提供するものとほぼ同じですが、LoadString と書かれている点はすべて、実際に std::string を取り込み、切り詰める必要がある場合は切り捨て、NOTIFYICONDATA 構造に適切にコピーします。 .

注: ここで TruncateTooltipText を定義しますので、それが役立つ場合は、それがどのように見えるかがわかります。TruncateTitleText と TruncateInfoText は、NOTIFYDATAICON 構造内の適切な変数を対象とする点を除いて、まったく同じです。

bool TruncateTooltipText(string originalText, NOTIFYICONDATA* output)
    {
        //If the text inputted to display as a tooltip is too long, shorten it.
        if(originalText.length() > ARRAYSIZE(output->szTip))
        {
            originalText = originalText.substr(0, ARRAYSIZE(output->szTip) - 1);
            OutputDebugStringA("Notification Warning: Tooltip text is longer than allowed 128 characters. Tooltip text has been truncated!\n");
        }

        wstring toolText = wstring(originalText.begin(), originalText.end());

        HRESULT copyResult;
        copyResult = StringCchCopy(output->szTip, ARRAYSIZE(output->szTip), toolText.c_str());
        if(FAILED(copyResult))
        {
            OutputDebugString(L"Notification Error: Failed to copy the std::string for the tooltip to the structure string.");
            return false;
        }

        return true;
    }

私は Windows 8 Pro 64 ビットを使用しており、私のプログラムは 64 ビット プログラムです。

4

0 に答える 0