~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/user32/focus.c

Version: ~ [ wine-1.5.31 ] ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Focus and activation functions
  3  *
  4  * Copyright 1993 David Metcalfe
  5  * Copyright 1995 Alex Korobka
  6  * Copyright 1994, 2002 Alexandre Julliard
  7  *
  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.
 12  *
 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.
 17  *
 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 21  */
 22 
 23 #include "config.h"
 24 #include "wine/port.h"
 25 
 26 #include <stdarg.h>
 27 
 28 #include "windef.h"
 29 #include "winbase.h"
 30 #include "winuser.h"
 31 #include "win.h"
 32 #include "user_private.h"
 33 #include "wine/server.h"
 34 #include "wine/debug.h"
 35 
 36 WINE_DEFAULT_DEBUG_CHANNEL(win);
 37 
 38 
 39 /*****************************************************************
 40  *              set_focus_window
 41  *
 42  * Change the focus window, sending the WM_SETFOCUS and WM_KILLFOCUS messages
 43  */
 44 static HWND set_focus_window( HWND hwnd )
 45 {
 46     HWND previous = 0;
 47     BOOL ret;
 48 
 49     SERVER_START_REQ( set_focus_window )
 50     {
 51         req->handle = wine_server_user_handle( hwnd );
 52         if ((ret = !wine_server_call_err( req )))
 53             previous = wine_server_ptr_handle( reply->previous );
 54     }
 55     SERVER_END_REQ;
 56     if (!ret) return 0;
 57     if (previous == hwnd) return previous;
 58 
 59     if (previous)
 60     {
 61         SendMessageW( previous, WM_KILLFOCUS, (WPARAM)hwnd, 0 );
 62         if (hwnd != GetFocus()) return previous;  /* changed by the message */
 63     }
 64     if (IsWindow(hwnd))
 65     {
 66         USER_Driver->pSetFocus(hwnd);
 67         SendMessageW( hwnd, WM_SETFOCUS, (WPARAM)previous, 0 );
 68     }
 69     return previous;
 70 }
 71 
 72 
 73 /*******************************************************************
 74  *              set_active_window
 75  */
 76 static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus )
 77 {
 78     HWND previous = GetActiveWindow();
 79     BOOL ret;
 80     DWORD old_thread, new_thread;
 81     CBTACTIVATESTRUCT cbt;
 82 
 83     if (previous == hwnd)
 84     {
 85         if (prev) *prev = hwnd;
 86         return TRUE;
 87     }
 88 
 89     /* call CBT hook chain */
 90     cbt.fMouse     = mouse;
 91     cbt.hWndActive = previous;
 92     if (HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt, TRUE )) return FALSE;
 93 
 94     if (IsWindow(previous))
 95     {
 96         SendMessageW( previous, WM_NCACTIVATE, FALSE, (LPARAM)hwnd );
 97         SendMessageW( previous, WM_ACTIVATE,
 98                       MAKEWPARAM( WA_INACTIVE, IsIconic(previous) ), (LPARAM)hwnd );
 99     }
