2

我一直在尝试将 Windows 的 Shell_Notify API 用于我正在制作的应用程序。通过使用 Shell_NotifyIcon,当我的应用程序开始使用以下代码时,我可以成功地将图标添加到任务栏。

注意:我的代码中不存在除 TruncateTooltipText 之外的以下方法。我像这样输入这些,所以我不必发布我的所有代码。我的代码完全符合我在下面输入的内容。我的代码是这样编写的,所以 Shell_NotifyIcon 总是会在它应该被调用的时候被调用,并且 NOTIFYICONDATA 结构是从一种检查结构的哪些部分应该被填充的方法产生的,这取决于我想要更新的内容。如果有帮助,我也会发布该方法。

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 示例中完美运行,但不适用于我的程序。我上面的所有代码几乎与微软提供的代码完全相同,除了它说的每个 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