Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / status_icons / status_tray_state_changer_win.h
blob78327f9719a829f636beb208b77b1b6004e22287
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.
26 struct NOTIFYITEM {
27 PWSTR exe_name; // The file name of the creating executable.
28 PWSTR tip; // The last hover-text value associated with this status
29 // item.
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
35 // unique.
36 GUID guid; // The GUID specified by the application, alternative to
37 // uID.
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
43 : public IUnknown {
44 public:
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 {
56 public:
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();
65 // IUnknown.
66 ULONG STDMETHODCALLTYPE AddRef() override;
67 ULONG STDMETHODCALLTYPE Release() override;
68 HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, PVOID*) override;
70 // INotificationCB.
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|
74 // is destroyed.
75 HRESULT STDMETHODCALLTYPE Notify(ULONG, NOTIFYITEM*) override;
77 protected:
78 ~StatusTrayStateChangerWin() override;
80 private:
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.
114 const UINT icon_id_;
115 // The HWND associated with the notification area icon that we want to
116 // manipulate. This is an unretained pointer, do not dereference.
117 const HWND window_;
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_