in shell/browser/ui/win/notify_icon_host.cc [134:215]
LRESULT CALLBACK NotifyIconHost::WndProc(HWND hwnd,
UINT message,
WPARAM wparam,
LPARAM lparam) {
if (message == taskbar_created_message_) {
// We need to reset all of our icons because the taskbar went away.
for (NotifyIcons::const_iterator i(notify_icons_.begin());
i != notify_icons_.end(); ++i) {
auto* win_icon = static_cast<NotifyIcon*>(*i);
win_icon->ResetIcon();
}
return TRUE;
} else if (message == kNotifyIconMessage) {
NotifyIcon* win_icon = NULL;
// Find the selected status icon.
for (NotifyIcons::const_iterator i(notify_icons_.begin());
i != notify_icons_.end(); ++i) {
auto* current_win_icon = static_cast<NotifyIcon*>(*i);
if (current_win_icon->icon_id() == wparam) {
win_icon = current_win_icon;
break;
}
}
// It is possible for this procedure to be called with an obsolete icon
// id. In that case we should just return early before handling any
// actions.
if (!win_icon)
return TRUE;
// We use a WeakPtr factory for NotifyIcons here so
// that the callback is aware if the NotifyIcon gets
// garbage-collected. This occurs when the tray gets
// GC'd, and the BALLOON events below will not emit.
base::WeakPtr<NotifyIcon> win_icon_weak = win_icon->GetWeakPtr();
switch (lparam) {
case NIN_BALLOONSHOW:
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(&NotifyIcon::NotifyBalloonShow, win_icon_weak));
return TRUE;
case NIN_BALLOONUSERCLICK:
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(&NotifyIcon::NotifyBalloonClicked, win_icon_weak));
return TRUE;
case NIN_BALLOONTIMEOUT:
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(&NotifyIcon::NotifyBalloonClosed, win_icon_weak));
return TRUE;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
case WM_CONTEXTMENU:
// Walk our icons, find which one was clicked on, and invoke its
// HandleClickEvent() method.
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE,
base::BindOnce(
&NotifyIcon::HandleClickEvent, win_icon_weak,
GetKeyboardModifiers(),
(lparam == WM_LBUTTONDOWN || lparam == WM_LBUTTONDBLCLK),
(lparam == WM_LBUTTONDBLCLK || lparam == WM_RBUTTONDBLCLK)));
return TRUE;
case WM_MOUSEMOVE:
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(&NotifyIcon::HandleMouseMoveEvent,
win_icon_weak, GetKeyboardModifiers()));
return TRUE;
}
}
return ::DefWindowProc(hwnd, message, wparam, lparam);
}