OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/status_icons/status_icon_win.h" | 5 #include "chrome/browser/ui/views/status_icons/status_icon_win.h" |
6 | 6 |
7 #include "base/sys_string_conversions.h" | 7 #include "base/sys_string_conversions.h" |
| 8 #include "base/win/windows_version.h" |
8 #include "third_party/skia/include/core/SkBitmap.h" | 9 #include "third_party/skia/include/core/SkBitmap.h" |
9 #include "ui/gfx/icon_util.h" | 10 #include "ui/gfx/icon_util.h" |
10 #include "ui/gfx/point.h" | 11 #include "ui/gfx/point.h" |
11 #if !defined(USE_AURA) | 12 #if !defined(USE_AURA) |
12 #include "views/controls/menu/menu_2.h" | 13 #include "views/controls/menu/menu_2.h" |
13 #endif | 14 #endif |
14 | 15 |
15 StatusIconWin::StatusIconWin(UINT id, HWND window, UINT message) | 16 StatusIconWin::StatusIconWin(UINT id, HWND window, UINT message) |
16 : icon_id_(id), | 17 : icon_id_(id), |
17 window_(window), | 18 window_(window), |
18 message_id_(message) { | 19 message_id_(message) { |
19 NOTIFYICONDATA icon_data; | 20 NOTIFYICONDATA icon_data; |
20 InitIconData(&icon_data); | 21 InitIconData(&icon_data); |
21 icon_data.uFlags = NIF_MESSAGE; | 22 icon_data.uFlags = NIF_MESSAGE; |
22 icon_data.uCallbackMessage = message_id_; | 23 icon_data.uCallbackMessage = message_id_; |
23 BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data); | 24 BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data); |
24 // This can happen if the explorer process isn't running when we try to | 25 // This can happen if the explorer process isn't running when we try to |
25 // create the icon for some reason (for example, at startup). | 26 // create the icon for some reason (for example, at startup). |
26 if (!result) | 27 if (!result) |
27 LOG(WARNING) << "Unable to create status tray icon."; | 28 LOG(WARNING) << "Unable to create status tray icon."; |
28 } | 29 } |
29 | 30 |
30 StatusIconWin::~StatusIconWin() { | 31 StatusIconWin::~StatusIconWin() { |
| 32 // Force to hide the balloon if any. Otherwise it might keep the icon in |
| 33 // the tray until the balloon goes away. |
| 34 HideBalloon(); |
| 35 |
31 // Remove our icon. | 36 // Remove our icon. |
32 NOTIFYICONDATA icon_data; | 37 NOTIFYICONDATA icon_data; |
33 InitIconData(&icon_data); | 38 InitIconData(&icon_data); |
34 Shell_NotifyIcon(NIM_DELETE, &icon_data); | 39 Shell_NotifyIcon(NIM_DELETE, &icon_data); |
35 } | 40 } |
36 | 41 |
37 void StatusIconWin::SetImage(const SkBitmap& image) { | 42 void StatusIconWin::SetImage(const SkBitmap& image) { |
38 // Create the icon. | 43 // Create the icon. |
39 NOTIFYICONDATA icon_data; | 44 NOTIFYICONDATA icon_data; |
40 InitIconData(&icon_data); | 45 InitIconData(&icon_data); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 icon_data.uFlags = NIF_TIP; | 82 icon_data.uFlags = NIF_TIP; |
78 wcscpy_s(icon_data.szTip, tool_tip.c_str()); | 83 wcscpy_s(icon_data.szTip, tool_tip.c_str()); |
79 BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); | 84 BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); |
80 if (!result) | 85 if (!result) |
81 LOG(WARNING) << "Unable to set tooltip for status tray icon"; | 86 LOG(WARNING) << "Unable to set tooltip for status tray icon"; |
82 } | 87 } |
83 | 88 |
84 void StatusIconWin::DisplayBalloon(const SkBitmap& icon, | 89 void StatusIconWin::DisplayBalloon(const SkBitmap& icon, |
85 const string16& title, | 90 const string16& title, |
86 const string16& contents) { | 91 const string16& contents) { |
87 // TODO(leandrogracia): implement custom icons for notification balloons. | |
88 | |
89 NOTIFYICONDATA icon_data; | 92 NOTIFYICONDATA icon_data; |
90 InitIconData(&icon_data); | 93 InitIconData(&icon_data); |
91 icon_data.uFlags = NIF_INFO; | 94 icon_data.uFlags = NIF_INFO; |
92 icon_data.dwInfoFlags = NIIF_INFO; | 95 icon_data.dwInfoFlags = NIIF_INFO; |
93 wcscpy_s(icon_data.szInfoTitle, title.c_str()); | 96 wcscpy_s(icon_data.szInfoTitle, title.c_str()); |
94 wcscpy_s(icon_data.szInfo, contents.c_str()); | 97 wcscpy_s(icon_data.szInfo, contents.c_str()); |
95 icon_data.uTimeout = 0; | 98 icon_data.uTimeout = 0; |
| 99 |
| 100 base::win::Version win_version = base::win::OSInfo::GetInstance()->version(); |
| 101 if (!icon.empty() && win_version != base::win::VERSION_PRE_XP) { |
| 102 balloon_icon_.Set(IconUtil::CreateHICONFromSkBitmap(icon)); |
| 103 if (win_version >= base::win::VERSION_VISTA) { |
| 104 icon_data.hBalloonIcon = balloon_icon_.Get(); |
| 105 icon_data.dwInfoFlags = NIIF_USER | NIIF_LARGE_ICON; |
| 106 } else { |
| 107 icon_data.hIcon = balloon_icon_.Get(); |
| 108 icon_data.uFlags |= NIF_ICON; |
| 109 icon_data.dwInfoFlags = NIIF_USER; |
| 110 } |
| 111 } |
| 112 |
96 BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); | 113 BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); |
97 if (!result) | 114 if (!result) |
98 LOG(WARNING) << "Unable to create status tray balloon."; | 115 LOG(WARNING) << "Unable to create status tray balloon."; |
99 } | 116 } |
100 | 117 |
| 118 void StatusIconWin::HideBalloon() { |
| 119 NOTIFYICONDATA icon_data; |
| 120 InitIconData(&icon_data); |
| 121 icon_data.szInfo[0] = '\0'; |
| 122 BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data); |
| 123 if (!result) |
| 124 LOG(WARNING) << "Unable to hide status tray balloon."; |
| 125 } |
| 126 |
101 void StatusIconWin::UpdatePlatformContextMenu(ui::MenuModel* menu) { | 127 void StatusIconWin::UpdatePlatformContextMenu(ui::MenuModel* menu) { |
102 #if defined(USE_AURA) | 128 #if defined(USE_AURA) |
103 // crbug.com/99489. | 129 // crbug.com/99489. |
104 NOTIMPLEMENTED(); | 130 NOTIMPLEMENTED(); |
105 #else | 131 #else |
106 // If no items are passed, blow away our context menu. | 132 // If no items are passed, blow away our context menu. |
107 if (!menu) { | 133 if (!menu) { |
108 context_menu_.reset(); | 134 context_menu_.reset(); |
109 return; | 135 return; |
110 } | 136 } |
(...skipping 16 matching lines...) Expand all Loading... |
127 if (context_menu_.get()) { | 153 if (context_menu_.get()) { |
128 // Set our window as the foreground window, so the context menu closes when | 154 // Set our window as the foreground window, so the context menu closes when |
129 // we click away from it. | 155 // we click away from it. |
130 SetForegroundWindow(window_); | 156 SetForegroundWindow(window_); |
131 context_menu_->RunContextMenuAt(gfx::Point(x, y)); | 157 context_menu_->RunContextMenuAt(gfx::Point(x, y)); |
132 } | 158 } |
133 #endif | 159 #endif |
134 } | 160 } |
135 | 161 |
136 void StatusIconWin::InitIconData(NOTIFYICONDATA* icon_data) { | 162 void StatusIconWin::InitIconData(NOTIFYICONDATA* icon_data) { |
137 icon_data->cbSize = sizeof(NOTIFYICONDATA); | 163 if (base::win::OSInfo::GetInstance()->version() >= base::win::VERSION_VISTA) |
| 164 icon_data->cbSize = sizeof(NOTIFYICONDATA); |
| 165 else |
| 166 icon_data->cbSize = NOTIFYICONDATA_V3_SIZE; |
| 167 |
138 icon_data->hWnd = window_; | 168 icon_data->hWnd = window_; |
139 icon_data->uID = icon_id_; | 169 icon_data->uID = icon_id_; |
140 } | 170 } |
OLD | NEW |