ReactOS  0.4.15-dev-1206-g731eddf
appbar.cpp
Go to the documentation of this file.
1 /*
2  * SHAppBarMessage implementation
3  *
4  * Copyright 2008 Vincent Povirk for CodeWeavers
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * TODO: freedesktop _NET_WM_STRUT integration
21  *
22  * TODO: find when a fullscreen app is in the foreground and send FULLSCREENAPP
23  * notifications
24  *
25  * TODO: detect changes in the screen size and send ABN_POSCHANGED ?
26  *
27  * TODO: multiple monitor support
28  */
29 
30 //
31 // Adapted from Wine appbar.c .
32 //
33 
34 #include "precomp.h"
35 
36 #include <wine/list.h>
37 
38 struct appbar_cmd
39 {
43  struct _AppBarData abd;
44 };
45 
47 {
49  struct _AppBarData abd;
50 };
51 
53 {
54  struct list entry;
60  /* BOOL autohide; */
61 };
62 
63 static struct list appbars = LIST_INIT(appbars);
64 
66 {
67  struct appbar_data* data;
68 
70  {
71  if (data->hwnd == hwnd)
72  return data;
73  }
74 
75  return NULL;
76 }
77 
78 void appbar_notify_all(HMONITOR hMon, UINT uMsg, HWND hwndExclude, LPARAM lParam)
79 {
80  struct appbar_data* data;
81 
83  {
84  if (data->hwnd == hwndExclude)
85  continue;
86 
87  if (hMon && hMon != MonitorFromWindow(data->hwnd, MONITOR_DEFAULTTONULL))
88  continue;
89 
90  SendMessageW(data->hwnd, data->callback_msg, uMsg, lParam);
91  }
92 }
93 
94 /* send_poschanged: send ABN_POSCHANGED to every appbar except one */
96 {
98 }
99 
100 /* appbar_cliprect: cut out parts of the rectangle that interfere with existing appbars */
102 {
103  struct appbar_data* data;
105  {
106  if (data->hwnd == hwnd)
107  {
108  /* we only care about appbars that were added before this one */
109  return;
110  }
111  if (data->space_reserved)
112  {
113  /* move in the side that corresponds to the other appbar's edge */
114  switch (data->edge)
115  {
116  case ABE_BOTTOM:
117  rect->bottom = min(rect->bottom, data->rc.top);
118  break;
119  case ABE_LEFT:
120  rect->left = max(rect->left, data->rc.right);
121  break;
122  case ABE_RIGHT:
123  rect->right = min(rect->right, data->rc.left);
124  break;
125  case ABE_TOP:
126  rect->top = max(rect->top, data->rc.bottom);
127  break;
128  }
129  }
130  }
131 }
132 
134 {
135  struct appbar_data* data;
136  HWND hwnd = abd->hWnd;
137 
138  switch (msg)
139  {
140  case ABM_NEW:
141  if (get_appbar(hwnd))
142  {
143  /* fail when adding an hwnd the second time */
144  return FALSE;
145  }
146 
147  data = (struct appbar_data*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct appbar_data));
148  if (!data)
149  {
150  ERR("out of memory\n");
151  return FALSE;
152  }
153  data->hwnd = hwnd;
154  data->callback_msg = abd->uCallbackMessage;
155 
156  list_add_tail(&appbars, &data->entry);
157 
158  return TRUE;
159  case ABM_REMOVE:
160  if ((data = get_appbar(hwnd)))
161  {
162  list_remove(&data->entry);
163 
165 
167  }
168  else
169  WARN("removing hwnd %p not on the list\n", hwnd);
170  return TRUE;
171  case ABM_QUERYPOS:
172  if (abd->uEdge > ABE_BOTTOM)
173  WARN("invalid edge %i for %p\n", abd->uEdge, hwnd);
174  appbar_cliprect( hwnd, &abd->rc );
175  return TRUE;
176  case ABM_SETPOS:
177  if (abd->uEdge > ABE_BOTTOM)
178  {
179  WARN("invalid edge %i for %p\n", abd->uEdge, hwnd);
180  return TRUE;
181  }
182  if ((data = get_appbar(hwnd)))
183  {
184  /* calculate acceptable space */
185  appbar_cliprect( hwnd, &abd->rc );
186 
187  if (!EqualRect(&abd->rc, &data->rc))
189 
190  /* reserve that space for this appbar */
191  data->edge = abd->uEdge;
192  data->rc = abd->rc;
193  data->space_reserved = TRUE;
194  }
195  else
196  {
197  WARN("app sent ABM_SETPOS message for %p without ABM_ADD\n", hwnd);
198  }
199  return TRUE;
200  case ABM_GETSTATE:
201  FIXME("SHAppBarMessage(ABM_GETSTATE): stub\n");
202  return ABS_ALWAYSONTOP | ABS_AUTOHIDE;
203  case ABM_GETTASKBARPOS:
204  FIXME("SHAppBarMessage(ABM_GETTASKBARPOS, hwnd=%p): stub\n", hwnd);
205  /* Report the taskbar is at the bottom of the screen. */
206  abd->rc.left = 0;
209  abd->rc.top = abd->rc.bottom-1;
210  abd->uEdge = ABE_BOTTOM;
211  return TRUE;
212  case ABM_ACTIVATE:
213  return TRUE;
214  case ABM_GETAUTOHIDEBAR:
215  FIXME("SHAppBarMessage(ABM_GETAUTOHIDEBAR, hwnd=%p, edge=%x): stub\n", hwnd, abd->uEdge);
216  return 0;
217  case ABM_SETAUTOHIDEBAR:
218  FIXME("SHAppBarMessage(ABM_SETAUTOHIDEBAR, hwnd=%p, edge=%x, lparam=%s): stub\n",
219  hwnd, abd->uEdge, wine_dbgstr_longlong(abd->lParam));
220  return TRUE;
222  return TRUE;
223  default:
224  FIXME("SHAppBarMessage(%x) unimplemented\n", msg);
225  return FALSE;
226  }
227 }
228 
230 {
231  struct appbar_cmd cmd;
233  HANDLE return_hproc;
235  LPVOID return_view;
236  struct appbar_response* response;
237 
238  if (cds->cbData != sizeof(struct appbar_cmd))
239  return TRUE;
240 
241  RtlCopyMemory(&cmd, cds->lpData, cds->cbData);
242 
243  result = handle_appbarmessage(cmd.dwMsg, &cmd.abd);
244 
245  return_hproc = OpenProcess(PROCESS_DUP_HANDLE, FALSE, cmd.return_process);
246  if (return_hproc == NULL)
247  {
248  ERR("couldn't open calling process\n");
249  return TRUE;
250  }
251 
252  if (!DuplicateHandle(return_hproc, UlongToHandle(cmd.return_map), GetCurrentProcess(), &return_map, 0, FALSE, DUPLICATE_SAME_ACCESS))
253  {
254  ERR("couldn't duplicate handle\n");
255  CloseHandle(return_hproc);
256  return TRUE;
257  }
258  CloseHandle(return_hproc);
259 
260  return_view = MapViewOfFile(return_map, FILE_MAP_WRITE, 0, 0, sizeof(struct appbar_response));
261 
262  if (return_view)
263  {
264  response = (struct appbar_response*)return_view;
265  response->result = result;
266  response->abd = cmd.abd;
267 
268  UnmapViewOfFile(return_view);
269  }
270  else
271  {
272  ERR("couldn't map view of file\n");
273  }
274 
275  CloseHandle(return_map);
276  return TRUE;
277 }
#define ABM_GETAUTOHIDEBAR
Definition: shellapi.h:66
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define ABE_TOP
Definition: shellapi.h:18
#define max(a, b)
Definition: svc.c:63
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define CloseHandle
Definition: compat.h:598
#define ABS_AUTOHIDE
Definition: shellapi.h:21
#define MapViewOfFile
Definition: compat.h:604
struct _AppBarData abd
Definition: appbar.cpp:43
Definition: ftp_var.h:139
#define TRUE
Definition: types.h:120
#define WARN(fmt,...)
Definition: debug.h:112
LONG top
Definition: windef.h:307
void appbar_notify_all(HMONITOR hMon, UINT uMsg, HWND hwndExclude, LPARAM lParam)
Definition: appbar.cpp:78
UINT uCallbackMessage
Definition: shellapi.h:217
#define ABM_GETTASKBARPOS
Definition: shellapi.h:64
HWND hWnd
Definition: shellapi.h:216
static void appbar_cliprect(HWND hwnd, RECT *rect)
Definition: appbar.cpp:101
LONG left
Definition: windef.h:306
LONG right
Definition: windef.h:308
#define ABE_LEFT
Definition: shellapi.h:17
& rect
Definition: startmenu.cpp:1413
LPARAM lParam
Definition: shellapi.h:220
DWORD dwMsg
Definition: appbar.cpp:40
#define ABM_ACTIVATE
Definition: shellapi.h:65
static struct appbar_data * get_appbar(HWND hwnd)
Definition: appbar.cpp:65
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
HWND hwnd
Definition: appbar.cpp:55
BOOL space_reserved
Definition: appbar.cpp:59
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define SM_CXSCREEN
Definition: winuser.h:949
#define DUPLICATE_SAME_ACCESS
#define FALSE
Definition: types.h:117
RECT rc
Definition: appbar.cpp:58
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ABM_GETSTATE
Definition: shellapi.h:63
#define PROCESS_DUP_HANDLE
#define FIXME(fmt,...)
Definition: debug.h:111
struct list entry
Definition: appbar.cpp:54
UINT callback_msg
Definition: appbar.cpp:56
smooth NULL
Definition: ftsmooth.c:416
#define ABE_RIGHT
Definition: shellapi.h:19
LONG_PTR LPARAM
Definition: windef.h:208
#define ABS_ALWAYSONTOP
Definition: shellapi.h:22
struct _AppBarData abd
Definition: appbar.cpp:49
static UINT_PTR handle_appbarmessage(DWORD msg, _AppBarData *abd)
Definition: appbar.cpp:133
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
#define SM_CYSCREEN
Definition: winuser.h:950
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define LIST_INIT(head)
Definition: queue.h:197
uint64_t ULONGLONG
Definition: typedefs.h:67
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define FILE_MAP_WRITE
Definition: winbase.h:154
ULONG return_map
Definition: appbar.cpp:41
#define ABM_NEW
Definition: shellapi.h:59
int WINAPI GetSystemMetrics(_In_ int)
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define ABM_SETAUTOHIDEBAR
Definition: shellapi.h:67
ULONGLONG result
Definition: appbar.cpp:48
uint32_t entry
Definition: isohybrid.c:63
#define GetCurrentProcess()
Definition: compat.h:618
#define ABN_POSCHANGED
Definition: shellapi.h:70
#define ERR(fmt,...)
Definition: debug.h:110
#define ABE_BOTTOM
Definition: shellapi.h:20
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1227
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HMONITOR WINAPI MonitorFromWindow(HWND, DWORD)
#define ABM_WINDOWPOSCHANGED
Definition: shellapi.h:68
#define list
Definition: rosglue.h:35
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
static void send_poschanged(HWND hwnd)
Definition: appbar.cpp:95
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static struct list appbars
Definition: appbar.cpp:63
#define msg(x)
Definition: auth_time.c:54
#define ABM_QUERYPOS
Definition: shellapi.h:61
unsigned int ULONG
Definition: retypes.h:1
#define ABM_REMOVE
Definition: shellapi.h:60
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
LONG bottom
Definition: windef.h:309
UINT edge
Definition: appbar.cpp:57
#define ABM_SETPOS
Definition: shellapi.h:62
LONG_PTR LRESULT
Definition: windef.h:209
LRESULT appbar_message(COPYDATASTRUCT *cds)
Definition: appbar.cpp:229
#define UnmapViewOfFile
Definition: compat.h:605
GLuint64EXT * result
Definition: glext.h:11304
LPARAM lParam
Definition: combotst.c:139
UINT uEdge
Definition: shellapi.h:218
#define HeapFree(x, y, z)
Definition: compat.h:594
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
DWORD return_process
Definition: appbar.cpp:42