• 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_icon_win.h"
6 
7 #include "base/sys_string_conversions.h"
8 #include "third_party/skia/include/core/SkBitmap.h"
9 #include "ui/gfx/icon_util.h"
10 #include "ui/gfx/point.h"
11 #include "views/controls/menu/menu_2.h"
12 
StatusIconWin(UINT id,HWND window,UINT message)13 StatusIconWin::StatusIconWin(UINT id, HWND window, UINT message)
14     : icon_id_(id),
15       window_(window),
16       message_id_(message) {
17   NOTIFYICONDATA icon_data;
18   InitIconData(&icon_data);
19   icon_data.uFlags = NIF_MESSAGE;
20   icon_data.uCallbackMessage = message_id_;
21   BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
22   // This can happen if the explorer process isn't running when we try to
23   // create the icon for some reason (for example, at startup).
24   if (!result)
25     LOG(WARNING) << "Unable to create status tray icon.";
26 }
27 
~StatusIconWin()28 StatusIconWin::~StatusIconWin() {
29   // Remove our icon.
30   NOTIFYICONDATA icon_data;
31   InitIconData(&icon_data);
32   Shell_NotifyIcon(NIM_DELETE, &icon_data);
33 }
34 
SetImage(const SkBitmap & image)35 void StatusIconWin::SetImage(const SkBitmap& image) {
36   // Create the icon.
37   NOTIFYICONDATA icon_data;
38   InitIconData(&icon_data);
39   icon_data.uFlags = NIF_ICON;
40   icon_.Set(IconUtil::CreateHICONFromSkBitmap(image));
41   icon_data.hIcon = icon_.Get();
42   BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
43   if (!result)
44     LOG(WARNING) << "Error setting status tray icon image";
45 }
46 
ResetIcon()47 void StatusIconWin::ResetIcon() {
48   NOTIFYICONDATA icon_data;
49   InitIconData(&icon_data);
50   // Delete any previously existing icon.
51   Shell_NotifyIcon(NIM_DELETE, &icon_data);
52   InitIconData(&icon_data);
53   icon_data.uFlags = NIF_MESSAGE;
54   icon_data.uCallbackMessage = message_id_;
55   icon_data.hIcon = icon_.Get();
56   // If we have an image, then set the NIF_ICON flag, which tells
57   // Shell_NotifyIcon() to set the image for the status icon it creates.
58   if (icon_data.hIcon)
59     icon_data.uFlags |= NIF_ICON;
60   // Re-add our icon.
61   BOOL result = Shell_NotifyIcon(NIM_ADD, &icon_data);
62   if (!result)
63     LOG(WARNING) << "Unable to re-create status tray icon.";
64 }
65 
SetPressedImage(const SkBitmap & image)66 void StatusIconWin::SetPressedImage(const SkBitmap& image) {
67   // Ignore pressed images, since the standard on Windows is to not highlight
68   // pressed status icons.
69 }
70 
SetToolTip(const string16 & tool_tip)71 void StatusIconWin::SetToolTip(const string16& tool_tip) {
72   // Create the icon.
73   NOTIFYICONDATA icon_data;
74   InitIconData(&icon_data);
75   icon_data.uFlags = NIF_TIP;
76   wcscpy_s(icon_data.szTip, tool_tip.c_str());
77   BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
78   if (!result)
79     LOG(WARNING) << "Unable to set tooltip for status tray icon";
80 }
81 
DisplayBalloon(const string16 & title,const string16 & contents)82 void StatusIconWin::DisplayBalloon(const string16& title,
83                                    const string16& contents) {
84   NOTIFYICONDATA icon_data;
85   InitIconData(&icon_data);
86   icon_data.uFlags = NIF_INFO;
87   icon_data.dwInfoFlags = NIIF_INFO;
88   wcscpy_s(icon_data.szInfoTitle, title.c_str());
89   wcscpy_s(icon_data.szInfo, contents.c_str());
90   icon_data.uTimeout = 0;
91   BOOL result = Shell_NotifyIcon(NIM_MODIFY, &icon_data);
92   if (!result)
93     LOG(WARNING) << "Unable to create status tray balloon.";
94 }
95 
UpdatePlatformContextMenu(ui::MenuModel * menu)96 void StatusIconWin::UpdatePlatformContextMenu(ui::MenuModel* menu) {
97   // If no items are passed, blow away our context menu.
98   if (!menu) {
99     context_menu_.reset();
100     return;
101   }
102 
103   // Create context menu with the new contents.
104   context_menu_.reset(new views::Menu2(menu));
105 }
106 
HandleClickEvent(int x,int y,bool left_mouse_click)107 void StatusIconWin::HandleClickEvent(int x, int y, bool left_mouse_click) {
108   // Pass to the observer if appropriate.
109   if (left_mouse_click && HasObservers()) {
110     DispatchClickEvent();
111     return;
112   }
113 
114   // Event not sent to the observer, so display the context menu if one exists.
115   if (context_menu_.get()) {
116     // Set our window as the foreground window, so the context menu closes when
117     // we click away from it.
118     SetForegroundWindow(window_);
119     context_menu_->RunContextMenuAt(gfx::Point(x, y));
120   }
121 }
122 
InitIconData(NOTIFYICONDATA * icon_data)123 void StatusIconWin::InitIconData(NOTIFYICONDATA* icon_data) {
124   icon_data->cbSize = sizeof(NOTIFYICONDATA);
125   icon_data->hWnd = window_;
126   icon_data->uID = icon_id_;
127 }
128