1 // Copyright 2014 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 #ifndef CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_TRAY_STATE_CHANGER_WIN_H_
6 #define CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_TRAY_STATE_CHANGER_WIN_H_
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string16.h"
10 #include "base/threading/non_thread_safe.h"
11 #include "base/win/iunknown_impl.h"
12 #include "base/win/scoped_comptr.h"
14 // The known values for NOTIFYITEM's dwPreference member.
15 enum NOTIFYITEM_PREFERENCE
{
16 // In Windows UI: "Only show notifications."
17 PREFERENCE_SHOW_WHEN_ACTIVE
= 0,
18 // In Windows UI: "Hide icon and notifications."
19 PREFERENCE_SHOW_NEVER
= 1,
20 // In Windows UI: "Show icon and notifications."
21 PREFERENCE_SHOW_ALWAYS
= 2
24 // NOTIFYITEM describes an entry in Explorer's registry of status icons.
25 // Explorer keeps entries around for a process even after it exits.
27 PWSTR exe_name
; // The file name of the creating executable.
28 PWSTR tip
; // The last hover-text value associated with this status
30 HICON icon
; // The icon associated with this status item.
31 HWND hwnd
; // The HWND associated with the status item.
32 DWORD preference
; // Determines the behavior of the icon with respect to
33 // the taskbar. Values taken from NOTIFYITEM_PREFERENCE.
34 UINT id
; // The ID specified by the application. (hWnd, uID) is
36 GUID guid
; // The GUID specified by the application, alternative to
40 // INotificationCB is an interface that applications can implement in order to
41 // receive notifications about the state of the notification area manager.
42 class __declspec(uuid("D782CCBA-AFB0-43F1-94DB-FDA3779EACCB")) INotificationCB
45 virtual HRESULT STDMETHODCALLTYPE
46 Notify(ULONG event
, NOTIFYITEM
* notify_item
) = 0;
49 // A class that is capable of reading and writing the state of the notification
50 // area in the Windows taskbar. It is used to promote a tray icon from the
51 // overflow area to the taskbar, and refuses to do anything if the user has
52 // explicitly marked an icon to be always hidden.
53 class StatusTrayStateChangerWin
: public INotificationCB
,
54 public base::win::IUnknownImpl
,
55 public base::NonThreadSafe
{
57 StatusTrayStateChangerWin(UINT icon_id
, HWND window
);
59 // Call this method to move the icon matching |icon_id| and |window| to the
60 // taskbar from the overflow area. This will not make any changes if the
61 // icon has been set to |PREFERENCE_SHOW_NEVER|, in order to comply with
62 // the explicit wishes/configuration of the user.
63 void EnsureTrayIconVisible();
66 ULONG STDMETHODCALLTYPE
AddRef() override
;
67 ULONG STDMETHODCALLTYPE
Release() override
;
68 HRESULT STDMETHODCALLTYPE
QueryInterface(REFIID
, PVOID
*) override
;
71 // Notify is called in response to RegisterCallback for each current
72 // entry in Explorer's list of notification area icons, and ever time
73 // one of them changes, until UnregisterCallback is called or |this|
75 HRESULT STDMETHODCALLTYPE
Notify(ULONG
, NOTIFYITEM
*) override
;
78 ~StatusTrayStateChangerWin() override
;
81 friend class StatusTrayStateChangerWinTest
;
83 enum InterfaceVersion
{
84 INTERFACE_VERSION_LEGACY
= 0,
85 INTERFACE_VERSION_WIN8
,
86 INTERFACE_VERSION_UNKNOWN
89 // Creates an instance of TrayNotify, and ensures that it supports either
90 // ITrayNotify or ITrayNotifyWin8. Returns true on success.
91 bool CreateTrayNotify();
93 // Returns the NOTIFYITEM that corresponds to this executable and the
94 // HWND/ID pair that were used to create the StatusTrayStateChangerWin.
95 // Internally it calls the appropriate RegisterCallback{Win8,Legacy}.
96 scoped_ptr
<NOTIFYITEM
> RegisterCallback();
98 // Calls RegisterCallback with the appropriate interface required by
99 // different versions of Windows. This will result in |notify_item_| being
100 // updated when a matching item is passed into
101 // StatusTrayStateChangerWin::Notify.
102 bool RegisterCallbackWin8();
103 bool RegisterCallbackLegacy();
105 // Sends an update to Explorer with the passed NOTIFYITEM.
106 void SendNotifyItemUpdate(scoped_ptr
<NOTIFYITEM
> notify_item
);
108 // Storing IUnknown since we will need to use different interfaces
109 // for different versions of Windows.
110 base::win::ScopedComPtr
<IUnknown
> tray_notify_
;
111 InterfaceVersion interface_version_
;
113 // The ID assigned to the notification area icon that we want to manipulate.
115 // The HWND associated with the notification area icon that we want to
116 // manipulate. This is an unretained pointer, do not dereference.
118 // Executable name of the current program. Along with |icon_id_| and
119 // |window_|, this uniquely identifies a notification area entry to Explorer.
120 base::string16 file_name_
;
122 // Temporary storage for the matched NOTIFYITEM. This is necessary because
123 // Notify doesn't return anything. The call flow looks like this:
124 // TrayNotify->RegisterCallback()
125 // ... other COM stack frames ..
126 // StatusTrayStateChangerWin->Notify(NOTIFYITEM);
127 // so we can't just return the notifyitem we're looking for.
128 scoped_ptr
<NOTIFYITEM
> notify_item_
;
130 DISALLOW_COPY_AND_ASSIGN(StatusTrayStateChangerWin
);
133 #endif // CHROME_BROWSER_UI_VIEWS_STATUS_ICONS_STATUS_TRAY_STATE_CHANGER_WIN_H_