You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
765 lines
19 KiB
765 lines
19 KiB
//
|
|
// utbtray.cpp
|
|
//
|
|
|
|
#include "private.h"
|
|
#include "globals.h"
|
|
#include "utbtray.h"
|
|
#include "inatlib.h"
|
|
#include "xstring.h"
|
|
#include "inatlib.h"
|
|
#include "tipbar.h"
|
|
#include "shlapip.h"
|
|
#include "nuiinat.h"
|
|
#include "resource.h"
|
|
#include "cresstr.h"
|
|
#include "cregkey.h"
|
|
#include "nuiinat.h"
|
|
#include "dlgs.h"
|
|
|
|
HICON WINAPI TF_GetLangIcon(WORD langid , WCHAR *psz, UINT cchMax);
|
|
|
|
const char CTrayIconWnd::_szWndClass[] = "CTrayIconWndClass";
|
|
extern UINT g_wmTaskbarCreated;
|
|
extern CTipbarWnd *g_pTipbarWnd;
|
|
|
|
/* e0b724e9-6f76-45f7-b4c1-b1c0fabce23e */
|
|
const GUID GUID_LBI_TRAYMAIN = {
|
|
0xe0b724e9,
|
|
0x6f76,
|
|
0x45f7,
|
|
{0xb4, 0xc1, 0xb1, 0xc0, 0xfa, 0xbc, 0xe2, 0x3e}
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CTrayIconItem
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// ctor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CTrayIconItem::CTrayIconItem(CTrayIconWnd *ptiwnd)
|
|
{
|
|
_fIconPrev = FALSE;
|
|
_ptiwnd = ptiwnd;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// dtor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CTrayIconItem::~CTrayIconItem()
|
|
{
|
|
RemoveIcon();
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Init
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CTrayIconItem::_Init(HWND hwnd, UINT uCallbackMessage, UINT uID, REFGUID rguid)
|
|
{
|
|
_hwnd = hwnd;
|
|
_uCallbackMessage = uCallbackMessage;
|
|
_uID = uID;
|
|
_guidBtnItem = rguid;
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// SetIcon
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CTrayIconItem::SetIcon(HICON hIcon, const WCHAR *pszTooltip)
|
|
{
|
|
DWORD dwMessage;
|
|
|
|
if (!hIcon)
|
|
return FALSE;
|
|
|
|
if (!_fIconPrev)
|
|
dwMessage = NIM_ADD;
|
|
else
|
|
dwMessage = NIM_MODIFY;
|
|
|
|
if (IsOnNT())
|
|
{
|
|
NOTIFYICONDATAW tndw;
|
|
tndw.cbSize = sizeof(NOTIFYICONDATAW);
|
|
tndw.hWnd = _hwnd;
|
|
tndw.uCallbackMessage = _uCallbackMessage;
|
|
tndw.uID = _uID;
|
|
tndw.uFlags = NIF_MESSAGE | NIF_ICON;
|
|
tndw.hIcon = hIcon;
|
|
if (pszTooltip)
|
|
{
|
|
tndw.uFlags |= NIF_TIP;
|
|
StringCchCopyW(tndw.szTip, ARRAYSIZE(tndw.szTip), pszTooltip);
|
|
}
|
|
Shell_NotifyIconW(dwMessage, &tndw);
|
|
}
|
|
else
|
|
{
|
|
NOTIFYICONDATA tnd;
|
|
tnd.cbSize = sizeof(NOTIFYICONDATA);
|
|
tnd.hWnd = _hwnd;
|
|
tnd.uCallbackMessage = _uCallbackMessage;
|
|
tnd.uID = _uID;
|
|
tnd.uFlags = NIF_MESSAGE | NIF_ICON;
|
|
tnd.hIcon = hIcon;
|
|
if (pszTooltip)
|
|
{
|
|
tnd.uFlags |= NIF_TIP;
|
|
StringCchCopyA(tnd.szTip, ARRAYSIZE(tnd.szTip), WtoA(pszTooltip));
|
|
}
|
|
Shell_NotifyIcon(dwMessage, &tnd);
|
|
}
|
|
|
|
_fIconPrev = TRUE;
|
|
_fShownInTray = TRUE;
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// RemoveIcon
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CTrayIconItem::RemoveIcon()
|
|
{
|
|
NOTIFYICONDATA tnd;
|
|
|
|
if (_fIconPrev) // this check is esp useful because we delay load shell32.dll
|
|
{
|
|
tnd.cbSize = sizeof(NOTIFYICONDATA);
|
|
tnd.hWnd = _hwnd;
|
|
tnd.uCallbackMessage = _uCallbackMessage;
|
|
tnd.uID = _uID;
|
|
tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
|
|
tnd.hIcon = NULL;
|
|
tnd.szTip[0] = '\0';
|
|
|
|
Shell_NotifyIcon(NIM_DELETE, &tnd);
|
|
}
|
|
|
|
_fIconPrev = FALSE;
|
|
_fShownInTray = FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// UpdateMenuRectPoint
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CTrayIconItem::UpdateMenuRectPoint()
|
|
{
|
|
HWND hwndNotify = _ptiwnd->GetNotifyWnd();
|
|
GetClientRect(hwndNotify, &_rcClick);
|
|
ClientToScreen(hwndNotify, (LPPOINT)&_rcClick.left);
|
|
ClientToScreen(hwndNotify, (LPPOINT)&_rcClick.right);
|
|
|
|
GetCursorPos(&_ptClick);
|
|
// *ppt = *(LPPOINT)prc;
|
|
// MapWindowPoints(hwndNotify, NULL, ppt, 2);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CButtonIconItem
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// ctor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CButtonIconItem::CButtonIconItem(CTrayIconWnd *ptiwnd, BOOL fMenuButtonItem) : CTrayIconItem(ptiwnd)
|
|
{
|
|
_fMenuButtonItem = fMenuButtonItem;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// dtor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CButtonIconItem::~CButtonIconItem()
|
|
{
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnMsg
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CButtonIconItem::OnMsg(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CTipbarThread *ptt;
|
|
|
|
if ((lParam == WM_LBUTTONDOWN) || (lParam == WM_RBUTTONDOWN) ||
|
|
(lParam == WM_LBUTTONDBLCLK) || (lParam == WM_RBUTTONDBLCLK))
|
|
{
|
|
if (_ptiwnd->_fInTrayMenu)
|
|
return FALSE;
|
|
|
|
g_pTipbarWnd->CancelMenu();
|
|
_ptiwnd->_uCurCallbackMessage = _uCallbackMessage;
|
|
_ptiwnd->_uCurMouseMessage = (UINT)lParam;
|
|
::KillTimer(_ptiwnd->GetWnd(), TRAYICONWND_TIMER_ONDELAYMSG);
|
|
::SetTimer(_ptiwnd->GetWnd(), TRAYICONWND_TIMER_ONDELAYMSG, g_uTimerElapseTRAYWNDONDELAYMSG, NULL);
|
|
|
|
ptt = g_pTipbarWnd->GetFocusThread();
|
|
|
|
g_pTipbarWnd->RestoreLastFocus(&_dwThreadFocus, TRUE);
|
|
|
|
if (ptt && (ptt->_dwThreadId == _dwThreadFocus))
|
|
g_pTipbarWnd->SetWaitNotifyThread(_dwThreadFocus);
|
|
else
|
|
g_pTipbarWnd->SetWaitNotifyThread(0);
|
|
|
|
|
|
UpdateMenuRectPoint();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnDelayMsg
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CButtonIconItem::OnDelayMsg(UINT uMsg)
|
|
{
|
|
CTipbarThread *ptt;
|
|
CTipbarButtonItem *pLangBtn;
|
|
BOOL bRet = FALSE;
|
|
|
|
_ptiwnd->_fInTrayMenu = TRUE;
|
|
|
|
Assert((uMsg == WM_LBUTTONDOWN) || (uMsg == WM_RBUTTONDOWN) ||
|
|
(uMsg == WM_LBUTTONDBLCLK) || (uMsg == WM_RBUTTONDBLCLK));
|
|
|
|
g_pTipbarWnd->SetWaitNotifyThread(0);
|
|
if (!_dwThreadFocus)
|
|
{
|
|
//
|
|
// we failed to set foreground at OnMsg.
|
|
// so we try again here.
|
|
//
|
|
g_pTipbarWnd->RestoreLastFocus(&_dwThreadFocus, TRUE);
|
|
// if (!_dwThreadFocus)
|
|
// {
|
|
//
|
|
// ok now we give up to restore focus.
|
|
//
|
|
// MessageBeep(0);
|
|
// goto Exit;
|
|
// }
|
|
}
|
|
_dwThreadFocus = 0;
|
|
|
|
ptt = g_pTipbarWnd->GetFocusThread();
|
|
if (!ptt)
|
|
goto Exit;
|
|
|
|
if (g_pTipbarWnd->IsInItemChangeOrDirty(ptt))
|
|
{
|
|
::KillTimer(_ptiwnd->GetWnd(), TRAYICONWND_TIMER_ONDELAYMSG);
|
|
::SetTimer(_ptiwnd->GetWnd(), TRAYICONWND_TIMER_ONDELAYMSG, g_uTimerElapseTRAYWNDONDELAYMSG, NULL);
|
|
goto Exit;
|
|
}
|
|
|
|
pLangBtn = (CTipbarButtonItem *)(ptt->GetItem(_guidBtnItem));
|
|
if (!pLangBtn)
|
|
{
|
|
if (IsEqualGUID(_guidBtnItem, GUID_LBI_CTRL))
|
|
{
|
|
pLangBtn = (CTipbarButtonItem *)(ptt->GetItem(GUID_LBI_INATITEM));
|
|
if (!pLangBtn)
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// In this case, it is MSUTB's CLBarInatItem.
|
|
//
|
|
bRet = TRUE;
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
if (uMsg == WM_LBUTTONDOWN)
|
|
{
|
|
if (_fMenuButtonItem)
|
|
{
|
|
g_pTipbarWnd->CancelMenu();
|
|
pLangBtn->DoModalMenu(&_ptClick, &_rcClick);
|
|
}
|
|
else
|
|
{
|
|
pLangBtn->OnLeftClick();
|
|
}
|
|
}
|
|
else if (uMsg == WM_RBUTTONDOWN)
|
|
{
|
|
if (IsEqualGUID(_guidBtnItem, GUID_LBI_CTRL) ||
|
|
IsEqualGUID(_guidBtnItem, GUID_TFCAT_TIP_KEYBOARD))
|
|
{
|
|
g_pTipbarWnd->ShowContextMenu(_ptClick, &_rcClick, TRUE);
|
|
}
|
|
else
|
|
{
|
|
pLangBtn->OnRightClick();
|
|
}
|
|
}
|
|
else if (uMsg == WM_LBUTTONDBLCLK)
|
|
{
|
|
if (IsEqualGUID(_guidBtnItem, GUID_LBI_CTRL))
|
|
{
|
|
g_pTipbarWnd->GetLangBarMgr()->ShowFloating(TF_SFT_SHOWNORMAL);
|
|
}
|
|
}
|
|
|
|
bRet = TRUE;
|
|
|
|
Exit:
|
|
_ptiwnd->_fInTrayMenu = FALSE;
|
|
return bRet;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CMainIconItem
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnDelayMsg
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CMainIconItem::OnDelayMsg(UINT uMsg)
|
|
{
|
|
BOOL bRet = CButtonIconItem::OnDelayMsg(uMsg);
|
|
|
|
if (!bRet)
|
|
return bRet;
|
|
|
|
if (uMsg == WM_LBUTTONDBLCLK)
|
|
{
|
|
if (g_pTipbarWnd->_fIsItemShownInFloatingToolbar)
|
|
g_pTipbarWnd->GetLangBarMgr()->ShowFloating(TF_SFT_SHOWNORMAL);
|
|
}
|
|
else if ((uMsg == WM_LBUTTONDOWN) || (uMsg == WM_RBUTTONDOWN))
|
|
{
|
|
g_pTipbarWnd->ShowContextMenu(_ptClick, &_rcClick, (uMsg == WM_RBUTTONDOWN));
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// CTrayIconWnd
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// ctor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CTrayIconWnd::CTrayIconWnd()
|
|
{
|
|
_uNextMsg = WM_TIW_START;
|
|
_uNextID = TIW_INDICATOR_ID_START;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// dtor
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CTrayIconWnd::~CTrayIconWnd()
|
|
{
|
|
int nCnt = _rgIconItems.Count();
|
|
int i;
|
|
|
|
|
|
for ( i = 0; i < nCnt; i++)
|
|
{
|
|
CTrayIconItem *pItem = _rgIconItems.Get(i);
|
|
delete pItem;
|
|
}
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CreateWnd
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
HWND CTrayIconWnd::CreateWnd()
|
|
{
|
|
_hWnd = CreateWindowEx(0, _szWndClass, TEXT(""),
|
|
WS_DISABLED,
|
|
0, 0, 0, 0,
|
|
NULL, 0, g_hInst, this);
|
|
|
|
|
|
FindTrayEtc();
|
|
|
|
CTrayIconItem **ppItem;
|
|
|
|
_ptiiMain = new CMainIconItem(this);
|
|
if (_ptiiMain)
|
|
{
|
|
_ptiiMain->Init(_hWnd);
|
|
ppItem = _rgIconItems.Append(1);
|
|
if (ppItem)
|
|
*ppItem = _ptiiMain;
|
|
}
|
|
|
|
return _hWnd;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// RegisterClass
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CTrayIconWnd::RegisterClass()
|
|
{
|
|
WNDCLASSEX wc;
|
|
|
|
memset(&wc, 0, sizeof(wc));
|
|
wc.cbSize = sizeof(wc);
|
|
wc.style = CS_HREDRAW | CS_VREDRAW ;
|
|
wc.hInstance = g_hInst;
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wc.lpfnWndProc = _WndProc;
|
|
wc.lpszClassName = _szWndClass;
|
|
::RegisterClassEx(&wc);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
//
|
|
// BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
|
|
//
|
|
// Look at the class names using GetClassName to see if you can find the
|
|
// Tray notification Window.
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
static TCHAR szNotifyWindow[] = TEXT("TrayNotifyWnd");
|
|
BOOL CALLBACK CTrayIconWnd::EnumChildWndProc(HWND hwnd, LPARAM lParam)
|
|
{
|
|
char szString[50];
|
|
CTrayIconWnd *_this = (CTrayIconWnd *)lParam;
|
|
|
|
GetClassName(hwnd, (LPSTR) szString, sizeof(szString));
|
|
|
|
if (0 == lstrcmp(szString, szNotifyWindow))
|
|
{
|
|
_this->_hwndNotify = hwnd;
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CTrayIconWnd::FindTrayEtc()
|
|
{
|
|
_hwndTray = FindWindow(TEXT(WNDCLASS_TRAYNOTIFY), NULL);
|
|
|
|
if (!_hwndTray)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
EnumChildWindows(_hwndTray, (WNDENUMPROC)EnumChildWndProc, (LPARAM)this);
|
|
|
|
if (!_hwndNotify)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
_dwThreadIdTray = GetWindowThreadProcessId(_hwndTray, NULL);
|
|
|
|
_hwndProgman = FindWindow("Progman", NULL);
|
|
_dwThreadIdProgman = GetWindowThreadProcessId(_hwndProgman, NULL);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _WndProc
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CTrayIconWnd::CallOnDelayMsg()
|
|
{
|
|
int nCnt = _rgIconItems.Count();
|
|
int i;
|
|
BOOL bRet = FALSE;
|
|
|
|
CTrayIconItem *pItem = NULL;
|
|
for ( i = 0; i < nCnt; i++)
|
|
{
|
|
CTrayIconItem *pItemTemp = _rgIconItems.Get(i);
|
|
if (_uCurCallbackMessage == pItemTemp->GetMsg())
|
|
{
|
|
pItem = pItemTemp;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!pItem)
|
|
return;
|
|
|
|
pItem->OnDelayMsg(_uCurMouseMessage);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// _WndProc
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
LRESULT CALLBACK CTrayIconWnd::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CTrayIconWnd *_this;
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_CREATE:
|
|
SetThis(hWnd, lParam);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
SetThis(hWnd, 0);
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
{
|
|
if (wParam == TRAYICONWND_TIMER_ONDELAYMSG)
|
|
{
|
|
::KillTimer(hWnd, TRAYICONWND_TIMER_ONDELAYMSG);
|
|
_this = GetThis(hWnd);
|
|
|
|
if (_this)
|
|
_this->CallOnDelayMsg();
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if (uMsg >= WM_USER)
|
|
{
|
|
_this = GetThis(hWnd);
|
|
|
|
if (!_this || !_this->OnIconMessage(uMsg, wParam, lParam))
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
}
|
|
else
|
|
{
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// SetMainIcon
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CTrayIconWnd::SetMainIcon(HKL hkl)
|
|
{
|
|
if (hkl)
|
|
{
|
|
HICON hIcon;
|
|
WCHAR wsz[64];
|
|
|
|
if (hkl == _ptiiMain->_hkl)
|
|
return TRUE;
|
|
|
|
hIcon = TF_GetLangIcon((LANGID)HandleToUlong(hkl), wsz, ARRAYSIZE(wsz));
|
|
|
|
if (hIcon)
|
|
{
|
|
_ptiiMain->SetIcon(hIcon, wsz);
|
|
DestroyIcon(hIcon);
|
|
}
|
|
else
|
|
_ptiiMain->SetIcon(LoadIcon(g_hInst,
|
|
MAKEINTRESOURCE(ID_ICON_CONTROLBTN)),
|
|
CRStr(IDS_CONTROLBTN));
|
|
_ptiiMain->_hkl = hkl;
|
|
}
|
|
else
|
|
{
|
|
_ptiiMain->RemoveIcon();
|
|
_ptiiMain->_hkl = NULL;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnIconMessage
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CTrayIconWnd::OnIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
int nCnt = _rgIconItems.Count();
|
|
int i;
|
|
BOOL bRet = FALSE;
|
|
|
|
if (g_pTipbarWnd)
|
|
g_pTipbarWnd->AttachFocusThread();
|
|
|
|
for ( i = 0; i < nCnt; i++)
|
|
{
|
|
CTrayIconItem *pItem = _rgIconItems.Get(i);
|
|
if (uMsg == pItem->GetMsg())
|
|
{
|
|
pItem->OnMsg(wParam, lParam);
|
|
bRet = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// SetIcon
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CTrayIconWnd::SetIcon(REFGUID rguid, BOOL fMenu, HICON hIcon, const WCHAR *pszToolTip)
|
|
{
|
|
BOOL bRet;
|
|
CTrayIconItem *pItem;
|
|
pItem = FindIconItem(rguid);
|
|
|
|
//
|
|
// we don't have to create new Itom to be removed.
|
|
//
|
|
if (!pItem && hIcon)
|
|
{
|
|
CTrayIconItem **ppItem;
|
|
pItem = new CButtonIconItem(this, fMenu);
|
|
if (!pItem)
|
|
return FALSE;
|
|
|
|
pItem->_Init(GetWnd(), _uNextMsg, _uNextID, rguid);
|
|
_uNextMsg += 2;
|
|
_uNextID += 1;
|
|
|
|
//
|
|
// check if these numbers dont go over.
|
|
//
|
|
Assert(_uNextMsg >= WM_USER);
|
|
Assert(_uNextMsg < WM_APP);
|
|
Assert(_uNextID < 0x8000000);
|
|
|
|
ppItem = _rgIconItems.Append(1);
|
|
if (ppItem)
|
|
*ppItem = pItem;
|
|
}
|
|
|
|
if (!pItem)
|
|
return FALSE;
|
|
|
|
if (hIcon)
|
|
bRet = pItem->SetIcon(hIcon, pszToolTip);
|
|
else
|
|
bRet = pItem->RemoveIcon();
|
|
|
|
return bRet;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// RemoveUnusedIcons
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void CTrayIconWnd::RemoveUnusedIcons(CPtrArray<CTipbarItem> *prgItem)
|
|
{
|
|
int i,j;
|
|
for (i = 0;i < _rgIconItems.Count(); i++)
|
|
{
|
|
CTrayIconItem *pItem = _rgIconItems.Get(i);
|
|
BOOL fFound;
|
|
|
|
if (IsEqualGUID(GUID_LBI_TRAYMAIN, *pItem->GetGuid()))
|
|
continue;
|
|
|
|
fFound = FALSE;
|
|
|
|
for (j = 0;j < prgItem->Count(); j++)
|
|
{
|
|
CTipbarItem *pTipbarItem = prgItem->Get(j);
|
|
|
|
//
|
|
// in case, this item is in tray icon...
|
|
// The item may be "show satus" in other thread.
|
|
//
|
|
// if (!pTipbarItem->IsShown())
|
|
// continue;
|
|
|
|
if (IsEqualGUID(*pTipbarItem->GetGUID(), *pItem->GetGuid()))
|
|
{
|
|
fFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!fFound)
|
|
{
|
|
pItem->RemoveIcon();
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|