LRESULT CALLBACK NotifyIconHost::WndProc()

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);
}