2015-10-17 79 views
0

我的目標是創建一個shell通知圖標,並在需要時顯示氣球工具提示。我寫了下面的代碼。如何根據需要顯示shell通知圖標氣球工具提示?

bool SystemTrayIcon::Create(const std::wstring & Tip, 
          HWND     hWndParent, 
          const GUID &   Guid, 
          UINT     IdCallback, 
          HICON     hIcon, 
          TYPE     Type, 
          bool     bSound, 
          bool     bSharedIcon, 
          bool     bHidden, 
          bool     bLargeIcon, 
          bool     bRespectQuiteTime) 
{ 
    NotifyIconData.cbSize   = sizeof(NotifyIconData); 
    NotifyIconData.hWnd    = hWndParent; 
    NotifyIconData.uID    = 0; // Use GUID instead. (NIF_GUID) 
    NotifyIconData.uFlags   = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_STATE | NIF_GUID | NIF_REALTIME | NIF_SHOWTIP; 
    NotifyIconData.uCallbackMessage = IdCallback; 
    NotifyIconData.hIcon   = hIcon; 

    if (Tip.length() > MAX_TIP) 
    { 
     std::wcsncpy(NotifyIconData.szTip, Tip.c_str(), MAX_TIP); 
     NotifyIconData.szTip[MAX_TIP] = wchar_t(0); 
    } 
    else 
    { 
     std::wcsncpy(NotifyIconData.szTip, Tip.c_str(), Tip.length() + 1); 
    } 

    NotifyIconData.dwState   = (bSharedIcon  ? NIS_SHAREDICON : 0) 
            | (bHidden   ? NIS_HIDDEN  : 0); 
    NotifyIconData.dwStateMask  = NIS_SHAREDICON | NIS_HIDDEN; 
    NotifyIconData.uVersion   = NOTIFYICON_VERSION_4; 

    DWORD dwType; 
    switch (Type) 
    { 
     case TYPE::STI_INFO: 
      dwType = NIIF_INFO; 
      break; 
     case TYPE::STI_WARNING: 
      dwType = NIIF_WARNING; 
      break; 
     case TYPE::STI_ERROR: 
      dwType = NIIF_ERROR; 
      break; 
    } 

    NotifyIconData.dwInfoFlags  = dwType | NIIF_USER 
            | (bSound    ? 0       : NIIF_NOSOUND) 
            | (bLargeIcon   ? NIIF_LARGE_ICON   : 0) 
            | (bRespectQuiteTime ? NIIF_RESPECT_QUIET_TIME : 0); 

    NotifyIconData.guidItem   = Guid; 

    return bInitialized = Shell_NotifyIconW(NIM_ADD, &NotifyIconData); 
} 

void SystemTrayIcon::Balloon( const std::wstring & Title, 
           const std::wstring & Message, 
           HICON     hBalloonIcon) 
{ 
    if (!bInitialized) return; 
    if (Title.length() > MAX_TITLE) 
    { 
     std::wcsncpy(NotifyIconData.szInfoTitle, Title.c_str(), MAX_TITLE); 
     NotifyIconData.szInfoTitle[MAX_TITLE] = wchar_t(0); 
    } 
    else 
    { 
     std::wcsncpy(NotifyIconData.szInfoTitle, Title.c_str(), Title.length() + 1); 
    } 
    if (Message.length() > MAX_MESSAGE) 
    { 
     std::wcsncpy(NotifyIconData.szInfo, Message.c_str(), MAX_MESSAGE); 
     NotifyIconData.szInfo[MAX_MESSAGE] = wchar_t(0); 
    } 
    else 
    { 
     std::wcsncpy(NotifyIconData.szInfo, Message.c_str(), Message.length() + 1); 
    } 
    NotifyIconData.hBalloonIcon = hBalloonIcon; 
    NotifyIconData.dwInfoFlags |= NIF_INFO; 
    Update(); 
} 

void SystemTrayIcon::Update() 
{ 
    Shell_NotifyIconW(NIM_MODIFY, &NotifyIconData); 
} 

我稱這些成員函數中這樣的代碼:在調用Create()方法之後正確顯示

