• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
StatusTrayWin()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 
WndProcStatic(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)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 
WndProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)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 
~StatusTrayWin()88 StatusTrayWin::~StatusTrayWin() {
89   if (window_)
90     DestroyWindow(window_);
91   UnregisterClass(chrome::kStatusTrayWindowClass, GetModuleHandle(NULL));
92 }
93 
CreatePlatformStatusIcon()94 StatusIcon* StatusTrayWin::CreatePlatformStatusIcon() {
95   return new StatusIconWin(next_icon_id_++, window_, kStatusIconMessage);
96 }
97 
Create()98 StatusTray* StatusTray::Create() {
99   return new StatusTrayWin();
100 }
101