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"
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;
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
);
27 StatusTrayWin::StatusTrayWin()
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
,
39 instance_
= window_class
.hInstance
;
40 atom_
= RegisterClassEx(&window_class
);
43 // If the taskbar is re-created after we start up, we have to rebuild all of
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
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
,
61 StatusTrayWin
* msg_wnd
= reinterpret_cast<StatusTrayWin
*>(
62 GetWindowLongPtr(hwnd
, GWLP_USERDATA
));
64 return msg_wnd
->WndProc(hwnd
, message
, wparam
, lparam
);
66 return ::DefWindowProc(hwnd
, message
, wparam
, lparam
);
69 LRESULT CALLBACK
StatusTrayWin::WndProc(HWND hwnd
,
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();
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();
88 StatusIconWin
* current_win_icon
= static_cast<StatusIconWin
*>(*i
);
89 if (current_win_icon
->icon_id() == wparam
) {
90 win_icon
= current_win_icon
;
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
102 case TB_INDETERMINATE
:
103 win_icon
->HandleBalloonClickEvent();
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
);
117 return ::DefWindowProc(hwnd
, message
, wparam
, lparam
);
120 StatusTrayWin::~StatusTrayWin() {
122 DestroyWindow(window_
);
125 UnregisterClass(MAKEINTATOM(atom_
), instance_
);
128 StatusIcon
* StatusTrayWin::CreatePlatformStatusIcon(
129 StatusTray::StatusIconType type
,
130 const gfx::ImageSkia
& image
,
131 const string16
& tool_tip
) {
133 if (type
== StatusTray::OTHER_ICON
)
134 next_icon_id
= NextIconId();
136 next_icon_id
= ReservedIconId(type
);
138 StatusIcon
* icon
= NULL
;
139 if (win8::IsSingleWindowMetroMode())
140 icon
= new StatusIconMetro(next_icon_id
);
142 icon
= new StatusIconWin(next_icon_id
, window_
, kStatusIconMessage
);
144 icon
->SetImage(image
);
145 icon
->SetToolTip(tool_tip
);
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();