TrayIcon.Create(/*const std::wstring & Tip*/    L"Tip", 
       /*HWND     hWndParent*/  Window.hWnd, 
       /*const GUID &   Guid*/    GUID {0x7f0f02e3, 0x479b, 0x4a09, {0xbf, 0x99, 0xd3, 0x39, 0xe9, 0x3a, 0x8b, 0x22}}, 
       /*UINT     IdCallback*/  ID_TRAYICON, 
       /*HICON     hIcon*/    (HICON) LoadImageW(Status::hInstance, L"icon1.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE), 
       /*TYPE     Type*/    SystemTrayIcon::TYPE::STI_INFO, 
       /*bool     bSound*/   true, 
       /*bool     bSharedIcon*/  false, 
       /*bool     bHidden*/   false, 
       /*bool     bLargeIcon*/  true, 
       /*bool     bRespectQuiteTime*/ false); 
Sleep(10000); 
TrayIcon.Balloon( L"New Title", 
        L"New Message", 
        (HICON) LoadImageW(Status::hInstance, L"icon2.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE)); 

的圖標。但Balloon()方法不起作用。不顯示氣球頂端提示。

我可以通過添加NIF_INFO恆定的uFlags,和填滿szInfoTitleszInfo構件使其在創建顯示氣球。但我想要實現的是在任意時間通過調用Balloon()方法來顯示它。

我在這裏錯過了什麼?

+0

用[已知能正常工作碼(http://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/ NotifyIcon.cs,d6f06dbccbf7a452)作爲指南。請注意它如何使用uFlags。 –

回答

0

我在我的代碼中解決了很多問題。現在它工作得很好,正如我所期望的那樣。以下是我的新代碼。請注意更改。

bool SystemTrayIcon::Create(const std::wstring & Tip, 
          HWND     hWndParent, 
          const GUID &   Guid, 
          UINT     IdCallback, 
          HICON     hIcon, 
          bool     bSharedIcon, 
          bool     bHidden) 
{ 
    if (bInitialized) return false; 

    NotifyIconData.cbSize   = sizeof(NotifyIconData); 
    NotifyIconData.hWnd    = hWndParent; 
    NotifyIconData.uID    = 0; // Use GUID instead. (NIF_GUID) 
    NotifyIconData.uFlags   = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_STATE | NIF_GUID | NIF_SHOWTIP; 
    NotifyIconData.uCallbackMessage = IdCallback; 
    NotifyIconData.hIcon   = hIcon; 

    if (Tip.length() > MAX_TIP) 
    { 
     std::wcsncpy(NotifyIconData.szTip, Tip.c_str(), MAX_TIP); 
     NotifyIconData.szTip[MAX_TIP] = wchar_t(0); 
    } 
    else 
    { 
     std::wcsncpy(NotifyIconData.szTip, Tip.c_str(), Tip.length() + 1); 
    } 

    NotifyIconData.dwState   = (bSharedIcon  ? NIS_SHAREDICON : 0) 
            | (bHidden   ? NIS_HIDDEN  : 0); 
    NotifyIconData.dwStateMask  = NIS_SHAREDICON | NIS_HIDDEN; 

    NotifyIconData.guidItem   = Guid; 

    bInitialized = Shell_NotifyIconW(NIM_ADD, &NotifyIconData); 

    NotifyIconData.uVersion   = NOTIFYICON_VERSION_4; 
    bLastResult = Shell_NotifyIconW(NIM_SETVERSION, &NotifyIconData); 

    return bInitialized; 
} 

void SystemTrayIcon::Balloon( const std::wstring & Title, 
           const std::wstring & Message, 
           HICON     hBalloonIcon, 
           BALLOON_ICON_TYPE  IconType, 
           UINT     Timeout, // In milliseconds. 
           bool     bSound, 
           bool     bLargeIcon, 
           bool     bRespectQuiteTime) 
{ 
    if (!bInitialized) return; 

    if (Title.length() > MAX_TITLE) 
    { 
     std::wcsncpy(NotifyIconData.szInfoTitle, Title.c_str(), MAX_TITLE); 
     NotifyIconData.szInfoTitle[MAX_TITLE] = wchar_t(0); 
    } 
    else 
    { 
     std::wcsncpy(NotifyIconData.szInfoTitle, Title.c_str(), Title.length() + 1); 
    } 

    if (Message.length() > MAX_MESSAGE) 
    { 
     std::wcsncpy(NotifyIconData.szInfo, Message.c_str(), MAX_MESSAGE); 
     NotifyIconData.szInfo[MAX_MESSAGE] = wchar_t(0); 
    } 
    else 
    { 
     std::wcsncpy(NotifyIconData.szInfo, Message.c_str(), Message.length() + 1); 
    } 

    DWORD dwType; 
    switch (IconType) 
    { 
     case BALLOON_ICON_TYPE::BIT_NONE: 
      dwType = 0; 
      break; 
     case BALLOON_ICON_TYPE::BIT_INFO: 
      dwType = NIIF_INFO; 
      break; 
     case BALLOON_ICON_TYPE::BIT_WARNING: 
      dwType = NIIF_WARNING; 
      break; 
     case BALLOON_ICON_TYPE::BIT_ERROR: 
      dwType = NIIF_ERROR; 
      break; 
     case BALLOON_ICON_TYPE::BIT_USER_DEFINED: 
      dwType = NIIF_USER; // Use the "hBalloonIcon" parameter. 
      break; 
    } 

    NotifyIconData.dwInfoFlags  = dwType 
            | (bSound    ? 0       : NIIF_NOSOUND) 
            | (bLargeIcon   ? NIIF_LARGE_ICON   : 0) 
            | (bRespectQuiteTime ? NIIF_RESPECT_QUIET_TIME : 0); 

    NotifyIconData.uTimeout  = Timeout; 
    NotifyIconData.hBalloonIcon = hBalloonIcon; 
    NotifyIconData.uFlags  = NIF_INFO | NIF_GUID; 

    Update(); 
} 

void SystemTrayIcon::Update() 
{ 
    bLastResult = Shell_NotifyIconW(NIM_MODIFY, &NotifyIconData); 
} 

用法在代碼:

TrayIcon.Create(/*const std::wstring & Tip*/    L"Tip", 
       /*HWND     hWndParent*/  Window.hWnd, 
       /*const GUID &   Guid*/    GUID {0x7f0f02e4, 0x479b, 0x4a09, {0xbf, 0x99, 0xd3, 0x39, 0xe9, 0x3a, 0x8b, 0x22}}, 
       /*UINT     IdCallback*/  ID_TRAYICON, 
       /*HICON     hIcon*/    (HICON) hImage, 
       /*bool     bSharedIcon*/  false, 
       /*bool     bHidden*/   false); 

// ... 

TrayIcon.Balloon( L"Button 2", 
        L"You have just clicked the Button #2.", 
        (HICON) hImage, 
        SystemTrayIcon::BALLOON_ICON_TYPE::BIT_USER_DEFINED, 
        20000U, 
        true, 
        true, 
        false); 
相關問題