mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:52:59 +00:00
[EXPLORER] Fix some issues with the notification area code,
and implement NIS_SHAREDICON while at it.
This commit is contained in:
parent
22ffe5300b
commit
74e58d938e
1 changed files with 132 additions and 47 deletions
|
@ -77,16 +77,41 @@ public:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FindExistingSharedIcon(HICON handle)
|
||||||
|
{
|
||||||
|
int count = GetButtonCount();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
NOTIFYICONDATA * data = GetItemData(i);
|
||||||
|
if (data->hIcon == handle)
|
||||||
|
{
|
||||||
|
TBBUTTON btn;
|
||||||
|
GetButton(i, &btn);
|
||||||
|
return btn.iBitmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL AddButton(IN CONST NOTIFYICONDATA *iconData)
|
BOOL AddButton(IN CONST NOTIFYICONDATA *iconData)
|
||||||
{
|
{
|
||||||
TBBUTTON tbBtn;
|
TBBUTTON tbBtn;
|
||||||
NOTIFYICONDATA * notifyItem;
|
NOTIFYICONDATA * notifyItem;
|
||||||
WCHAR text[] = L"";
|
WCHAR text[] = L"";
|
||||||
|
|
||||||
|
TRACE("Adding icon %d from hWnd %08x flags%s%s state%s%s",
|
||||||
|
iconData->uID, iconData->hWnd,
|
||||||
|
(iconData->uFlags & NIF_ICON) ? " ICON" : "",
|
||||||
|
(iconData->uFlags & NIF_STATE) ? " STATE" : "",
|
||||||
|
(iconData->dwState & NIS_HIDDEN) ? " HIDDEN" : "",
|
||||||
|
(iconData->dwState & NIS_SHAREDICON) ? " SHARED" : "");
|
||||||
|
|
||||||
int index = FindItemByIconData(iconData, ¬ifyItem);
|
int index = FindItemByIconData(iconData, ¬ifyItem);
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
return UpdateButton(iconData);
|
TRACE("Icon %d from hWnd %08x ALREADY EXISTS!", iconData->uID, iconData->hWnd);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyItem = new NOTIFYICONDATA();
|
notifyItem = new NOTIFYICONDATA();
|
||||||
|
@ -101,6 +126,11 @@ public:
|
||||||
tbBtn.iString = (INT_PTR) text;
|
tbBtn.iString = (INT_PTR) text;
|
||||||
tbBtn.idCommand = GetButtonCount();
|
tbBtn.idCommand = GetButtonCount();
|
||||||
|
|
||||||
|
if (iconData->uFlags & NIF_STATE)
|
||||||
|
{
|
||||||
|
notifyItem->dwState = iconData->dwState & iconData->dwStateMask;
|
||||||
|
}
|
||||||
|
|
||||||
if (iconData->uFlags & NIF_MESSAGE)
|
if (iconData->uFlags & NIF_MESSAGE)
|
||||||
{
|
{
|
||||||
notifyItem->uCallbackMessage = iconData->uCallbackMessage;
|
notifyItem->uCallbackMessage = iconData->uCallbackMessage;
|
||||||
|
@ -108,8 +138,22 @@ public:
|
||||||
|
|
||||||
if (iconData->uFlags & NIF_ICON)
|
if (iconData->uFlags & NIF_ICON)
|
||||||
{
|
{
|
||||||
notifyItem->hIcon = (HICON)CopyImage(iconData->hIcon, IMAGE_ICON, 0, 0, 0);
|
notifyItem->hIcon = iconData->hIcon;
|
||||||
tbBtn.iBitmap = ImageList_AddIcon(m_ImageList, iconData->hIcon);
|
BOOL hasSharedIcon = notifyItem->dwState & NIS_SHAREDICON;
|
||||||
|
if (hasSharedIcon)
|
||||||
|
{
|
||||||
|
INT iIcon = FindExistingSharedIcon(notifyItem->hIcon);
|
||||||
|
if (iIcon < 0)
|
||||||
|
{
|
||||||
|
notifyItem->hIcon = NULL;
|
||||||
|
TRACE("Shared icon requested, but HICON not found!!!");
|
||||||
|
}
|
||||||
|
tbBtn.iBitmap = iIcon;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tbBtn.iBitmap = ImageList_AddIcon(m_ImageList, notifyItem->hIcon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iconData->uFlags & NIF_TIP)
|
if (iconData->uFlags & NIF_TIP)
|
||||||
|
@ -118,15 +162,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
m_VisibleButtonCount++;
|
m_VisibleButtonCount++;
|
||||||
if (iconData->uFlags & NIF_STATE)
|
if (notifyItem->dwState & NIS_HIDDEN)
|
||||||
{
|
{
|
||||||
notifyItem->dwState &= ~iconData->dwStateMask;
|
tbBtn.fsState |= TBSTATE_HIDDEN;
|
||||||
notifyItem->dwState |= (iconData->dwState & iconData->dwStateMask);
|
m_VisibleButtonCount--;
|
||||||
if (notifyItem->dwState & NIS_HIDDEN)
|
|
||||||
{
|
|
||||||
tbBtn.fsState |= TBSTATE_HIDDEN;
|
|
||||||
m_VisibleButtonCount--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: support NIF_INFO, NIF_GUID, NIF_REALTIME, NIF_SHOWTIP */
|
/* TODO: support NIF_INFO, NIF_GUID, NIF_REALTIME, NIF_SHOWTIP */
|
||||||
|
@ -142,34 +181,28 @@ public:
|
||||||
NOTIFYICONDATA * notifyItem;
|
NOTIFYICONDATA * notifyItem;
|
||||||
TBBUTTONINFO tbbi = { 0 };
|
TBBUTTONINFO tbbi = { 0 };
|
||||||
|
|
||||||
|
TRACE("Updating icon %d from hWnd %08x flags%s%s state%s%s",
|
||||||
|
iconData->uID, iconData->hWnd,
|
||||||
|
(iconData->uFlags & NIF_ICON) ? " ICON" : "",
|
||||||
|
(iconData->uFlags & NIF_STATE) ? " STATE" : "",
|
||||||
|
(iconData->dwState & NIS_HIDDEN) ? " HIDDEN" : "",
|
||||||
|
(iconData->dwState & NIS_SHAREDICON) ? " SHARED" : "");
|
||||||
|
|
||||||
int index = FindItemByIconData(iconData, ¬ifyItem);
|
int index = FindItemByIconData(iconData, ¬ifyItem);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
|
WARN("Icon %d from hWnd %08x DOES NOT EXIST!", iconData->uID, iconData->hWnd);
|
||||||
return AddButton(iconData);
|
return AddButton(iconData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TBBUTTON btn;
|
||||||
|
GetButton(index, &btn);
|
||||||
|
int oldIconIndex = btn.iBitmap;
|
||||||
|
|
||||||
tbbi.cbSize = sizeof(tbbi);
|
tbbi.cbSize = sizeof(tbbi);
|
||||||
tbbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND;
|
tbbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND;
|
||||||
tbbi.idCommand = index;
|
tbbi.idCommand = index;
|
||||||
|
|
||||||
if (iconData->uFlags & NIF_MESSAGE)
|
|
||||||
{
|
|
||||||
notifyItem->uCallbackMessage = iconData->uCallbackMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iconData->uFlags & NIF_ICON)
|
|
||||||
{
|
|
||||||
DestroyIcon(notifyItem->hIcon);
|
|
||||||
notifyItem->hIcon = (HICON)CopyImage(iconData->hIcon, IMAGE_ICON, 0, 0, 0);
|
|
||||||
tbbi.dwMask |= TBIF_IMAGE;
|
|
||||||
tbbi.iImage = ImageList_ReplaceIcon(m_ImageList, index, iconData->hIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iconData->uFlags & NIF_TIP)
|
|
||||||
{
|
|
||||||
StringCchCopy(notifyItem->szTip, _countof(notifyItem->szTip), iconData->szTip);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iconData->uFlags & NIF_STATE)
|
if (iconData->uFlags & NIF_STATE)
|
||||||
{
|
{
|
||||||
if (iconData->dwStateMask & NIS_HIDDEN &&
|
if (iconData->dwStateMask & NIS_HIDDEN &&
|
||||||
|
@ -192,6 +225,41 @@ public:
|
||||||
notifyItem->dwState |= (iconData->dwState & iconData->dwStateMask);
|
notifyItem->dwState |= (iconData->dwState & iconData->dwStateMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (iconData->uFlags & NIF_MESSAGE)
|
||||||
|
{
|
||||||
|
notifyItem->uCallbackMessage = iconData->uCallbackMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iconData->uFlags & NIF_ICON)
|
||||||
|
{
|
||||||
|
BOOL hasSharedIcon = notifyItem->dwState & NIS_SHAREDICON;
|
||||||
|
if (hasSharedIcon)
|
||||||
|
{
|
||||||
|
INT iIcon = FindExistingSharedIcon(iconData->hIcon);
|
||||||
|
if (iIcon >= 0)
|
||||||
|
{
|
||||||
|
notifyItem->hIcon = iconData->hIcon;
|
||||||
|
tbbi.dwMask |= TBIF_IMAGE;
|
||||||
|
tbbi.iImage = iIcon;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TRACE("Shared icon requested, but HICON not found!!! IGNORING!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
notifyItem->hIcon = iconData->hIcon;
|
||||||
|
tbbi.dwMask |= TBIF_IMAGE;
|
||||||
|
tbbi.iImage = ImageList_ReplaceIcon(m_ImageList, oldIconIndex, notifyItem->hIcon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iconData->uFlags & NIF_TIP)
|
||||||
|
{
|
||||||
|
StringCchCopy(notifyItem->szTip, _countof(notifyItem->szTip), iconData->szTip);
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO: support NIF_INFO, NIF_GUID, NIF_REALTIME, NIF_SHOWTIP */
|
/* TODO: support NIF_INFO, NIF_GUID, NIF_REALTIME, NIF_SHOWTIP */
|
||||||
|
|
||||||
SetButtonInfo(index, &tbbi);
|
SetButtonInfo(index, &tbbi);
|
||||||
|
@ -203,34 +271,48 @@ public:
|
||||||
{
|
{
|
||||||
NOTIFYICONDATA * notifyItem;
|
NOTIFYICONDATA * notifyItem;
|
||||||
|
|
||||||
|
TRACE("Removing icon %d from hWnd %08x", iconData->uID, iconData->hWnd);
|
||||||
|
|
||||||
int index = FindItemByIconData(iconData, ¬ifyItem);
|
int index = FindItemByIconData(iconData, ¬ifyItem);
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
|
{
|
||||||
|
TRACE("Icon %d from hWnd %08x ALREADY MISSING!", iconData->uID, iconData->hWnd);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(notifyItem->dwState & NIS_HIDDEN))
|
if (!(notifyItem->dwState & NIS_HIDDEN))
|
||||||
{
|
{
|
||||||
m_VisibleButtonCount--;
|
m_VisibleButtonCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
DestroyIcon(notifyItem->hIcon);
|
if (!(notifyItem->dwState & NIS_SHAREDICON))
|
||||||
|
|
||||||
delete notifyItem;
|
|
||||||
|
|
||||||
ImageList_Remove(m_ImageList, index);
|
|
||||||
|
|
||||||
int count = GetButtonCount();
|
|
||||||
|
|
||||||
/* shift all buttons one index to the left -- starting one index right
|
|
||||||
from item to delete -- to preserve their correct icon and tip */
|
|
||||||
for (int i = index; i < count - 1; i++)
|
|
||||||
{
|
{
|
||||||
notifyItem = GetItemData(i + 1);
|
TBBUTTON btn;
|
||||||
SetItemData(i, notifyItem);
|
GetButton(index, &btn);
|
||||||
UpdateButton(notifyItem);
|
int oldIconIndex = btn.iBitmap;
|
||||||
|
ImageList_Remove(m_ImageList, oldIconIndex);
|
||||||
|
|
||||||
|
// Update other icons!
|
||||||
|
int count = GetButtonCount();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
TBBUTTON btn;
|
||||||
|
GetButton(i, &btn);
|
||||||
|
|
||||||
|
if (btn.iBitmap > oldIconIndex)
|
||||||
|
{
|
||||||
|
TBBUTTONINFO tbbi2 = { 0 };
|
||||||
|
tbbi2.cbSize = sizeof(tbbi2);
|
||||||
|
tbbi2.dwMask = TBIF_BYINDEX | TBIF_IMAGE;
|
||||||
|
tbbi2.iImage = btn.iBitmap-1;
|
||||||
|
SetButtonInfo(i, &tbbi2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete the right-most, now obsolete button */
|
delete notifyItem;
|
||||||
DeleteButton(count - 1);
|
DeleteButton(index);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -269,7 +351,10 @@ public:
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
NOTIFYICONDATA * data = GetItemData(i);
|
NOTIFYICONDATA * data = GetItemData(i);
|
||||||
INT iIcon = ImageList_AddIcon(iml, data->hIcon);
|
BOOL hasSharedIcon = data->dwState & NIS_SHAREDICON;
|
||||||
|
INT iIcon = hasSharedIcon ? FindExistingSharedIcon(data->hIcon) : -1;
|
||||||
|
if (iIcon < 0)
|
||||||
|
iIcon = ImageList_AddIcon(iml, data->hIcon);
|
||||||
TBBUTTONINFO tbbi = { sizeof(tbbi), TBIF_BYINDEX | TBIF_IMAGE, 0, iIcon};
|
TBBUTTONINFO tbbi = { sizeof(tbbi), TBIF_BYINDEX | TBIF_IMAGE, 0, iIcon};
|
||||||
SetButtonInfo(i, &tbbi);
|
SetButtonInfo(i, &tbbi);
|
||||||
}
|
}
|
||||||
|
@ -304,7 +389,7 @@ private:
|
||||||
{
|
{
|
||||||
// We detect and destroy icons with invalid handles only on mouse move over systray, same as MS does.
|
// We detect and destroy icons with invalid handles only on mouse move over systray, same as MS does.
|
||||||
// Alternatively we could search for them periodically (would waste more resources).
|
// Alternatively we could search for them periodically (would waste more resources).
|
||||||
TRACE("destroying icon with invalid handle\n");
|
TRACE("Destroying icon %d with invalid handle hWnd=%08x\n", notifyItem->uID, notifyItem->hWnd);
|
||||||
|
|
||||||
HWND parentHWND = GetParent();
|
HWND parentHWND = GetParent();
|
||||||
parentHWND = ::GetParent(parentHWND);
|
parentHWND = ::GetParent(parentHWND);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue