Home | History | Annotate | Download | only in status_icons
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/views/status_icons/status_tray_win.h"
      6 
      7 #include "base/win/wrapped_window_proc.h"
      8 #include "chrome/browser/ui/views/status_icons/status_icon_win.h"
      9 #include "chrome/common/chrome_constants.h"
     10 #include "ui/base/win/hwnd_util.h"
     11 
     12 static const UINT kStatusIconMessage = WM_APP + 1;
     13 
     14 StatusTrayWin::StatusTrayWin()
     15     : next_icon_id_(1) {
     16   // Register our window class
     17   HINSTANCE hinst = GetModuleHandle(NULL);
     18   WNDCLASSEX wc = {0};
     19   wc.cbSize = sizeof(wc);
     20   wc.lpfnWndProc = base::win::WrappedWindowProc<StatusTrayWin::WndProcStatic>;
     21   wc.hInstance = hinst;
     22   wc.lpszClassName = chrome::kStatusTrayWindowClass;
     23   ATOM clazz = RegisterClassEx(&wc);
     24   DCHECK(clazz);
     25 
     26   // If the taskbar is re-created after we start up, we have to rebuild all of
     27   // our icons.
     28   taskbar_created_message_ = RegisterWindowMessage(TEXT("TaskbarCreated"));
     29 
     30   // Create an offscreen window for handling messages for the status icons. We
     31   // create a hidden WS_POPUP window instead of an HWND_MESSAGE window, because
     32   // only top-level windows such as popups can receive broadcast messages like
     33   // "TaskbarCreated".
     34   window_ = CreateWindow(chrome::kStatusTrayWindowClass,
     35                          0, WS_POPUP, 0, 0, 0, 0, 0, 0, hinst, 0);
     36   ui::CheckWindowCreated(window_);
     37   ui::SetWindowUserData(window_, this);
     38 }
     39 
     40 LRESULT CALLBACK StatusTrayWin::WndProcStatic(HWND hwnd,
     41                                               UINT message,
     42                                               WPARAM wparam,
     43                                               LPARAM lparam) {
     44   StatusTrayWin* msg_wnd = reinterpret_cast<StatusTrayWin*>(
     45       GetWindowLongPtr(hwnd, GWLP_USERDATA));
     46   if (msg_wnd)
     47     return msg_wnd->WndProc(hwnd, message, wparam, lparam);
     48   else
     49     return ::DefWindowProc(hwnd, message, wparam, lparam);
     50 }
     51 
     52 LRESULT CALLBACK StatusTrayWin::WndProc(HWND hwnd,
     53                                         UINT message,
     54                                         WPARAM wparam,
     55                                         LPARAM lparam) {
     56   if (message == taskbar_created_message_) {
     57     // We need to reset all of our icons because the taskbar went away.
     58     for (StatusIconList::const_iterator iter = status_icons().begin();
     59          iter != status_icons().end();
     60          ++iter) {
     61       StatusIconWin* win_icon = static_cast<StatusIconWin*>(*iter);
     62       win_icon->ResetIcon();
     63     }
     64     return TRUE;
     65   } else if (message == kStatusIconMessage) {
     66     switch (lparam) {
     67       case WM_LBUTTONDOWN:
     68       case WM_RBUTTONDOWN:
     69       case WM_CONTEXTMENU:
     70         // Walk our icons, find which one was clicked on, and invoke its
     71         // HandleClickEvent() method.
     72         for (StatusIconList::const_iterator iter = status_icons().begin();
     73              iter != status_icons().end();
     74              ++iter) {
     75           StatusIconWin* win_icon = static_cast<StatusIconWin*>(*iter);
     76           if (win_icon->icon_id() == wparam) {
     77             POINT p;
     78             GetCursorPos(&p);
     79             win_icon->HandleClickEvent(p.x, p.y, lparam == WM_LBUTTONDOWN);
     80           }
     81         }
     82         return TRUE;
     83     }
     84   }
     85   return ::DefWindowProc(hwnd, message, wparam, lparam);
     86 }
     87 
     88 StatusTrayWin::~StatusTrayWin() {
     89   if (window_)
     90     DestroyWindow(window_);
     91   UnregisterClass(chrome::kStatusTrayWindowClass, GetModuleHandle(NULL));
     92 }
     93 
     94 StatusIcon* StatusTrayWin::CreatePlatformStatusIcon() {
     95   return new StatusIconWin(next_icon_id_++, window_, kStatusIconMessage);
     96 }
     97 
     98 StatusTray* StatusTray::Create() {
     99   return new StatusTrayWin();
    100 }
    101