100 
101     SERVER_START_REQ( set_active_window )
102     {
103         req->handle = wine_server_user_handle( hwnd );
104         if ((ret = !wine_server_call_err( req )))
105             previous = wine_server_ptr_handle( reply->previous );
106     }
107     SERVER_END_REQ;
108     if (!ret) return FALSE;
109     if (prev) *prev = previous;
110     if (previous == hwnd) return TRUE;
111 
112     if (hwnd)
113     {
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 );
118         if (!IsWindow(hwnd)) return FALSE;
119     }
120 
121     old_thread = previous ? GetWindowThreadProcessId( previous, NULL ) : 0;
122     new_thread = hwnd ? GetWindowThreadProcessId( hwnd, NULL ) : 0;
123 
124     if (old_thread != new_thread)
125     {
126         HWND *list, *phwnd;
127 
128         if ((list = WIN_ListChildren( GetDesktopWindow() )))
129         {
130             if (old_thread)
131             {
132                 for (phwnd = list; *phwnd; phwnd++)
133                 {
134                     if (GetWindowThreadProcessId( *phwnd, NULL ) == old_thread)
135                         SendMessageW( *phwnd, WM_ACTIVATEAPP, 0, new_thread );
136                 }
137             }
138             if (new_thread)
139             {
140                 for (phwnd = list; *phwnd; phwnd++)
141                 {
142                     if (GetWindowThreadProcessId( *phwnd, NULL ) == new_thread)
143                         SendMessageW( *phwnd, WM_ACTIVATEAPP, 1, old_thread );
144                 }
145             }
146             HeapFree( GetProcessHeap(), 0, list );
147         }
148     }
149 
150     if (IsWindow(hwnd))
151     {
152         SendMessageW( hwnd, WM_NCACTIVATE, (hwnd == GetForegroundWindow()), (LPARAM)previous );
153         SendMessageW( hwnd, WM_ACTIVATE,
154                       MAKEWPARAM( mouse ? WA_CLICKACTIVE : WA_ACTIVE, IsIconic(hwnd) ),
155                       (LPARAM)previous );
156     }
157 
158     /* now change focus if necessary */
159     if (focus)
160     {
161         GUITHREADINFO info;
162 
163         GetGUIThreadInfo( GetCurrentThreadId(), &info );
164         /* Do not change focus if the window is no more active */
165         if (hwnd == info.hwndActive)
166         {
167             if (!info.hwndFocus || !hwnd || GetAncestor( info.hwndFocus, GA_ROOT ) != hwnd)
168                 set_focus_window( hwnd );
169         }
170     }
171 
172     return TRUE;
173 }
174 
175 
176 /*******************************************************************
177  *              set_foreground_window
178  */
179 static BOOL set_foreground_window( HWND hwnd, BOOL mouse )
180 {
181     BOOL ret, send_msg_old = FALSE, send_msg_new = FALSE;
182     HWND previous = 0;
183 
184     SERVER_START_REQ( set_foreground_window )
185     {
186         req->handle = wine_server_user_handle( hwnd );
187         if ((ret = !wine_server_call_err( req )))
188         {
189             previous = wine_server_ptr_handle( reply->previous );
190             send_msg_old = reply->send_msg_old;
191             send_msg_new = reply->send_msg_new;
192         }
193     }
194     SERVER_END_REQ;
195 
196     if (ret)
197     {
198         if (send_msg_old)  /* old window belongs to other thread */
199             SendNotifyMessageW( previous, WM_WINE_SETACTIVEWINDOW, 0, 0 );
200         else if (send_msg_new)  /* old window belongs to us but new one to other thread */
201             ret = set_active_window( 0, NULL, mouse, TRUE );
202 
203         if (send_msg_new)  /* new window belongs to other thread */
204             SendNotifyMessageW( hwnd, WM_WINE_SETACTIVEWINDOW, (WPARAM)hwnd, 0 );
205         else  /* new window belongs to us */
206             ret = set_active_window( hwnd, NULL, mouse, TRUE );
207     }
208     return ret;
209 }
210 
211 
212 /*******************************************************************
213  *              FOCUS_MouseActivate
214  *
215  * Activate a window as a result of a mouse click
216  */
217 BOOL FOCUS_MouseActivate( HWND hwnd )
218 {
219     return set_foreground_window( hwnd, TRUE );
220 }
221 
222 
223 /*******************************************************************
224  *              SetActiveWindow (USER32.@)
225  */
226 HWND WINAPI SetActiveWindow( HWND hwnd )
227 {
228     HWND prev;
229 
230     TRACE( "%p\n", hwnd );
231 
232     if (hwnd)
233     {
234         LONG style = GetWindowLongW( hwnd, GWL_STYLE );
235 
236         if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD)
237             return GetActiveWindow();  /* Windows doesn't seem to return an error here */
238 
239         hwnd = WIN_GetFullHandle( hwnd );
240     }
241 
242     if (!set_active_window( hwnd, &prev, FALSE, TRUE )) return 0;
243     return prev;
244 }
245 
246 
247 /*****************************************************************
248  *              SetFocus  (USER32.@)
249  */
250 HWND WINAPI SetFocus( HWND hwnd )
251 {
252     HWND hwndTop = hwnd;
253     HWND previous = GetFocus();
254 
255     TRACE( "%p prev %p\n", hwnd, previous );
256 
257     if (hwnd)
258     {
259         /* Check if we can set the focus to this window */
260         hwnd = WIN_GetFullHandle( hwnd );
261         if (hwnd == previous) return previous;  /* nothing to do */
262         for (;;)
263         {
264             HWND parent;
265             LONG style = GetWindowLongW( hwndTop, GWL_STYLE );
266             if (style & (WS_MINIMIZE | WS_DISABLED)) return 0;
267             parent = GetAncestor( hwndTop, GA_PARENT );
268             if (!parent || parent == GetDesktopWindow()) break;
269             if (parent == get_hwnd_message_parent()) return 0;
270             hwndTop = parent;
271         }
272 
273         /* call hooks */
274         if (HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous, TRUE )) return 0;
275 
276         /* activate hwndTop if needed. */
277         if (hwndTop != GetActiveWindow())
278         {
279             if (!set_active_window( hwndTop, NULL, FALSE, FALSE )) return 0;
280             if (!IsWindow( hwnd )) return 0;  /* Abort if window destroyed */
281 
282             /* Do not change focus if the window is no longer active */
283             if (hwndTop != GetActiveWindow()) return 0;
284         }
285     }
286     else /* NULL hwnd passed in */
287     {
288         if (!previous) return 0;  /* nothing to do */
289         if (HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)previous, TRUE )) return 0;
290     }
291 
292     /* change focus and send messages */
293     return set_focus_window( hwnd );
294 }
295 
296 
297 /*******************************************************************
298  *              SetForegroundWindow  (USER32.@)
299  */
300 BOOL WINAPI SetForegroundWindow( HWND hwnd )
301 {
302     TRACE( "%p\n", hwnd );
303 
304     hwnd = WIN_GetFullHandle( hwnd );
305     return set_foreground_window( hwnd, FALSE );
306 }
307 
308 
309 /*******************************************************************
310  *              GetActiveWindow  (USER32.@)
311  */
312 HWND WINAPI GetActiveWindow(void)
313 {
314     HWND ret = 0;
315 
316     SERVER_START_REQ( get_thread_input )
317     {
318         req->tid = GetCurrentThreadId();
319         if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->active );
320     }
321     SERVER_END_REQ;
322     return ret;
323 }
324 
325 
326 /*****************************************************************
327  *              GetFocus  (USER32.@)
328  */
329 HWND WINAPI GetFocus(void)
330 {
331     HWND ret = 0;
332 
333     SERVER_START_REQ( get_thread_input )
334     {
335         req->tid = GetCurrentThreadId();
336         if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->focus );
337     }
338     SERVER_END_REQ;
339     return ret;
340 }
341 
342 
343 /*******************************************************************
344  *              GetForegroundWindow  (USER32.@)
345  */
346 HWND WINAPI GetForegroundWindow(void)
347 {
348     HWND ret = 0;
349 
350     SERVER_START_REQ( get_thread_input )
351     {
352         req->tid = 0;
353         if (!wine_server_call_err( req )) ret = wine_server_ptr_handle( reply->foreground );
354     }
355     SERVER_END_REQ;
356     return ret;
357 }
358 
359 
360 /***********************************************************************
361 *               SetShellWindowEx (USER32.@)
362 * hwndShell =    Progman[Program Manager]
363 *                |-> SHELLDLL_DefView
364 * hwndListView = |   |-> SysListView32
365 *                |   |   |-> tooltips_class32
366 *                |   |
367 *                |   |-> SysHeader32
368 *                |
369 *                |-> ProxyTarget
370 */
371 BOOL WINAPI SetShellWindowEx(HWND hwndShell, HWND hwndListView)
372 {
373     BOOL ret;
374 
375     if (GetShellWindow())
376         return FALSE;
377 
378     if (GetWindowLongW(hwndShell, GWL_EXSTYLE) & WS_EX_TOPMOST)
379         return FALSE;
380 
381     if (hwndListView != hwndShell)
382         if (GetWindowLongW(hwndListView, GWL_EXSTYLE) & WS_EX_TOPMOST)
383             return FALSE;
384 
385     if (hwndListView && hwndListView!=hwndShell)
386         SetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
387 
388     SetWindowPos(hwndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
389 
390     SERVER_START_REQ(set_global_windows)
391     {
392         req->flags          = SET_GLOBAL_SHELL_WINDOWS;
393         req->shell_window   = wine_server_user_handle( hwndShell );
394         req->shell_listview = wine_server_user_handle( hwndListView );
395         ret = !wine_server_call_err(req);
396     }
397     SERVER_END_REQ;
398 
399     return ret;
400 }
401 
402 
403 /*******************************************************************
404 *               SetShellWindow (USER32.@)
405 */
406 BOOL WINAPI SetShellWindow(HWND hwndShell)
407 {
408     return SetShellWindowEx(hwndShell, hwndShell);
409 }
410 
411 
412 /*******************************************************************
413 *               GetShellWindow (USER32.@)
414 */
415 HWND WINAPI GetShellWindow(void)
416 {
417     HWND hwndShell = 0;
418 
419     SERVER_START_REQ(set_global_windows)
420     {
421         req->flags = 0;
422         if (!wine_server_call_err(req))
423             hwndShell = wine_server_ptr_handle( reply->old_shell_window );
424     }
425     SERVER_END_REQ;
426 
427     return hwndShell;
428 }
429 
430 
431 /***********************************************************************
432  *              SetProgmanWindow (USER32.@)
433  */
434 HWND WINAPI SetProgmanWindow ( HWND hwnd )
435 {
436     SERVER_START_REQ(set_global_windows)
437     {
438         req->flags          = SET_GLOBAL_PROGMAN_WINDOW;
439         req->progman_window = wine_server_user_handle( hwnd );
440         if (wine_server_call_err( req )) hwnd = 0;
441     }
442     SERVER_END_REQ;
443     return hwnd;
444 }
445 
446 
447 /***********************************************************************
448  *              GetProgmanWindow (USER32.@)
449  */
450 HWND WINAPI GetProgmanWindow(void)
451 {
452     HWND ret = 0;
453 
454     SERVER_START_REQ(set_global_windows)
455     {
456         req->flags = 0;
457         if (!wine_server_call_err(req))
458             ret = wine_server_ptr_handle( reply->old_progman_window );
459     }
460     SERVER_END_REQ;
461     return ret;
462 }
463 
464 
465 /***********************************************************************
466  *              SetTaskmanWindow (USER32.@)
467  * NOTES
468  *   hwnd = MSTaskSwWClass
469  *          |-> SysTabControl32
470  */
471 HWND WINAPI SetTaskmanWindow ( HWND hwnd )
472 {
473     SERVER_START_REQ(set_global_windows)
474     {
475         req->flags          = SET_GLOBAL_TASKMAN_WINDOW;
476         req->taskman_window = wine_server_user_handle( hwnd );
477         if (wine_server_call_err( req )) hwnd = 0;
478     }
479     SERVER_END_REQ;
480     return hwnd;
481 }
482 
483 /***********************************************************************
484  *              GetTaskmanWindow (USER32.@)
485  */
486 HWND WINAPI GetTaskmanWindow(void)
487 {
488     HWND ret = 0;
489 
490     SERVER_START_REQ(set_global_windows)
491     {
492         req->flags = 0;
493         if (!wine_server_call_err(req))
494             ret = wine_server_ptr_handle( reply->old_taskman_window );
495     }
496     SERVER_END_REQ;
497     return ret;
498 }
499 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.