Add a minor text member to ui::MenuModel.
[chromium-blink-merge.git] / chrome / browser / ui / views / status_icons / status_tray_win.cc
bloba1f5c667b9dd933092be41f16ffc2d37b4d76cbb
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/views/status_icons/status_tray_win.h"
7 #include <commctrl.h>
9 #include "base/win/wrapped_window_proc.h"
10 #include "chrome/browser/ui/views/status_icons/status_icon_win.h"
11 #include "chrome/common/chrome_constants.h"
12 #include "ui/base/win/hwnd_util.h"
13 #include "ui/gfx/screen.h"
14 #include "win8/util/win8_util.h"
16 static const UINT kStatusIconMessage = WM_APP + 1;
18 namespace {
19 // |kBaseIconId| is 2 to avoid conflicts with plugins that hard-code id 1.
20 const UINT kBaseIconId = 2;
22 UINT ReservedIconId(StatusTray::StatusIconType type) {
23 return kBaseIconId + static_cast<UINT>(type);
25 } // namespace
27 StatusTrayWin::StatusTrayWin()
28 : next_icon_id_(1),
29 atom_(0),
30 instance_(NULL),
31 window_(NULL) {
32 // Register our window class
33 WNDCLASSEX window_class;
34 base::win::InitializeWindowClass(
35 chrome::kStatusTrayWindowClass,
36 &base::win::WrappedWindowProc<StatusTrayWin::WndProcStatic>,
37 0, 0, 0, NULL, NULL, NULL, NULL, NULL,
38 &window_class);
39 instance_ = window_class.hInstance;
40 atom_ = RegisterClassEx(&window_class);
41 CHECK(atom_);
43 // If the taskbar is re-created after we start up, we have to rebuild all of
44 // our icons.
45 taskbar_created_message_ = RegisterWindowMessage(TEXT("TaskbarCreated"));
47 // Create an offscreen window for handling messages for the status icons. We
48 // create a hidden WS_POPUP window instead of an HWND_MESSAGE window, because
49 // only top-level windows such as popups can receive broadcast messages like
50 // "TaskbarCreated".
51 window_ = CreateWindow(MAKEINTATOM(atom_),
52 0, WS_POPUP, 0, 0, 0, 0, 0, 0, instance_, 0);
53 ui::CheckWindowCreated(window_);
54 ui::SetWindowUserData(window_, this);
57 LRESULT CALLBACK StatusTrayWin::WndProcStatic(HWND hwnd,
58 UINT message,
59 WPARAM wparam,
60 LPARAM lparam) {
61 StatusTrayWin* msg_wnd = reinterpret_cast<StatusTrayWin*>(
62 GetWindowLongPtr(hwnd, GWLP_USERDATA));
63 if (msg_wnd)
64 return msg_wnd->WndProc(hwnd, message, wparam, lparam);
65 else
66 return ::DefWindowProc(hwnd, message, wparam, lparam);
69 LRESULT CALLBACK StatusTrayWin::WndProc(HWND hwnd,
70 UINT message,
71 WPARAM wparam,
72 LPARAM lparam) {
73 if (message == taskbar_created_message_) {
74 // We need to reset all of our icons because the taskbar went away.
75 for (StatusIcons::const_iterator i(status_icons().begin());
76 i != status_icons().end(); ++i) {
77 StatusIconWin* win_icon = static_cast<StatusIconWin*>(*i);
78 win_icon->ResetIcon();
80 return TRUE;
81 } else if (message == kStatusIconMessage) {
82 StatusIconWin* win_icon = NULL;
84 // Find the selected status icon.
85 for (StatusIcons::const_iterator i(status_icons().begin());
86 i != status_icons().end();
87 ++i) {
88 StatusIconWin* current_win_icon = static_cast<StatusIconWin*>(*i);
89 if (current_win_icon->icon_id() == wparam) {
90 win_icon = current_win_icon;
91 break;
95 // It is possible for this procedure to be called with an obsolete icon
96 // id. In that case we should just return early before handling any
97 // actions.
98 if (!win_icon)
99 return TRUE;
101 switch (lparam) {
102 case TB_INDETERMINATE:
103 win_icon->HandleBalloonClickEvent();
104 return TRUE;
106 case WM_LBUTTONDOWN:
107 case WM_RBUTTONDOWN:
108 case WM_CONTEXTMENU:
109 // Walk our icons, find which one was clicked on, and invoke its
110 // HandleClickEvent() method.
111 gfx::Point cursor_pos(
112 gfx::Screen::GetNativeScreen()->GetCursorScreenPoint());
113 win_icon->HandleClickEvent(cursor_pos, lparam == WM_LBUTTONDOWN);
114 return TRUE;
117 return ::DefWindowProc(hwnd, message, wparam, lparam);
120 StatusTrayWin::~StatusTrayWin() {
121 if (window_)
122 DestroyWindow(window_);
124 if (atom_)
125 UnregisterClass(MAKEINTATOM(atom_), instance_);
128 StatusIcon* StatusTrayWin::CreatePlatformStatusIcon(
129 StatusTray::StatusIconType type,
130 const gfx::ImageSkia& image,
131 const string16& tool_tip) {
132 UINT next_icon_id;
133 if (type == StatusTray::OTHER_ICON)
134 next_icon_id = NextIconId();
135 else
136 next_icon_id = ReservedIconId(type);
138 StatusIcon* icon = NULL;
139 if (win8::IsSingleWindowMetroMode())
140 icon = new StatusIconMetro(next_icon_id);
141 else
142 icon = new StatusIconWin(next_icon_id, window_, kStatusIconMessage);
144 icon->SetImage(image);
145 icon->SetToolTip(tool_tip);
146 return icon;
149 UINT StatusTrayWin::NextIconId() {
150 UINT icon_id = next_icon_id_++;
151 return kBaseIconId + static_cast<UINT>(NAMED_STATUS_ICON_COUNT) + icon_id;
154 StatusTray* StatusTray::Create() {
155 return new StatusTrayWin();