Changeset 67 for trunk/SystemTray.cpp


Ignore:
Timestamp:
10/18/2007 9:37:01 AM (7 years ago)
Author:
lowjoel
Message:

-Updated the System Tray class
-Make the Scheduler popup menu slightly more meaningful (in terms of text chosen)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/SystemTray.cpp

    r3 r67  
    11///////////////////////////////////////////////////////////////////////////// 
    22// SystemTray.cpp : implementation file 
     3// 
     4// MFC VERSION 
    35// 
    46// This is a conglomeration of ideas from the MSJ "Webster" application, 
     
    2325//                          hIcon, nSystemTrayID); 
    2426// 
    25 // Written by Chris Maunder (chrismaunder@codeguru.com) 
    26 // Copyright (c) 1998. 
     27// Written by Chris Maunder (cmaunder@mail.com) 
     28// Copyright (c) 1998-2003. 
    2729// 
    2830// Updated: 25 Jul 1998 - Added icon animation, and derived class 
     
    3133//                        Added API to set default menu item. Code provided 
    3234//                        by Enrico Lelina. 
     35// 
     36// Updated: 6 June 1999 - SetIcon can now load non-standard sized icons (Chip Calvert) 
     37//                        Added "bHidden" parameter when creating icon 
     38//                        (Thanks to Michael Gombar for these suggestions) 
     39//                        Restricted tooltip text to 64 characters. 
     40// 
     41// Updated: 9 Nov 1999  - Now works in WindowsCE. 
     42//                        Fix for use in NT services (Thomas Mooney, TeleProc, Inc) 
     43//                        Added W2K stuff by Michael Dunn 
     44// 
     45// Updated: 1 Jan 2000  - Added tray minimisation stuff. 
     46//  
     47// Updated: 21 Sep 2000 - Added GetDoWndAnimation - animation only occurs if the system 
     48//                        settings allow it (Matthew Ellis). Updated the GetTrayWndRect 
     49//                        function to include more fallback logic (Matthew Ellis) 
     50//                        NOTE: Signature of GetTrayWndRect has changed! 
     51//  
     52// Updated: 4 Aug 2003 - Fixed bug that was stopping icon from being recreated when 
     53//                       Explorer crashed 
     54//                       Fixed resource leak in SetIcon 
     55//                       Animate() now checks for empty icon list - Anton Treskunov 
     56//                       Added the virutal CustomizeMenu() method - Anton Treskunov 
     57//                        
    3358// 
    3459// This code may be used in compiled form in any way you desire. This 
     
    4166// 
    4267// This file is provided "as is" with no expressed or implied warranty. 
    43 // The author accepts no liability if it causes any damage to your 
    44 // computer, causes your pet cat to fall ill, increases baldness or 
    45 // makes you car start emitting strange noises when you start it up. 
     68// The author accepts no liability for any damage caused through use. 
    4669// 
    4770// Expect bugs. 
     
    5477     
    5578#include "stdafx.h" 
    56 #include "resource.h" 
    5779#include "SystemTray.h" 
    5880 
     
    6385#endif 
    6486 
     87#ifndef _WIN32_WCE  // Use C++ exception handling instead of structured. 
     88#undef TRY 
     89#undef CATCH 
     90#undef END_CATCH 
     91#define TRY try 
     92#define CATCH(ex_class, ex_object) catch(ex_class* ex_object) 
     93#define END_CATCH 
     94#endif  // _WIN32_WCE 
     95 
     96#ifndef _countof 
     97#define _countof(x) ( sizeof(x) / sizeof(x[0]) ) 
     98#endif 
     99 
    65100IMPLEMENT_DYNAMIC(CSystemTray, CWnd) 
    66101 
    67 UINT CSystemTray::m_nIDEvent = 4567; 
     102const UINT CSystemTray::m_nTimerID    = 4567; 
     103UINT CSystemTray::m_nMaxTooltipLength  = 128;     // This may change... 
     104const UINT CSystemTray::m_nTaskbarCreatedMsg = ::RegisterWindowMessage(_T("TaskbarCreated")); 
     105CWnd  CSystemTray::m_wndInvisible; 
    68106 
    69107///////////////////////////////////////////////////////////////////////////// 
     
    75113} 
    76114 
    77 CSystemTray::CSystemTray(CWnd* pParent, UINT uCallbackMessage, LPCTSTR szToolTip,  
    78                          HICON icon, UINT uID) 
     115CSystemTray::CSystemTray(CWnd* pParent,             // The window that will recieve tray notifications 
     116                         UINT uCallbackMessage,     // the callback message to send to parent 
     117                         LPCTSTR szToolTip,         // tray icon tooltip 
     118                         HICON icon,                // Handle to icon 
     119                         UINT uID,                  // Identifier of tray icon 
     120                         BOOL bHidden /*=FALSE*/,   // Hidden on creation?                   
     121                         LPCTSTR szBalloonTip /*=NULL*/,    // Ballon tip (w2k only) 
     122                         LPCTSTR szBalloonTitle /*=NULL*/,  // Balloon tip title (w2k) 
     123                         DWORD dwBalloonIcon /*=NIIF_NONE*/,// Ballon tip icon (w2k) 
     124                         UINT uBalloonTimeout /*=10*/)      // Balloon timeout (w2k) 
    79125{ 
    80126    Initialise(); 
    81     Create(pParent, uCallbackMessage, szToolTip, icon, uID); 
     127    Create(pParent, uCallbackMessage, szToolTip, icon, uID, bHidden, 
     128           szBalloonTip, szBalloonTitle, dwBalloonIcon, uBalloonTimeout); 
    82129} 
    83130 
     
    85132{ 
    86133    memset(&m_tnd, 0, sizeof(m_tnd)); 
    87     m_bEnabled   = FALSE; 
    88     m_bHidden    = FALSE; 
     134 
     135    m_bEnabled = FALSE; 
     136    m_bHidden  = TRUE; 
     137    m_bRemoved = TRUE; 
     138 
     139    m_DefaultMenuItemID    = 0; 
     140    m_DefaultMenuItemByPos = TRUE; 
     141 
     142    m_bShowIconPending = FALSE; 
     143 
    89144    m_uIDTimer   = 0; 
    90145    m_hSavedIcon = NULL; 
    91     m_DefaultMenuItemID = 0; 
    92     m_DefaultMenuItemByPos = TRUE; 
    93 } 
    94  
    95 #pragma warning(disable : 4706) 
     146 
     147    m_pTargetWnd = NULL; 
     148    m_uCreationFlags = 0; 
     149 
     150#ifdef SYSTEMTRAY_USEW2K 
     151    OSVERSIONINFO os = { sizeof(os) }; 
     152    GetVersionEx(&os); 
     153    m_bWin2K = ( VER_PLATFORM_WIN32_NT == os.dwPlatformId && os.dwMajorVersion >= 5 ); 
     154#else 
     155    m_bWin2K = FALSE; 
     156#endif 
     157} 
     158 
     159// update by Michael Dunn, November 1999 
     160// 
     161//  New version of Create() that handles new features in Win 2K. 
     162// 
     163// Changes: 
     164//  szTip: Same as old, but can be 128 characters instead of 64. 
     165//  szBalloonTip: Text for a balloon tooltip that is shown when the icon 
     166//                is first added to the tray.  Pass "" if you don't want 
     167//                a balloon. 
     168//  szBalloonTitle: Title text for the balloon tooltip.  This text is shown 
     169//                  in bold above the szBalloonTip text.  Pass "" if you 
     170//                  don't want a title. 
     171//  dwBalloonIcon: Specifies which icon will appear in the balloon.  Legal 
     172//                 values are: 
     173//                     NIIF_NONE: No icon 
     174//                     NIIF_INFO: Information 
     175//                     NIIF_WARNING: Exclamation 
     176//                     NIIF_ERROR: Critical error (red circle with X) 
     177//  uBalloonTimeout: Number of seconds for the balloon to remain visible. 
     178//                   Must be between 10 and 30 inclusive. 
     179 
    96180BOOL CSystemTray::Create(CWnd* pParent, UINT uCallbackMessage, LPCTSTR szToolTip,  
    97                          HICON icon, UINT uID, BOOL bInitialShow /*=TRUE*/) 
    98 { 
     181                         HICON icon, UINT uID, BOOL bHidden /*=FALSE*/, 
     182                         LPCTSTR szBalloonTip /*=NULL*/,  
     183                         LPCTSTR szBalloonTitle /*=NULL*/,   
     184                         DWORD dwBalloonIcon /*=NIIF_NONE*/, 
     185                         UINT uBalloonTimeout /*=10*/) 
     186{ 
     187#ifdef _WIN32_WCE 
     188    m_bEnabled = TRUE; 
     189#else 
    99190    // this is only for Windows 95 (or higher) 
    100     VERIFY(m_bEnabled = ( GetVersion() & 0xff ) >= 4); 
    101     if (!m_bEnabled) return FALSE; 
    102  
    103     // Make sure Notification window is valid (not needed - CJM) 
    104     // VERIFY(m_bEnabled = (pParent && ::IsWindow(pParent->GetSafeHwnd()))); 
    105     // if (!m_bEnabled) return FALSE; 
     191    m_bEnabled = (GetVersion() & 0xff) >= 4; 
     192    if (!m_bEnabled)  
     193    { 
     194        ASSERT(FALSE); 
     195        return FALSE; 
     196    } 
     197#endif 
     198 
     199    m_nMaxTooltipLength = _countof(m_tnd.szTip); 
    106200     
    107201    // Make sure we avoid conflict with other messages 
    108     ASSERT(uCallbackMessage >= WM_USER); 
    109  
    110     // Tray only supports tooltip text up to 64 characters 
    111     ASSERT(_tcslen(szToolTip) <= 64); 
     202    ASSERT(uCallbackMessage >= WM_APP); 
     203 
     204    // Tray only supports tooltip text up to m_nMaxTooltipLength) characters 
     205    ASSERT(AfxIsValidString(szToolTip)); 
     206    ASSERT(_tcslen(szToolTip) <= m_nMaxTooltipLength); 
    112207 
    113208    // Create an invisible window 
    114     CWnd::CreateEx(0, AfxRegisterWndClass(0), _T(""), WS_POPUP, 0,0,10,10, NULL, 0); 
     209    CWnd::CreateEx(0, AfxRegisterWndClass(0), _T(""), WS_POPUP, 0,0,0,0, NULL, 0); 
    115210 
    116211    // load up the NOTIFYICONDATA structure 
     
    121216    m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; 
    122217    m_tnd.uCallbackMessage = uCallbackMessage; 
    123     _tcsncpy(m_tnd.szTip, szToolTip, 64); 
    124  
    125     if (bInitialShow) 
    126     { 
    127         // Set the tray icon 
    128         VERIFY(m_bEnabled = Shell_NotifyIcon(NIM_ADD, &m_tnd)); 
    129         return m_bEnabled; 
    130     } 
    131     else 
    132     { 
    133         m_bHidden = TRUE; 
    134         return TRUE; 
    135     } 
    136 } 
    137 #pragma warning(default : 4706) 
     218    _tcsncpy(m_tnd.szTip, szToolTip, m_nMaxTooltipLength-1); 
     219 
     220#ifdef SYSTEMTRAY_USEW2K 
     221    if (m_bWin2K && szBalloonTip) 
     222    { 
     223        // The balloon tooltip text can be up to 255 chars long. 
     224        ASSERT(AfxIsValidString(szBalloonTip)); 
     225        ASSERT(lstrlen(szBalloonTip) < 256); 
     226 
     227        // The balloon title text can be up to 63 chars long. 
     228        if (szBalloonTitle) 
     229        { 
     230            ASSERT(AfxIsValidString(szBalloonTitle)); 
     231            ASSERT(lstrlen(szBalloonTitle) < 64); 
     232        } 
     233 
     234        // dwBalloonIcon must be valid. 
     235        ASSERT(NIIF_NONE == dwBalloonIcon    || NIIF_INFO == dwBalloonIcon || 
     236               NIIF_WARNING == dwBalloonIcon || NIIF_ERROR == dwBalloonIcon); 
     237 
     238        // The timeout must be between 10 and 30 seconds. 
     239        ASSERT(uBalloonTimeout >= 10 && uBalloonTimeout <= 30); 
     240 
     241        m_tnd.uFlags |= NIF_INFO; 
     242 
     243        _tcsncpy(m_tnd.szInfo, szBalloonTip, 255); 
     244        if (szBalloonTitle) 
     245            _tcsncpy(m_tnd.szInfoTitle, szBalloonTitle, 63); 
     246        else 
     247            m_tnd.szInfoTitle[0] = _T('\0'); 
     248        m_tnd.uTimeout    = uBalloonTimeout * 1000; // convert time to ms 
     249        m_tnd.dwInfoFlags = dwBalloonIcon; 
     250    } 
     251#endif 
     252 
     253    m_bHidden = bHidden; 
     254 
     255#ifdef SYSTEMTRAY_USEW2K 
     256    if (m_bWin2K && m_bHidden) 
     257    { 
     258        m_tnd.uFlags = NIF_STATE; 
     259        m_tnd.dwState = NIS_HIDDEN; 
     260        m_tnd.dwStateMask = NIS_HIDDEN; 
     261    } 
     262#endif 
     263 
     264    m_uCreationFlags = m_tnd.uFlags;    // Store in case we need to recreate in OnTaskBarCreate 
     265 
     266    BOOL bResult = TRUE; 
     267    if (!m_bHidden || m_bWin2K) 
     268    { 
     269        bResult = Shell_NotifyIcon(NIM_ADD, &m_tnd); 
     270        m_bShowIconPending = m_bHidden = m_bRemoved = !bResult; 
     271    } 
     272     
     273#ifdef SYSTEMTRAY_USEW2K     
     274    if (m_bWin2K && szBalloonTip) 
     275    { 
     276        // Zero out the balloon text string so that later operations won't redisplay 
     277        // the balloon. 
     278        m_tnd.szInfo[0] = _T('\0'); 
     279    } 
     280#endif 
     281 
     282    return bResult; 
     283} 
    138284 
    139285CSystemTray::~CSystemTray() 
     
    147293// CSystemTray icon manipulation 
    148294 
    149 void CSystemTray::MoveToRight() 
    150 { 
    151     HideIcon(); 
    152     ShowIcon(); 
    153 } 
    154  
    155 void CSystemTray::RemoveIcon() 
    156 { 
    157     if (!m_bEnabled) return; 
     295////////////////////////////////////////////////////////////////////////// 
     296// 
     297// Function:    SetFocus() 
     298// 
     299// Description: 
     300//  Sets the focus to the tray icon.  Microsoft's Win 2K UI guidelines 
     301//  say you should do this after the user dismisses the icon's context 
     302//  menu. 
     303// 
     304// Input: 
     305//  Nothing. 
     306// 
     307// Returns: 
     308//  Nothing. 
     309// 
     310////////////////////////////////////////////////////////////////////////// 
     311// Added by Michael Dunn, November, 1999 
     312////////////////////////////////////////////////////////////////////////// 
     313 
     314void CSystemTray::SetFocus() 
     315{ 
     316#ifdef SYSTEMTRAY_USEW2K 
     317    Shell_NotifyIcon ( NIM_SETFOCUS, &m_tnd ); 
     318#endif 
     319} 
     320 
     321BOOL CSystemTray::MoveToRight() 
     322{ 
     323    RemoveIcon(); 
     324    return AddIcon(); 
     325} 
     326 
     327BOOL CSystemTray::AddIcon() 
     328{ 
     329    if (!m_bRemoved) 
     330        RemoveIcon(); 
     331 
     332    if (m_bEnabled) 
     333    { 
     334        m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; 
     335        if (!Shell_NotifyIcon(NIM_ADD, &m_tnd)) 
     336            m_bShowIconPending = TRUE; 
     337        else 
     338            m_bRemoved = m_bHidden = FALSE; 
     339    } 
     340    return (m_bRemoved == FALSE); 
     341} 
     342 
     343BOOL CSystemTray::RemoveIcon() 
     344{ 
     345    m_bShowIconPending = FALSE; 
     346 
     347    if (!m_bEnabled || m_bRemoved) 
     348        return TRUE; 
    158349 
    159350    m_tnd.uFlags = 0; 
    160     Shell_NotifyIcon(NIM_DELETE, &m_tnd); 
    161     m_bEnabled = FALSE; 
    162 } 
    163  
    164 void CSystemTray::HideIcon() 
    165 { 
    166     if (m_bEnabled && !m_bHidden) { 
    167         m_tnd.uFlags = NIF_ICON; 
    168         Shell_NotifyIcon (NIM_DELETE, &m_tnd); 
    169         m_bHidden = TRUE; 
    170     } 
    171 } 
    172  
    173 void CSystemTray::ShowIcon() 
    174 { 
    175     if (m_bEnabled && m_bHidden) { 
    176         m_tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; 
    177         Shell_NotifyIcon(NIM_ADD, &m_tnd); 
     351    if (Shell_NotifyIcon(NIM_DELETE, &m_tnd)) 
     352        m_bRemoved = m_bHidden = TRUE; 
     353 
     354    return (m_bRemoved == TRUE); 
     355} 
     356 
     357BOOL CSystemTray::HideIcon() 
     358{ 
     359    if (!m_bEnabled || m_bRemoved || m_bHidden) 
     360        return TRUE; 
     361 
     362#ifdef SYSTEMTRAY_USEW2K 
     363    if (m_bWin2K) 
     364    { 
     365        m_tnd.uFlags = NIF_STATE; 
     366        m_tnd.dwState = NIS_HIDDEN; 
     367        m_tnd.dwStateMask = NIS_HIDDEN; 
     368 
     369        m_bHidden = Shell_NotifyIcon( NIM_MODIFY, &m_tnd); 
     370    } 
     371    else 
     372#endif 
     373        RemoveIcon(); 
     374 
     375    return (m_bHidden == TRUE); 
     376} 
     377 
     378BOOL CSystemTray::ShowIcon() 
     379{ 
     380    if (m_bRemoved) 
     381        return AddIcon(); 
     382 
     383    if (!m_bHidden) 
     384        return TRUE; 
     385 
     386#ifdef SYSTEMTRAY_USEW2K 
     387    if (m_bWin2K) 
     388    { 
     389        m_tnd.uFlags = NIF_STATE; 
     390        m_tnd.dwState = 0; 
     391        m_tnd.dwStateMask = NIS_HIDDEN; 
     392        Shell_NotifyIcon ( NIM_MODIFY, &m_tnd ); 
    178393        m_bHidden = FALSE; 
    179394    } 
     395    else 
     396#endif 
     397        AddIcon(); 
     398 
     399    return (m_bHidden == FALSE); 
    180400} 
    181401 
    182402BOOL CSystemTray::SetIcon(HICON hIcon) 
    183403{ 
    184     if (!m_bEnabled) return FALSE; 
    185     if (m_tnd.hIcon == hIcon) return TRUE; 
     404    if (!m_bEnabled) 
     405        return FALSE; 
    186406 
    187407    m_tnd.uFlags = NIF_ICON; 
    188408    m_tnd.hIcon = hIcon; 
    189409 
    190     return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); 
     410    if (m_bHidden) 
     411        return TRUE; 
     412    else 
     413        return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); 
    191414} 
    192415 
    193416BOOL CSystemTray::SetIcon(LPCTSTR lpszIconName) 
    194417{ 
    195     HICON hIcon = AfxGetApp()->LoadIcon(lpszIconName); 
     418    HICON hIcon = (HICON) ::LoadImage(AfxGetResourceHandle(),  
     419                                      lpszIconName, 
     420                                      IMAGE_ICON,  
     421                                      0, 0, 
     422                                      LR_DEFAULTCOLOR); 
     423    if (!hIcon) 
     424        return FALSE; 
     425 
     426    BOOL bSuccess = SetIcon(hIcon); 
     427    ::DestroyIcon(hIcon); 
     428 
     429    return bSuccess; 
     430} 
     431 
     432BOOL CSystemTray::SetIcon(UINT nIDResource) 
     433{ 
     434    return SetIcon(MAKEINTRESOURCE(nIDResource)); 
     435} 
     436 
     437BOOL CSystemTray::SetStandardIcon(LPCTSTR lpIconName) 
     438{ 
     439    HICON hIcon = LoadIcon(NULL, lpIconName); 
    196440 
    197441    return SetIcon(hIcon); 
    198442} 
    199443 
    200 BOOL CSystemTray::SetIcon(UINT nIDResource) 
    201 { 
    202     HICON hIcon = AfxGetApp()->LoadIcon(nIDResource); 
    203  
    204     return SetIcon(hIcon); 
    205 } 
    206  
    207 BOOL CSystemTray::SetStandardIcon(LPCTSTR lpIconName) 
    208 { 
    209     HICON hIcon = LoadIcon(NULL, lpIconName); 
    210  
    211     return SetIcon(hIcon); 
    212 } 
    213  
    214444BOOL CSystemTray::SetStandardIcon(UINT nIDResource) 
    215445{ 
    216     HICON hIcon = LoadIcon(NULL, MAKEINTRESOURCE(nIDResource)); 
    217  
    218     return SetIcon(hIcon); 
     446    return SetStandardIcon(MAKEINTRESOURCE(nIDResource)); 
    219447} 
    220448  
     
    226454BOOL CSystemTray::SetIconList(UINT uFirstIconID, UINT uLastIconID)  
    227455{ 
    228     if (uFirstIconID > uLastIconID) 
    229         return FALSE; 
    230  
    231 //    UINT uIconArraySize = uLastIconID - uFirstIconID + 1; 
    232     const CWinApp * pApp = AfxGetApp(); 
    233     ASSERT(pApp != 0); 
     456    if (uFirstIconID > uLastIconID) 
     457        return FALSE; 
     458 
     459    const CWinApp* pApp = AfxGetApp(); 
     460    if (!pApp) 
     461    { 
     462        ASSERT(FALSE); 
     463        return FALSE; 
     464    } 
    234465 
    235466    m_IconList.RemoveAll(); 
    236     try { 
    237         for (UINT i = uFirstIconID; i <= uLastIconID; i++) 
    238             m_IconList.Add(pApp->LoadIcon(i)); 
    239     } 
    240     catch (CException *e) 
    241     { 
    242         REPORT_ERROR(e); 
     467    TRY { 
     468        for (UINT i = uFirstIconID; i <= uLastIconID; i++) 
     469            m_IconList.Add(pApp->LoadIcon(i)); 
     470    } 
     471    CATCH(CMemoryException, e) 
     472    { 
     473        e->ReportError(); 
    243474        e->Delete(); 
    244475        m_IconList.RemoveAll(); 
    245476        return FALSE; 
    246477    } 
     478    END_CATCH 
    247479 
    248480    return TRUE; 
     
    253485    m_IconList.RemoveAll(); 
    254486 
    255     try { 
    256         for (UINT i = 0; i <= nNumIcons; i++) 
    257             m_IconList.Add(pHIconList[i]); 
    258     } 
    259     catch (CException *e) 
    260     { 
    261         REPORT_ERROR(e); 
     487    TRY { 
     488        for (UINT i = 0; i < nNumIcons; i++) 
     489            m_IconList.Add(pHIconList[i]); 
     490    } 
     491    CATCH (CMemoryException, e) 
     492    { 
     493        e->ReportError(); 
    262494        e->Delete(); 
    263495        m_IconList.RemoveAll(); 
    264496        return FALSE; 
    265497    } 
     498    END_CATCH 
    266499 
    267500    return TRUE; 
     
    270503BOOL CSystemTray::Animate(UINT nDelayMilliSeconds, int nNumSeconds /*=-1*/) 
    271504{ 
     505    if (m_IconList.IsEmpty()) 
     506        return FALSE; 
     507 
    272508    StopAnimation(); 
    273509 
    274510    m_nCurrentIcon = 0; 
    275     m_StartTime = GetTimeTimeZoneBased(); 
     511    m_StartTime = COleDateTime::GetCurrentTime(); 
    276512    m_nAnimationPeriod = nNumSeconds; 
    277513    m_hSavedIcon = GetIcon(); 
    278514 
    279     // Setup a timer for the animation 
    280     m_uIDTimer = SetTimer(m_nIDEvent, nDelayMilliSeconds, NULL); 
     515    // Setup a timer for the animation 
     516    m_uIDTimer = SetTimer(m_nTimerID, nDelayMilliSeconds, NULL); 
    281517 
    282518    return (m_uIDTimer != 0); 
     
    300536 
    301537    if (m_uIDTimer) 
    302         bResult = KillTimer(m_uIDTimer); 
     538        bResult = KillTimer(m_uIDTimer); 
    303539    m_uIDTimer = 0; 
    304540 
     
    315551BOOL CSystemTray::SetTooltipText(LPCTSTR pszTip) 
    316552{ 
    317     if (!m_bEnabled) return FALSE; 
     553    ASSERT(AfxIsValidString(pszTip)); // (md) 
     554    ASSERT(_tcslen(pszTip) < m_nMaxTooltipLength); 
     555 
     556    if (!m_bEnabled)  
     557        return FALSE; 
    318558 
    319559    m_tnd.uFlags = NIF_TIP; 
    320     _tcsncpy(m_tnd.szTip, pszTip, 64); 
    321  
    322     return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); 
     560    _tcsncpy(m_tnd.szTip, pszTip, m_nMaxTooltipLength-1); 
     561 
     562    if (m_bHidden) 
     563        return TRUE; 
     564    else 
     565        return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); 
    323566} 
    324567 
     
    326569{ 
    327570    CString strText; 
    328  
    329     try 
    330     { 
    331         VERIFY(strText.LoadString(nID)); 
    332     } 
    333     catch (...) 
    334     { 
    335         strText.Empty(); 
    336     } 
     571    VERIFY(strText.LoadString(nID)); 
    337572 
    338573    return SetTooltipText(strText); 
     
    349584 
    350585///////////////////////////////////////////////////////////////////////////// 
     586// CSystemTray support for Win 2K features. 
     587 
     588////////////////////////////////////////////////////////////////////////// 
     589// 
     590// Function:    ShowBalloon 
     591// 
     592// Description: 
     593//  Shows a balloon tooltip over the tray icon. 
     594// 
     595// Input: 
     596//  szText: [in] Text for the balloon tooltip. 
     597//  szTitle: [in] Title for the balloon.  This text is shown in bold above 
     598//           the tooltip text (szText).  Pass "" if you don't want a title. 
     599//  dwIcon: [in] Specifies an icon to appear in the balloon.  Legal values are: 
     600//                 NIIF_NONE: No icon 
     601//                 NIIF_INFO: Information 
     602//                 NIIF_WARNING: Exclamation 
     603//                 NIIF_ERROR: Critical error (red circle with X) 
     604//  uTimeout: [in] Number of seconds for the balloon to remain visible.  Can 
     605//            be between 10 and 30 inclusive. 
     606// 
     607// Returns: 
     608//  TRUE if successful, FALSE if not. 
     609// 
     610////////////////////////////////////////////////////////////////////////// 
     611// Added by Michael Dunn, November 1999 
     612////////////////////////////////////////////////////////////////////////// 
     613 
     614BOOL CSystemTray::ShowBalloon(LPCTSTR szText, 
     615                              LPCTSTR szTitle  /*=NULL*/, 
     616                              DWORD   dwIcon   /*=NIIF_NONE*/, 
     617                              UINT    uTimeout /*=10*/ ) 
     618{ 
     619#ifndef SYSTEMTRAY_USEW2K 
     620    return FALSE; 
     621#else 
     622    // Bail out if we're not on Win 2K. 
     623    if (!m_bWin2K) 
     624        return FALSE; 
     625 
     626    // Verify input parameters. 
     627 
     628    // The balloon tooltip text can be up to 255 chars long. 
     629    ASSERT(AfxIsValidString(szText)); 
     630    ASSERT(lstrlen(szText) < 256); 
     631 
     632    // The balloon title text can be up to 63 chars long. 
     633    if (szTitle) 
     634    { 
     635        ASSERT(AfxIsValidString( szTitle)); 
     636        ASSERT(lstrlen(szTitle) < 64); 
     637    } 
     638 
     639    // dwBalloonIcon must be valid. 
     640    ASSERT(NIIF_NONE == dwIcon    || NIIF_INFO == dwIcon || 
     641           NIIF_WARNING == dwIcon || NIIF_ERROR == dwIcon); 
     642 
     643    // The timeout must be between 10 and 30 seconds. 
     644    ASSERT(uTimeout >= 10 && uTimeout <= 30); 
     645 
     646 
     647    m_tnd.uFlags = NIF_INFO; 
     648    _tcsncpy(m_tnd.szInfo, szText, 256); 
     649    if (szTitle) 
     650        _tcsncpy(m_tnd.szInfoTitle, szTitle, 64); 
     651    else 
     652        m_tnd.szInfoTitle[0] = _T('\0'); 
     653    m_tnd.dwInfoFlags = dwIcon; 
     654    m_tnd.uTimeout = uTimeout * 1000;   // convert time to ms 
     655 
     656    BOOL bSuccess = Shell_NotifyIcon (NIM_MODIFY, &m_tnd); 
     657 
     658    // Zero out the balloon text string so that later operations won't redisplay 
     659    // the balloon. 
     660    m_tnd.szInfo[0] = _T('\0'); 
     661 
     662    return bSuccess; 
     663#endif 
     664} 
     665 
     666///////////////////////////////////////////////////////////////////////////// 
    351667// CSystemTray notification window stuff 
    352668 
    353669BOOL CSystemTray::SetNotificationWnd(CWnd* pWnd) 
    354670{ 
    355     if (!m_bEnabled) return FALSE; 
     671    if (!m_bEnabled)  
     672        return FALSE; 
    356673 
    357674    // Make sure Notification window is valid 
    358     ASSERT(pWnd && ::IsWindow(pWnd->GetSafeHwnd())); 
     675    if (!pWnd || !::IsWindow(pWnd->GetSafeHwnd())) 
     676    { 
     677        ASSERT(FALSE); 
     678        return FALSE; 
     679    } 
    359680 
    360681    m_tnd.hWnd = pWnd->GetSafeHwnd(); 
    361682    m_tnd.uFlags = 0; 
    362683 
    363     return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); 
     684    if (m_bHidden) 
     685        return TRUE; 
     686    else 
     687        return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); 
    364688} 
    365689 
     
    367691{ 
    368692    return CWnd::FromHandle(m_tnd.hWnd); 
     693} 
     694 
     695// Hatr added 
     696 
     697// Hatr added 
     698 
     699// Change or retrive the window to send menu commands to 
     700BOOL CSystemTray::SetTargetWnd(CWnd* pTargetWnd) 
     701{ 
     702    m_pTargetWnd = pTargetWnd; 
     703    return TRUE; 
     704} // CSystemTray::SetTargetWnd() 
     705 
     706CWnd* CSystemTray::GetTargetWnd() const 
     707{ 
     708    if (m_pTargetWnd) 
     709        return m_pTargetWnd; 
     710    else 
     711        return AfxGetMainWnd(); 
     712} // CSystemTray::GetTargetWnd() 
     713 
     714///////////////////////////////////////////////////////////////////////////// 
     715// CSystemTray notification message stuff 
     716 
     717BOOL CSystemTray::SetCallbackMessage(UINT uCallbackMessage) 
     718{ 
     719    if (!m_bEnabled) 
     720        return FALSE; 
     721 
     722    // Make sure we avoid conflict with other messages 
     723    ASSERT(uCallbackMessage >= WM_APP); 
     724 
     725    m_tnd.uCallbackMessage = uCallbackMessage; 
     726    m_tnd.uFlags = NIF_MESSAGE; 
     727 
     728    if (m_bHidden) 
     729        return TRUE; 
     730    else 
     731        return Shell_NotifyIcon(NIM_MODIFY, &m_tnd); 
     732} 
     733 
     734UINT CSystemTray::GetCallbackMessage() const 
     735{ 
     736    return m_tnd.uCallbackMessage; 
    369737} 
    370738 
     
    374742BOOL CSystemTray::SetMenuDefaultItem(UINT uItem, BOOL bByPos) 
    375743{ 
     744#ifdef _WIN32_WCE 
     745    return FALSE; 
     746#else 
    376747    if ((m_DefaultMenuItemID == uItem) && (m_DefaultMenuItemByPos == bByPos))  
    377748        return TRUE; 
     
    382753    CMenu menu, *pSubMenu; 
    383754 
    384     if (!menu.LoadMenu(m_tnd.uID)) return FALSE; 
     755    if (!menu.LoadMenu(m_tnd.uID)) 
     756        return FALSE; 
    385757 
    386758    pSubMenu = menu.GetSubMenu(0); 
    387     if (!pSubMenu) return FALSE; 
     759    if (!pSubMenu) 
     760        return FALSE; 
    388761 
    389762    ::SetMenuDefaultItem(pSubMenu->m_hMenu, m_DefaultMenuItemID, m_DefaultMenuItemByPos); 
    390763 
    391     menu.DestroyMenu(); 
    392  
    393764    return TRUE; 
     765#endif 
    394766} 
    395767 
     
    404776 
    405777BEGIN_MESSAGE_MAP(CSystemTray, CWnd) 
    406     //{{AFX_MSG_MAP(CSystemTray) 
    407     ON_WM_TIMER() 
    408     //}}AFX_MSG_MAP 
     778    //{{AFX_MSG_MAP(CSystemTray) 
     779    ON_WM_TIMER() 
     780    //}}AFX_MSG_MAP 
     781#ifndef _WIN32_WCE 
     782    ON_WM_SETTINGCHANGE() 
     783#endif 
     784    ON_REGISTERED_MESSAGE(CSystemTray::m_nTaskbarCreatedMsg, OnTaskbarCreated) 
    409785END_MESSAGE_MAP() 
    410786 
    411787void CSystemTray::OnTimer(UINT_PTR nIDEvent)  
    412788{ 
    413     UNUSED(nIDEvent); 
    414     ASSERT(nIDEvent == m_nIDEvent); 
    415  
    416     COleDateTime CurrentTime = GetTimeTimeZoneBased(); 
     789    if (nIDEvent != m_uIDTimer) 
     790    { 
     791        ASSERT(FALSE); 
     792        return; 
     793    } 
     794 
     795    COleDateTime CurrentTime = COleDateTime::GetCurrentTime(); 
    417796    COleDateTimeSpan period = CurrentTime - m_StartTime; 
     797 
    418798    if (m_nAnimationPeriod > 0 && m_nAnimationPeriod < period.GetTotalSeconds()) 
    419799    { 
     
    425805} 
    426806 
    427 void CSystemTray::DeleteItem(UINT uItem) 
    428 { 
    429     m_ItemsToDelete.Add(uItem); 
    430 } 
    431  
    432 void CSystemTray::CheckItem(UINT uItem) 
    433 { 
    434     m_ItemsToCheck.Add(uItem); 
    435 } 
    436  
    437 void CSystemTray::DisableItem(UINT uItem) 
    438 { 
    439     m_ItemsToDisable.Add(uItem); 
    440 } 
    441  
    442 void CSystemTray::CleanCheckList() 
    443 { 
    444     m_ItemsToCheck.RemoveAll(); 
    445 } 
    446  
    447 void CSystemTray::CleanDisableList() 
    448 { 
    449     m_ItemsToDisable.RemoveAll(); 
    450 } 
    451  
    452 void CSystemTray::CleanDeleteList() 
    453 { 
    454     m_ItemsToDelete.RemoveAll(); 
    455 } 
     807// This is called whenever the taskbar is created (eg after explorer crashes 
     808// and restarts. Please note that the WM_TASKBARCREATED message is only passed 
     809// to TOP LEVEL windows (like WM_QUERYNEWPALETTE) 
     810LRESULT CSystemTray::OnTaskbarCreated(WPARAM /*wParam*/, LPARAM /*lParam*/)  
     811{ 
     812    m_bShowIconPending = TRUE; // !m_bHidden; 
     813    InstallIconPending(); 
     814 
     815    return 0L; 
     816} 
     817 
     818#ifndef _WIN32_WCE 
     819void CSystemTray::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)  
     820{ 
     821    CWnd::OnSettingChange(uFlags, lpszSection); 
     822 
     823    if (uFlags == SPI_SETWORKAREA) 
     824    { 
     825        m_bShowIconPending = !m_bHidden; 
     826        InstallIconPending();    
     827    } 
     828} 
     829#endif 
    456830 
    457831LRESULT CSystemTray::OnTrayNotification(WPARAM wParam, LPARAM lParam)  
     
    459833    //Return quickly if its not for this tray icon 
    460834    if (wParam != m_tnd.uID) 
    461         return(0L); 
     835        return 0L; 
    462836 
    463837    CMenu menu, *pSubMenu; 
    464     CWnd* pTarget = AfxGetMainWnd(); 
    465  
    466     // sanity check - st@iki.fi 
    467     if (!IsWindow(pTarget->GetSafeHwnd())) 
    468         return(0); 
     838    CWnd *pTargetWnd = GetTargetWnd(); 
     839    if (!pTargetWnd) 
     840        return 0L; 
    469841 
    470842    // Clicking with right button brings up a context menu 
     843#if defined(_WIN32_WCE) //&& _WIN32_WCE < 211 
     844    BOOL bAltPressed = ((GetKeyState(VK_MENU) & (1 << (sizeof(SHORT)*8-1))) != 0); 
     845    if (LOWORD(lParam) == WM_LBUTTONUP && bAltPressed) 
     846#else 
    471847    if (LOWORD(lParam) == WM_RBUTTONUP) 
     848#endif 
    472849    {     
    473         if (!menu.LoadMenu(m_tnd.uID)) return(0); 
     850        if (!menu.LoadMenu(m_tnd.uID)) 
     851            return 0; 
    474852         
    475853        pSubMenu = menu.GetSubMenu(0); 
    476         if (!pSubMenu) return(0); 
    477  
     854        if (!pSubMenu) 
     855            return 0; 
     856 
     857#ifndef _WIN32_WCE 
    478858        // Make chosen menu item the default (bold font) 
    479859        ::SetMenuDefaultItem(pSubMenu->m_hMenu, m_DefaultMenuItemID, m_DefaultMenuItemByPos); 
    480  
    481         // Delete unwanted items 
    482         UINT uIndex, uSize = m_ItemsToDelete.GetSize(); 
    483         for (uIndex = 0; uIndex < uSize; uIndex++) 
    484             pSubMenu->DeleteMenu(m_ItemsToDelete[uIndex], MF_BYCOMMAND); 
    485  
    486         // Check items 
    487         uSize = m_ItemsToCheck.GetSize(); 
    488         for (uIndex = 0; uIndex < uSize; uIndex++) 
    489             pSubMenu->CheckMenuItem(m_ItemsToCheck[uIndex], MF_BYCOMMAND | MF_CHECKED); 
    490  
    491         // Disable items 
    492         uSize = m_ItemsToDisable.GetSize(); 
    493         for (uIndex = 0; uIndex < uSize; uIndex++) 
    494             pSubMenu->EnableMenuItem(m_ItemsToDisable[uIndex], MF_DISABLED | MF_GRAYED | MF_BYCOMMAND); 
     860#endif 
     861 
     862        CustomizeMenu(pSubMenu); 
    495863 
    496864        // Display and track the popup menu 
    497865        CPoint pos; 
     866#ifdef _WIN32_WCE 
     867        pos = CPoint(GetMessagePos()); 
     868#else 
    498869        GetCursorPos(&pos); 
    499  
    500         pTarget->SetForegroundWindow();   
     870#endif 
     871 
     872        pTargetWnd->SetForegroundWindow();  
     873         
     874#ifndef _WIN32_WCE 
    501875        ::TrackPopupMenu(pSubMenu->m_hMenu, 0, pos.x, pos.y, 0,  
    502                          pTarget->GetSafeHwnd(), NULL); 
     876                         pTargetWnd->GetSafeHwnd(), NULL); 
     877#else 
     878        pSubMenu->TrackPopupMenu(TPM_LEFTALIGN, pos.x, pos.y, pTargetWnd, NULL); 
     879#endif 
    503880 
    504881        // BUGFIX: See "PRB: Menus for Notification Icons Don't Work Correctly" 
    505         pTarget->PostMessage(WM_NULL, 0, 0); 
     882        pTargetWnd->PostMessage(WM_NULL, 0, 0); 
    506883 
    507884        menu.DestroyMenu(); 
    508885    }  
     886#if defined(_WIN32_WCE) //&& _WIN32_WCE < 211 
     887    if (LOWORD(lParam) == WM_LBUTTONDBLCLK && bAltPressed) 
     888#else 
    509889    else if (LOWORD(lParam) == WM_LBUTTONDBLCLK)  
     890#endif 
    510891    { 
    511892        // double click received, the default action is to execute default menu item 
    512         pTarget->SetForegroundWindow();   
     893        pTargetWnd->SetForegroundWindow();   
    513894 
    514895        UINT uItem; 
    515896        if (m_DefaultMenuItemByPos) 
    516897        { 
    517             if (!menu.LoadMenu(m_tnd.uID)) return(0); 
     898            if (!menu.LoadMenu(m_tnd.uID)) 
     899                return 0; 
     900             
    518901            pSubMenu = menu.GetSubMenu(0); 
    519             if (!pSubMenu) return(0); 
    520  
     902            if (!pSubMenu) 
     903                return 0; 
     904             
    521905            uItem = pSubMenu->GetMenuItemID(m_DefaultMenuItemID); 
     906 
     907            menu.DestroyMenu(); 
    522908        } 
    523909        else 
    524910            uItem = m_DefaultMenuItemID; 
    525911         
    526         pTarget->SendMessage(WM_COMMAND, uItem, 0); 
    527  
    528         menu.DestroyMenu(); 
    529     } 
    530  
    531     return(1); 
     912        pTargetWnd->PostMessage(WM_COMMAND, uItem, 0); 
     913    } 
     914 
     915    return 1; 
    532916} 
    533917 
     
    536920    if (message == m_tnd.uCallbackMessage) 
    537921        return OnTrayNotification(wParam, lParam); 
     922     
     923    return CWnd::WindowProc(message, wParam, lParam); 
     924} 
     925 
     926void CSystemTray::InstallIconPending() 
     927{ 
     928    // Is the icon display pending, and it's not been set as "hidden"? 
     929    if (!m_bShowIconPending || m_bHidden) 
     930        return; 
     931 
     932    // Reset the flags to what was used at creation 
     933    m_tnd.uFlags = m_uCreationFlags; 
     934 
     935    // Try and recreate the icon 
     936    m_bHidden = !Shell_NotifyIcon(NIM_ADD, &m_tnd); 
     937 
     938    // If it's STILL hidden, then have another go next time... 
     939    m_bShowIconPending = m_bHidden; 
     940 
     941    ASSERT(m_bHidden == FALSE); 
     942} 
     943 
     944///////////////////////////////////////////////////////////////////////////// 
     945// For minimising/maximising from system tray 
     946 
     947BOOL CALLBACK FindTrayWnd(HWND hwnd, LPARAM lParam) 
     948{ 
     949    TCHAR szClassName[256]; 
     950    GetClassName(hwnd, szClassName, 255); 
     951 
     952    // Did we find the Main System Tray? If so, then get its size and keep going 
     953    if (_tcscmp(szClassName, _T("TrayNotifyWnd")) == 0) 
     954    { 
     955        CRect *pRect = (CRect*) lParam; 
     956        ::GetWindowRect(hwnd, pRect); 
     957        return TRUE; 
     958    } 
     959 
     960    // Did we find the System Clock? If so, then adjust the size of the rectangle 
     961    // we have and quit (clock will be found after the system tray) 
     962    if (_tcscmp(szClassName, _T("TrayClockWClass")) == 0) 
     963    { 
     964        CRect *pRect = (CRect*) lParam; 
     965        CRect rectClock; 
     966        ::GetWindowRect(hwnd, rectClock); 
     967        // if clock is above system tray adjust accordingly 
     968        if (rectClock.bottom < pRect->bottom-5) // 10 = random fudge factor. 
     969            pRect->top = rectClock.bottom; 
     970        else 
     971            pRect->right = rectClock.left; 
     972        return FALSE; 
     973    } 
     974  
     975    return TRUE; 
     976} 
     977  
     978#ifndef _WIN32_WCE 
     979// enhanced version by Matthew Ellis <m.t.ellis@bigfoot.com> 
     980void CSystemTray::GetTrayWndRect(LPRECT lprect) 
     981{ 
     982#define DEFAULT_RECT_WIDTH 150 
     983#define DEFAULT_RECT_HEIGHT 30 
     984 
     985    HWND hShellTrayWnd = ::FindWindow(_T("Shell_TrayWnd"), NULL); 
     986    if (hShellTrayWnd) 
     987    { 
     988        ::GetWindowRect(hShellTrayWnd, lprect); 
     989        EnumChildWindows(hShellTrayWnd, FindTrayWnd, (LPARAM)lprect); 
     990        return; 
     991    } 
     992    // OK, we failed to get the rect from the quick hack. Either explorer isn't 
     993    // running or it's a new version of the shell with the window class names 
     994    // changed (how dare Microsoft change these undocumented class names!) So, we 
     995    // try to find out what side of the screen the taskbar is connected to. We 
     996    // know that the system tray is either on the right or the bottom of the 
     997    // taskbar, so we can make a good guess at where to minimize to 
     998    APPBARDATA appBarData; 
     999    appBarData.cbSize=sizeof(appBarData); 
     1000    if (SHAppBarMessage(ABM_GETTASKBARPOS,&appBarData)) 
     1001    { 
     1002        // We know the edge the taskbar is connected to, so guess the rect of the 
     1003        // system tray. Use various fudge factor to make it look good 
     1004        switch(appBarData.uEdge) 
     1005        { 
     1006        case ABE_LEFT: 
     1007        case ABE_RIGHT: 
     1008            // We want to minimize to the bottom of the taskbar 
     1009            lprect->top    = appBarData.rc.bottom-100; 
     1010            lprect->bottom = appBarData.rc.bottom-16; 
     1011            lprect->left   = appBarData.rc.left; 
     1012            lprect->right  = appBarData.rc.right; 
     1013            break; 
     1014             
     1015        case ABE_TOP: 
     1016        case ABE_BOTTOM: 
     1017            // We want to minimize to the right of the taskbar 
     1018            lprect->top    = appBarData.rc.top; 
     1019            lprect->bottom = appBarData.rc.bottom; 
     1020            lprect->left   = appBarData.rc.right-100; 
     1021            lprect->right  = appBarData.rc.right-16; 
     1022            break; 
     1023        } 
     1024        return; 
     1025    } 
    5381026     
    539     return CWnd::WindowProc(message, wParam, lParam); 
    540 } 
     1027    // Blimey, we really aren't in luck. It's possible that a third party shell 
     1028    // is running instead of explorer. This shell might provide support for the 
     1029    // system tray, by providing a Shell_TrayWnd window (which receives the 
     1030    // messages for the icons) So, look for a Shell_TrayWnd window and work out 
     1031    // the rect from that. Remember that explorer's taskbar is the Shell_TrayWnd, 
     1032    // and stretches either the width or the height of the screen. We can't rely 
     1033    // on the 3rd party shell's Shell_TrayWnd doing the same, in fact, we can't 
     1034    // rely on it being any size. The best we can do is just blindly use the 
     1035    // window rect, perhaps limiting the width and height to, say 150 square. 
     1036    // Note that if the 3rd party shell supports the same configuraion as 
     1037    // explorer (the icons hosted in NotifyTrayWnd, which is a child window of 
     1038    // Shell_TrayWnd), we would already have caught it above 
     1039    if (hShellTrayWnd) 
     1040    { 
     1041        ::GetWindowRect(hShellTrayWnd, lprect); 
     1042        if (lprect->right - lprect->left > DEFAULT_RECT_WIDTH) 
     1043            lprect->left = lprect->right - DEFAULT_RECT_WIDTH; 
     1044        if (lprect->bottom - lprect->top > DEFAULT_RECT_HEIGHT) 
     1045            lprect->top = lprect->bottom - DEFAULT_RECT_HEIGHT; 
     1046         
     1047        return; 
     1048    } 
     1049     
     1050    // OK. Haven't found a thing. Provide a default rect based on the current work 
     1051    // area 
     1052    SystemParametersInfo(SPI_GETWORKAREA,0, lprect, 0); 
     1053    lprect->left = lprect->right - DEFAULT_RECT_WIDTH; 
     1054    lprect->top  = lprect->bottom - DEFAULT_RECT_HEIGHT; 
     1055} 
     1056 
     1057// Check to see if the animation has been disabled (Matthew Ellis <m.t.ellis@bigfoot.com>) 
     1058BOOL CSystemTray::GetDoWndAnimation() 
     1059{ 
     1060  ANIMATIONINFO ai; 
     1061 
     1062  ai.cbSize=sizeof(ai); 
     1063  SystemParametersInfo(SPI_GETANIMATION,sizeof(ai),&ai,0); 
     1064 
     1065  return ai.iMinAnimate?TRUE:FALSE; 
     1066} 
     1067#endif 
     1068 
     1069BOOL CSystemTray::RemoveTaskbarIcon(CWnd* pWnd) 
     1070{ 
     1071    LPCTSTR pstrOwnerClass = AfxRegisterWndClass(0); 
     1072 
     1073    // Create static invisible window 
     1074    if (!::IsWindow(m_wndInvisible.m_hWnd)) 
     1075    { 
     1076        if (!m_wndInvisible.CreateEx(0, pstrOwnerClass, _T(""), WS_POPUP, 
     1077                CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
     1078                NULL, 0)) 
     1079            return FALSE; 
     1080    } 
     1081 
     1082    pWnd->SetParent(&m_wndInvisible); 
     1083 
     1084    return TRUE; 
     1085} 
     1086 
     1087void CSystemTray::MinimiseToTray(CWnd* pWnd, BOOL bForceAnimation /*= FALSE*/) 
     1088{ 
     1089#ifndef _WIN32_WCE 
     1090    if (bForceAnimation || GetDoWndAnimation()) 
     1091    { 
     1092        CRect rectFrom, rectTo; 
     1093 
     1094        pWnd->GetWindowRect(rectFrom); 
     1095        GetTrayWndRect(rectTo); 
     1096 
     1097        ::DrawAnimatedRects(pWnd->m_hWnd, IDANI_CAPTION, rectFrom, rectTo); 
     1098    } 
     1099 
     1100    RemoveTaskbarIcon(pWnd); 
     1101    pWnd->ModifyStyle(WS_VISIBLE, 0); 
     1102#endif 
     1103} 
     1104 
     1105void CSystemTray::MaximiseFromTray(CWnd* pWnd, BOOL bForceAnimation /*= TRUE*/) 
     1106{ 
     1107#ifndef _WIN32_WCE 
     1108    if (bForceAnimation || GetDoWndAnimation()) 
     1109    { 
     1110        CRect rectTo; 
     1111        pWnd->GetWindowRect(rectTo); 
     1112 
     1113        CRect rectFrom; 
     1114        GetTrayWndRect(rectFrom); 
     1115 
     1116        pWnd->SetParent(NULL); 
     1117        ::DrawAnimatedRects(pWnd->m_hWnd, IDANI_CAPTION, rectFrom, rectTo); 
     1118    } 
     1119    else 
     1120        pWnd->SetParent(NULL); 
     1121 
     1122    pWnd->ModifyStyle(0, WS_VISIBLE); 
     1123    pWnd->RedrawWindow(NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_FRAME | 
     1124                                   RDW_INVALIDATE | RDW_ERASE); 
     1125 
     1126    // Move focus away and back again to ensure taskbar icon is recreated 
     1127    if (::IsWindow(m_wndInvisible.m_hWnd)) 
     1128        m_wndInvisible.SetActiveWindow(); 
     1129    pWnd->SetActiveWindow(); 
     1130    pWnd->SetForegroundWindow(); 
     1131#endif 
     1132} 
Note: See TracChangeset for help on using the changeset viewer.