1 /*
2  * Copyright 2003, 2004 Martin Fuchs
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 
19 
20  //
21  // Explorer and Desktop clone
22  //
23  // traynotify.h
24  //
25  // Martin Fuchs, 22.08.2003
26  //
27 
28 
29 #define	CLASSNAME_TRAYNOTIFY	TEXT("TrayNotifyWnd")
30 #define	TITLE_TRAYNOTIFY		TEXT("")
31 
32 #define	CLASSNAME_CLOCKWINDOW	TEXT("TrayClockWClass")
33 
34 #define	NOTIFYAREA_WIDTH_DEF	100
35 #define	NOTIFYICON_DIST			20
36 #define	NOTIFYAREA_SPACE		10
37 #define	NOTIFYICON_SIZE			16
38 #define	NOTIFYICON_X			2
39 #define	NOTIFYICON_Y			3
40 
41 #define	ICON_AUTOHIDE_SECONDS	300
42 
43 #define	PM_GETMODULEPATH_CB		(WM_APP+0x21)
44 #define	PM_GET_NOTIFYAREA		(WM_APP+0x22)
45 
46 
47  /// NotifyIconIndex is used for maintaining the order of notification icons.
48 struct NotifyIconIndex
49 {
50 	NotifyIconIndex(NOTIFYICONDATA* pnid);
51 
52 	 // sort operator
53 	friend bool operator<(const NotifyIconIndex& a, const NotifyIconIndex& b)
54 		{return a._hWnd<b._hWnd || (a._hWnd==b._hWnd && a._uID<b._uID);}
55 
56 	HWND	_hWnd;
57 	UINT	_uID;
58 
59 protected:
60 	NotifyIconIndex();
61 };
62 
63 
64 enum NOTIFYICONMODE {
65 	NIM_SHOW, NIM_HIDE, NIM_AUTO
66 };
67 
68 extern String string_from_mode(NOTIFYICONMODE mode);
69 
70  /// configuration for the display mode of a notification icon
71 struct NotifyIconConfig
72 {
NotifyIconConfigNotifyIconConfig73 	NotifyIconConfig() : _mode(NIM_AUTO) {}
74 
75 	void	create_name();
76 	bool	match(const NotifyIconConfig& props) const;
77 
78 	 // properties used to identify a notification icon
79 	String	_tipText;
80 	String	_windowTitle;	// To look at the window title and at the window module path of the notify icon owner window
81 	String	_modulePath;	// to identify notification icons is an extension above XP's behaviour.
82 							// (XP seems to store icon image data in the registry instead.)
83 	NOTIFYICONMODE _mode;
84 
85 	String	_name;			/// unique name used to identify the entry in the configuration file
86 };
87 
88  /// list of NotifyIconConfig structures
89 typedef list<NotifyIconConfig> NotifyIconCfgList;
90 
91 
92  /// structure for maintaining informations about one notification icon
93 struct NotifyInfo : public NotifyIconIndex, public NotifyIconConfig
94 {
95 	NotifyInfo();
96 
97 	 // sort operator
98 	friend bool operator<(const NotifyInfo& a, const NotifyInfo& b)
99 		{return a._idx < b._idx;}
100 
101 	bool	modify(NOTIFYICONDATA* pnid);
102 
103 	int		_idx;	// display index
104 	HICON	_hIcon;
105 	DWORD	_dwState;
106 	UINT	_uCallbackMessage;
107 	UINT	_version;
108 
109 	DWORD	_lastChange;	// timer tick value of the last change
110 };
111 
112 typedef map<NotifyIconIndex, NotifyInfo> NotifyIconMap;
113 typedef set<NotifyInfo> NotifyIconSet;
114 
115 
116 struct NotifyHook
117 {
118 	NotifyHook();
119 	~NotifyHook();
120 
121 	void	GetModulePath(HWND hwnd, HWND hwndCallback);
122 	bool	ModulePathCopyData(LPARAM lparam, HWND* phwnd, String& path);
123 
124 protected:
125 	const UINT WM_GETMODULEPATH;
126 };
127 
128 
129  /// tray notification area aka "tray"
130 struct NotifyArea : public Window
131 {
132 	typedef Window super;
133 
134 	NotifyArea(HWND hwnd);
135 	~NotifyArea();
136 
137 	static HWND Create(HWND hwndParent);
138 
139 	LRESULT	ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pnid);
140 
141 protected:
142 	WindowHandle _hwndClock;
143 	int		_clock_width;
144 
145 	ToolTip	_tooltip;
146 	NotifyHook _hook;
147 
148 	bool	_show_hidden;
149 	bool	_hide_inactive;
150 	bool	_show_button;
151 
152 	LRESULT Init(LPCREATESTRUCT pcs);
153 	LRESULT	WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
154 	int		Command(int id, int code);
155 	int		Notify(int id, NMHDR* pnmh);
156 
157 	void	UpdateIcons();
158 	void	Paint();
159 	void	Refresh(bool do_refresh=false);
160 	void	CancelModes();
161 
162 	NotifyIconSet::iterator IconHitTest(const POINT& pos);
163 	bool	DetermineHideState(NotifyInfo& entry);
164 
165 	void	read_config();
166 	void	write_config();
167 
168 	friend struct TrayNotifyDlg;
169 
170 	NotifyIconCfgList _cfg;
171 
172 	map<HWND, String> _window_modules;
173 
174 	NotifyIconMap _icon_map;
175 	NotifyIconSet _sorted_icons;
176 	int		_next_idx;
177 	size_t	_last_icon_count;
178 
179 	void	show_clock(bool flag);
180 };
181 
182 
183 struct NotifyIconDlgInfo : public NotifyIconConfig
184 {
185 	typedef NotifyIconConfig super;
186 
NotifyIconDlgInfoNotifyIconDlgInfo187 	NotifyIconDlgInfo(const NotifyInfo& info) : super(info), _lastChange(info._lastChange) {}
NotifyIconDlgInfoNotifyIconDlgInfo188 	NotifyIconDlgInfo(const NotifyIconConfig& cfg) : super(cfg), _lastChange(0) {}
NotifyIconDlgInfoNotifyIconDlgInfo189 	NotifyIconDlgInfo() : _lastChange(0) {}
190 
191 	DWORD	_lastChange;
192 };
193 
194 typedef map<int, NotifyIconDlgInfo> NotifyIconDlgInfoMap;
195 
196 
197  /// configuration dialog for notification icons
198 struct TrayNotifyDlg : public ResizeController<Dialog>
199 {
200 	typedef ResizeController<Dialog> super;
201 
202 	TrayNotifyDlg(HWND hwnd);
203 	~TrayNotifyDlg();
204 
205 protected:
206 	HWND	_tree_ctrl;
207 	HACCEL	_haccel;
208 	HIMAGELIST	_himl;
209 	NotifyArea* _pNotifyArea;
210 	NotifyIconDlgInfoMap _info;
211 
212 	typedef pair<NOTIFYICONMODE, DWORD> IconStatePair;
213 	typedef map<NotifyIconIndex, IconStatePair> IconStateMap;
214 
215 	NotifyIconCfgList _cfg_org;
216 	IconStateMap _icon_states_org;
217 	bool	_show_hidden_org;
218 
219 	HTREEITEM _hitemCurrent;
220 	HTREEITEM _hitemCurrent_visible;
221 	HTREEITEM _hitemCurrent_hidden;
222 	HTREEITEM _hitemConfig;
223 	HTREEITEM _selectedItem;
224 
225 	virtual LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
226 	virtual int	Command(int id, int code);
227 	virtual int	Notify(int id, NMHDR* pnmh);
228 
229 	void	Refresh();
230 	void	InsertItem(HTREEITEM hparent, HTREEITEM after, const NotifyInfo&, HDC);
231 	void	InsertItem(HTREEITEM hparent, HTREEITEM after, const NotifyIconDlgInfo&, HDC, HICON, NOTIFYICONMODE);
232 	void	SetIconMode(NOTIFYICONMODE mode);
233 	void	RefreshProperties(const NotifyIconDlgInfo& entry);
234 };
235 
236 
237  /// window for displaying the time in the tray notification area
238 struct ClockWindow : public Window
239 {
240 	typedef Window super;
241 
242 	ClockWindow(HWND hwnd);
243 
244 	static HWND Create(HWND hwndParent);
245 
246 	void	TimerTick();
247 
248 protected:
249 	LRESULT	WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
250 	int		Notify(int id, NMHDR* pnmh);
251 
252 	bool	FormatTime();
253 	void	Paint();
254 
255 	TCHAR	_time[16];
256 	ToolTip	_tooltip;
257 };
258