Remove the win32 debug channel, misc cleanup of debugging code.
[wine/dcerpc.git] / dlls / user / focus.c
blob3126379658714fbdccabb2c13b5e06dd4fcd0643
1 /*
2 * Focus and activation functions
4 * Copyright 1993 David Metcalfe
5 * Copyright 1995 Alex Korobka
6 * Copyright 1994, 2002 Alexandre Julliard
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "config.h"
24 #include "wine/port.h"
26 #include <stdarg.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winuser.h"
31 #include "winerror.h"
32 #include "win.h"
33 #include "message.h"
34 #include "user.h"
35 #include "wine/server.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(win);
41 /*****************************************************************
42 * set_focus_window
44 * Change the focus window, sending the WM_SETFOCUS and WM_KILLFOCUS messages
46 static HWND set_focus_window( HWND hwnd )
48 HWND previous = 0;
49 BOOL ret;
51 SERVER_START_REQ( set_focus_window )
53 req->handle = hwnd;
54 if ((ret = !wine_server_call_err( req ))) previous = reply->previous;
56 SERVER_END_REQ;
57 if (!ret) return 0;
58 if (previous == hwnd) return previous;
60 if (previous)
62 SendMessageW( previous, WM_KILLFOCUS, (WPARAM)hwnd, 0 );
63 if (hwnd != GetFocus()) return previous; /* changed by the message */
65 if (IsWindow(hwnd))
67 if (USER_Driver.pSetFocus) USER_Driver.pSetFocus(hwnd);
68 SendMessageW( hwnd, WM_SETFOCUS, (WPARAM)previous, 0 );
70 return previous;
74 /*******************************************************************
75 * set_active_window
77 static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
79 HWND previous = GetActiveWindow();
80 BOOL ret;
81 DWORD old_thread, new_thread;
82 CBTACTIVATESTRUCT cbt;
84 if (previous == hwnd)
86 if (prev) *prev = hwnd;
87 return TRUE;
90 /* call CBT hook chain */
91 cbt.fMouse = mouse;
92 cbt.hWndActive = previous;
93 if (HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt, TRUE )) return FALSE;
95 if (IsWindow(previous))
97 SendMessageW( previous, WM_NCACTIVATE, FALSE, (LPARAM)hwnd );
98 SendMessageW( previous, WM_ACTIVATE,
99 MAKEWPARAM( WA_INACTIVE, IsIconic(previous) ), (LPARAM)hwnd );
102 SERVER_START_REQ( set_active_window )
104 req->handle = hwnd;
105 if ((ret = !wine_server_call_err( req ))) previous = reply->previous;
107 SERVER_END_REQ;
108 if (!ret) return FALSE;
109 if (prev) *prev = previous;
110 if (previous == hwnd) return TRUE;
112 if (hwnd)
114 /* send palette messages */
115 if (SendMessageW( hwnd, WM_QUERYNEWPALETTE, 0, 0 ))
116 SendMessageTimeoutW( HWND_BROADCAST, WM_PALETTEISCHANGING, (WPARAM)hwnd, 0,
117 SMTO_ABORTIFHUNG, 2000, NULL );
119 if (!(GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_MANAGED))
120 SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
122 if (!IsWindow(hwnd)) return FALSE;
125 old_thread = previous ? GetWindowThreadProcessId( previous, NULL ) : 0;
126 new_thread = hwnd ? GetWindowThreadProcessId( hwnd, NULL ) : 0;
128 if (old_thread != new_thread)
130 HWND *list, *phwnd;
132 if ((list = WIN_ListChildren( GetDesktopWindow() )))
134 if (old_thread)
136 for (phwnd = list; *phwnd; phwnd++)
138 if (GetWindowThreadProcessId( *phwnd, NULL ) == old_thread)
139 SendMessageW( *phwnd, WM_ACTIVATEAPP, 0, new_thread );
142 if (new_thread)
144 for (phwnd = list; *phwnd; phwnd++)
146 if (GetWindowThreadProcessId( *phwnd, NULL ) == new_thread)
147 SendMessageW( *phwnd, WM_ACTIVATEAPP, 1, old_thread );
150 HeapFree( GetProcessHeap(), 0, list );
154 if (IsWindow(hwnd))
156 SendMessageW( hwnd, WM_NCACTIVATE, (hwnd == GetForegroundWindow()), (LPARAM)previous );
157 SendMessageW( hwnd, WM_ACTIVATE,
158 MAKEWPARAM( mouse ? WA_CLICKACTIVE : WA_ACTIVE, IsIconic(hwnd) ),
159 (LPARAM)previous );
162 /* now change focus if necessary */
163 if (focus)
165 HWND curfocus = GetFocus();
166 if (!curfocus || !hwnd || GetAncestor( curfocus, GA_ROOT ) != hwnd)
167 set_focus_window( hwnd );
170 return TRUE;
174 /*******************************************************************
175 * set_foreground_window
177 static BOOL set_foreground_window( HWND hwnd, BOOL mouse )
179 BOOL ret, send_msg_old = FALSE, send_msg_new = FALSE;
180 HWND previous = 0;
182 SERVER_START_REQ( set_foreground_window )
184 req->handle = hwnd;
185 if ((ret = !wine_server_call_err( req )))
187 previous = reply->previous;
188 send_msg_old = reply->send_msg_old;
189 send_msg_new = reply->send_msg_new;
192 SERVER_END_REQ;
194 if (ret)
196 if (send_msg_old) /* old window belongs to other thread */
197 SendNotifyMessageW( previous, WM_WINE_SETACTIVEWINDOW, 0, 0 );
198 else if (send_msg_new) /* old window belongs to us but new one to other thread */
199 ret = set_active_window( 0, NULL, mouse, TRUE );
201 if (send_msg_new) /* new window belongs to other thread */
202 SendNotifyMessageW( hwnd, WM_WINE_SETACTIVEWINDOW, (WPARAM)hwnd, 0 );
203 else /* new window belongs to us */
204 ret = set_active_window( hwnd, NULL, mouse, TRUE );
206 return ret;
210 /*******************************************************************
211 * FOCUS_MouseActivate
213 * Activate a window as a result of a mouse click
215 BOOL FOCUS_MouseActivate( HWND hwnd )
217 return set_foreground_window( hwnd, TRUE );
221 /*******************************************************************
222 * SetActiveWindow (USER32.@)
224 HWND WINAPI SetActiveWindow( HWND hwnd )
226 HWND prev;
228 TRACE( "%p\n", hwnd );
230 if (hwnd)
232 LONG style = GetWindowLongW( hwnd, GWL_STYLE );
234 if (!(style & WS_VISIBLE) || (style & (WS_POPUP|WS_CHILD)) == WS_CHILD)
235 return GetActiveWindow(); /* Windows doesn't seem to return an error here */
237 hwnd = WIN_GetFullHandle( hwnd );
240 if (!set_active_window( hwnd, &prev, FALSE, TRUE )) return 0;
241 return prev;
245 /*****************************************************************
246 * SetFocus (USER32.@)
248 HWND WINAPI SetFocus( HWND hwnd )
250 HWND hwndTop = hwnd;
251 HWND previous = GetFocus();
253 TRACE( "%p prev %p\n", hwnd, previous );
255 if (hwnd)
257 /* Check if we can set the focus to this window */
258 hwnd = WIN_GetFullHandle( hwnd );
259 if (hwnd == previous) return previous; /* nothing to do */
260 for (;;)
262 HWND parent;
263 LONG style = GetWindowLongW( hwndTop, GWL_STYLE );
264 if (style & (WS_MINIMIZE | WS_DISABLED)) return 0;
265 parent = GetAncestor( hwndTop, GA_PARENT );
266 if (!parent || parent == GetDesktopWindow()) break;
267 hwndTop = parent;
270 /* call hooks */
271 if (HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous, TRUE )) return 0;
273 /* activate hwndTop if needed. */
274 if (hwndTop != GetActiveWindow())
276 if (!set_active_window( hwndTop, NULL, FALSE, FALSE )) return 0;
277 if (!IsWindow( hwnd )) return 0; /* Abort if window destroyed */
280 else /* NULL hwnd passed in */
282 if (!previous) return 0; /* nothing to do */
283 if (HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)previous, TRUE )) return 0;
286 /* change focus and send messages */
287 return set_focus_window( hwnd );
291 /*******************************************************************
292 * SetForegroundWindow (USER32.@)
294 BOOL WINAPI SetForegroundWindow( HWND hwnd )
296 TRACE( "%p\n", hwnd );
297 if (hwnd) hwnd = WIN_GetFullHandle( hwnd );
298 return set_foreground_window( hwnd, FALSE );
302 /*******************************************************************
303 * GetActiveWindow (USER32.@)
305 HWND WINAPI GetActiveWindow(void)
307 HWND ret = 0;
309 SERVER_START_REQ( get_thread_input )
311 req->tid = GetCurrentThreadId();
312 if (!wine_server_call_err( req )) ret = reply->active;
314 SERVER_END_REQ;
315 return ret;
319 /*****************************************************************
320 * GetFocus (USER32.@)
322 HWND WINAPI GetFocus(void)
324 HWND ret = 0;
326 SERVER_START_REQ( get_thread_input )
328 req->tid = GetCurrentThreadId();
329 if (!wine_server_call_err( req )) ret = reply->focus;
331 SERVER_END_REQ;
332 return ret;
336 /*******************************************************************
337 * GetForegroundWindow (USER32.@)
339 HWND WINAPI GetForegroundWindow(void)
341 HWND ret = 0;
343 SERVER_START_REQ( get_thread_input )
345 req->tid = 0;
346 if (!wine_server_call_err( req )) ret = reply->foreground;
348 SERVER_END_REQ;
349 return ret;
353 /***********************************************************************
354 * SetShellWindowEx (USER32.@)
355 * hwndShell = Progman[Program Manager]
356 * |-> SHELLDLL_DefView
357 * hwndListView = | |-> SysListView32
358 * | | |-> tooltips_class32
359 * | |
360 * | |-> SysHeader32
362 * |-> ProxyTarget
364 BOOL WINAPI SetShellWindowEx(HWND hwndShell, HWND hwndListView)
366 BOOL ret;
368 if (GetShellWindow())
369 return FALSE;
371 if (GetWindowLongW(hwndShell, GWL_EXSTYLE) & WS_EX_TOPMOST)
372 return FALSE;
374 if (hwndListView != hwndShell)
375 if (GetWindowLongW(hwndListView, GWL_EXSTYLE) & WS_EX_TOPMOST)
376 return FALSE;
378 if (hwndListView && hwndListView!=hwndShell)
379 SetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
381 SetWindowPos(hwndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
383 SERVER_START_REQ(set_global_windows)
385 req->flags = SET_GLOBAL_SHELL_WINDOWS;
386 req->shell_window = hwndShell;
387 req->shell_listview = hwndListView;
388 ret = !wine_server_call_err(req);
390 SERVER_END_REQ;
392 return ret;
396 /*******************************************************************
397 * SetShellWindow (USER32.@)
399 BOOL WINAPI SetShellWindow(HWND hwndShell)
401 return SetShellWindowEx(hwndShell, hwndShell);
405 /*******************************************************************
406 * GetShellWindow (USER32.@)
408 HWND WINAPI GetShellWindow(void)
410 HWND hwndShell = 0;
412 SERVER_START_REQ(set_global_windows)
414 req->flags = 0;
415 if (!wine_server_call_err(req))
416 hwndShell = reply->old_shell_window;
418 SERVER_END_REQ;
420 return hwndShell;
424 /***********************************************************************
425 * SetProgmanWindow (USER32.@)
427 HWND WINAPI SetProgmanWindow ( HWND hwnd )
429 SERVER_START_REQ(set_global_windows)
431 req->flags = SET_GLOBAL_PROGMAN_WINDOW;
432 req->progman_window = hwnd;
433 if (wine_server_call_err( req )) hwnd = 0;
435 SERVER_END_REQ;
436 return hwnd;
440 /***********************************************************************
441 * GetProgmanWindow (USER32.@)
443 HWND WINAPI GetProgmanWindow(void)
445 HWND ret = 0;
447 SERVER_START_REQ(set_global_windows)
449 req->flags = 0;
450 if (!wine_server_call_err(req)) ret = reply->old_progman_window;
452 SERVER_END_REQ;
453 return ret;
457 /***********************************************************************
458 * SetTaskmanWindow (USER32.@)
459 * NOTES
460 * hwnd = MSTaskSwWClass
461 * |-> SysTabControl32
463 HWND WINAPI SetTaskmanWindow ( HWND hwnd )
465 SERVER_START_REQ(set_global_windows)
467 req->flags = SET_GLOBAL_TASKMAN_WINDOW;
468 req->taskman_window = hwnd;
469 if (wine_server_call_err( req )) hwnd = 0;
471 SERVER_END_REQ;
472 return hwnd;
475 /***********************************************************************
476 * GetTaskmanWindow (USER32.@)
478 HWND WINAPI GetTaskmanWindow(void)
480 HWND ret = 0;
482 SERVER_START_REQ(set_global_windows)
484 req->flags = 0;
485 if (!wine_server_call_err(req)) ret = reply->old_taskman_window;
487 SERVER_END_REQ;
488 return ret;