C++ C++;带有修改标志的Win32 API外壳\u NotifyIcon始终失败

C++ C++;带有修改标志的Win32 API外壳\u NotifyIcon始终失败,c++,shell,winapi,notifications,C++,Shell,Winapi,Notifications,我一直在尝试为我正在制作的应用程序使用Windows的Shell_Notify API。通过使用Shell_NotifyIcon,当我的应用程序开始使用以下代码时,我能够成功地将图标添加到任务栏 注意:我的代码中不存在除TruncateTooltipText之外的以下方法。我这样键入这些代码,这样就不必发布所有代码。我的代码与我在下面键入的代码完全相同。我的代码是这样编写的:Shell_NotifyIcon总是在应该调用的时候被调用,NotifyIconda结构是由一个方法生成的,该方法检查应该

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

注意:我的代码中不存在除TruncateTooltipText之外的以下方法。我这样键入这些代码,这样就不必发布所有代码。我的代码与我在下面键入的代码完全相同。我的代码是这样编写的:Shell_NotifyIcon总是在应该调用的时候被调用,NotifyIconda结构是由一个方法生成的,该方法检查应该填充结构的哪些部分,具体取决于我想要更新的内容。如果有帮助的话,我也会发布这个方法

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);
}
它总是失败,尽管它在微软提供的WindowsAPI通知示例中可以完美地工作。当我试图展示一个气球时也会发生同样的事情,如下例所示

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,如果需要截断它,请将其截断,然后将其正确复制到NotifyIConda结构中

注意:我将在这里定义TruncateTooltipText,以便大家都知道它是什么样子,如果它有帮助的话。TRUNCATETLETEXT和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;
    }

我使用的是64位Windows 8 Pro,我的程序是一个64位程序。

我认为即使包含guid,也需要提供修改操作的窗口句柄。Microsoft示例不这样做,但在其示例中仍然有效。尽管如此,我还是尝试为窗口包含一个HWND,现在该方法返回true,但实际上什么也没有发生。工具提示不会更改,也不会显示信息气泡。您没有设置uTimeout成员。使用NIF_GUID仅适用于Win7及以上版本,对于早期版本,请使用hWnd+uID。永远不要忽略winapi函数的返回值,请确保断言()LoadString返回的内容。您忘记了在ShowBalloon函数中调用Shell_NotifyIcon()。1。uTimeout成员在Windows Vista中已被弃用。2.我使用的是Windows 8,因此NIF\u GUID应该可以工作。3.我并没有在我的代码中实际使用LoadString,我把它放在上面,这样上面显示的代码更短,更内聚。我将继续,并把我用来填充气球标题、文本和工具提示文本的实际代码放上去。4.实际上,我在程序中调用了Shell_NotifyIcon,上面的方法实际上并不存在于我的代码中,尽管我的代码与上面的几乎完全相同。不过我会纠正的。那么这个问题从来没有解决过吗?我一直都有同样的问题,虽然是间歇性的(有时有效,有时出错)。似乎应该有一些原因来解释为什么这个错误描述/代码是为这个方法编写的,而不仅仅是任意的。