blob: f9a05cab7eae350b32e15978b370bbbadcad4bc0 [file] [log] [blame]
Alexandre Julliard401710d1993-09-04 10:09:32 +00001/*
2 * Window related functions
3 *
Alexandre Julliardaca05781994-10-17 18:12:41 +00004 * Copyright 1993, 1994 Alexandre Julliard
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00005 *
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Alexandre Julliard401710d1993-09-04 10:09:32 +000019 */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +000020
Alexandre Julliard5769d1d2002-04-26 19:05:15 +000021#include "config.h"
22#include "wine/port.h"
23
Alexandre Julliard7695d692001-09-24 01:19:59 +000024#include <assert.h>
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000025#include <stdarg.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000026#include <stdlib.h>
Alexandre Julliardfb9a9191994-03-01 19:48:04 +000027#include <string.h>
Jeremy Whited3e22d92000-02-10 19:03:02 +000028#include "windef.h"
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000029#include "winbase.h"
Marcus Meissner317af321999-02-17 13:51:06 +000030#include "wine/winbase16.h"
Michael Veksler9d14a001999-05-08 12:40:24 +000031#include "wine/winuser16.h"
Alexandre Julliard0ca051e2002-10-17 16:43:42 +000032#include "wownt32.h"
Alexandre Julliard1a66d222001-08-28 18:44:52 +000033#include "wine/server.h"
Alexandre Julliardcb10fda2000-08-06 02:41:16 +000034#include "wine/unicode.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000035#include "win.h"
Alexandre Julliard6a78c162004-12-08 18:06:14 +000036#include "user_private.h"
Alexandre Julliard5f721f81994-01-04 20:14:34 +000037#include "dce.h"
Alexandre Julliard91222da2000-12-10 23:01:33 +000038#include "controls.h"
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000039#include "cursoricon.h"
Alexandre Julliardef702d81996-05-28 18:54:58 +000040#include "message.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000041#include "winpos.h"
Alexandre Julliard767e6f61998-08-09 12:47:43 +000042#include "winerror.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000043#include "wine/debug.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000044
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000045WINE_DEFAULT_DEBUG_CHANNEL(win);
46WINE_DECLARE_DEBUG_CHANNEL(msg);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000047
Alexandre Julliarded8a41c2004-05-28 19:35:37 +000048#define NB_USER_HANDLES ((LAST_USER_HANDLE - FIRST_USER_HANDLE + 1) >> 1)
49#define USER_HANDLE_TO_INDEX(hwnd) ((LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1)
Alexandre Julliard7695d692001-09-24 01:19:59 +000050
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000051/**********************************************************************/
52
Alexandre Julliard59730ae1996-03-24 16:20:51 +000053/* Desktop window */
54static WND *pWndDesktop = NULL;
55
Alexandre Julliardd4719651995-12-12 18:49:11 +000056static WORD wDragWidth = 4;
57static WORD wDragHeight= 3;
Alexandre Julliardade697e1995-11-26 13:59:11 +000058
Alexandre Julliard7695d692001-09-24 01:19:59 +000059static void *user_handles[NB_USER_HANDLES];
Alexandre Julliard1a66d222001-08-28 18:44:52 +000060
Alexandre Julliard401710d1993-09-04 10:09:32 +000061/***********************************************************************
Alexandre Julliard1a66d222001-08-28 18:44:52 +000062 * create_window_handle
63 *
64 * Create a window handle with the server.
65 */
Alexandre Julliardbfce1512003-12-10 04:08:06 +000066static WND *create_window_handle( HWND parent, HWND owner, ATOM atom,
67 HINSTANCE instance, WINDOWPROCTYPE type )
Alexandre Julliard1a66d222001-08-28 18:44:52 +000068{
Alexandre Julliard7695d692001-09-24 01:19:59 +000069 WORD index;
Alexandre Julliardbfce1512003-12-10 04:08:06 +000070 WND *win;
Alexandre Julliardbd13ab82003-12-11 05:34:53 +000071 struct tagCLASS *class = NULL;
Alexandre Julliardbfce1512003-12-10 04:08:06 +000072 user_handle_t handle = 0;
Alexandre Julliardbd13ab82003-12-11 05:34:53 +000073 int extra_bytes = 0;
Alexandre Julliard1a66d222001-08-28 18:44:52 +000074
Alexandre Julliard417bcb32004-01-28 21:43:36 +000075 /* if 16-bit instance, map to module handle */
76 if (instance && !HIWORD(instance))
77 instance = HINSTANCE_32(GetExePtr(HINSTANCE_16(instance)));
Alexandre Julliard1a66d222001-08-28 18:44:52 +000078
Alexandre Julliarda09da0c2001-09-21 21:08:40 +000079 SERVER_START_REQ( create_window )
Alexandre Julliard1a66d222001-08-28 18:44:52 +000080 {
Alexandre Julliardbfce1512003-12-10 04:08:06 +000081 req->parent = parent;
82 req->owner = owner;
83 req->atom = atom;
84 req->instance = instance;
Alexandre Julliardbd13ab82003-12-11 05:34:53 +000085 if (!wine_server_call_err( req ))
86 {
87 handle = reply->handle;
88 extra_bytes = reply->extra;
89 class = reply->class_ptr;
90 }
Alexandre Julliard1a66d222001-08-28 18:44:52 +000091 }
Alexandre Julliarda09da0c2001-09-21 21:08:40 +000092 SERVER_END_REQ;
Alexandre Julliard1a66d222001-08-28 18:44:52 +000093
Alexandre Julliardbd13ab82003-12-11 05:34:53 +000094 if (!handle)
Alexandre Julliard1a66d222001-08-28 18:44:52 +000095 {
Alexandre Julliardbd13ab82003-12-11 05:34:53 +000096 WARN( "error %ld creating window\n", GetLastError() );
Alexandre Julliard1a66d222001-08-28 18:44:52 +000097 return NULL;
98 }
Alexandre Julliardbd13ab82003-12-11 05:34:53 +000099
100 if (!(win = HeapAlloc( GetProcessHeap(), 0, sizeof(WND) + extra_bytes - sizeof(win->wExtra) )))
101 {
102 SERVER_START_REQ( destroy_window )
103 {
104 req->handle = handle;
105 wine_server_call( req );
106 }
107 SERVER_END_REQ;
108 SetLastError( ERROR_NOT_ENOUGH_MEMORY );
109 return NULL;
110 }
111
112 USER_Lock();
113
Alexandre Julliarded8a41c2004-05-28 19:35:37 +0000114 index = USER_HANDLE_TO_INDEX(handle);
Alexandre Julliard7695d692001-09-24 01:19:59 +0000115 assert( index < NB_USER_HANDLES );
116 user_handles[index] = win;
Alexandre Julliardbfce1512003-12-10 04:08:06 +0000117 win->hwndSelf = handle;
118 win->dwMagic = WND_MAGIC;
119 win->irefCount = 1;
Alexandre Julliardbfce1512003-12-10 04:08:06 +0000120 win->cbWndExtra = extra_bytes;
121 memset( win->wExtra, 0, extra_bytes );
Alexandre Julliardbd13ab82003-12-11 05:34:53 +0000122 CLASS_AddWindow( class, win, type );
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000123 return win;
124}
125
126
127/***********************************************************************
128 * free_window_handle
129 *
130 * Free a window handle.
131 */
132static WND *free_window_handle( HWND hwnd )
133{
134 WND *ptr;
Alexandre Julliarded8a41c2004-05-28 19:35:37 +0000135 WORD index = USER_HANDLE_TO_INDEX(hwnd);
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000136
Alexandre Julliard7695d692001-09-24 01:19:59 +0000137 if (index >= NB_USER_HANDLES) return NULL;
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000138 USER_Lock();
Alexandre Julliard7695d692001-09-24 01:19:59 +0000139 if ((ptr = user_handles[index]))
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000140 {
141 SERVER_START_REQ( destroy_window )
142 {
143 req->handle = hwnd;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000144 if (!wine_server_call_err( req ))
Alexandre Julliard7695d692001-09-24 01:19:59 +0000145 user_handles[index] = NULL;
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000146 else
147 ptr = NULL;
148 }
149 SERVER_END_REQ;
150 }
151 USER_Unlock();
Michael Stefaniuc5ad7d852004-12-23 17:06:43 +0000152 HeapFree( GetProcessHeap(), 0, ptr );
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000153 return ptr;
154}
155
156
Alexandre Julliard844ceb92001-10-09 23:26:40 +0000157/*******************************************************************
158 * list_window_children
159 *
160 * Build an array of the children of a given window. The array must be
161 * freed with HeapFree. Returns NULL when no windows are found.
162 */
163static HWND *list_window_children( HWND hwnd, ATOM atom, DWORD tid )
164{
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000165 HWND *list;
166 int size = 32;
Alexandre Julliard844ceb92001-10-09 23:26:40 +0000167
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000168 for (;;)
Alexandre Julliard844ceb92001-10-09 23:26:40 +0000169 {
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000170 int count = 0;
171
172 if (!(list = HeapAlloc( GetProcessHeap(), 0, size * sizeof(HWND) ))) break;
173
174 SERVER_START_REQ( get_window_children )
Alexandre Julliard844ceb92001-10-09 23:26:40 +0000175 {
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000176 req->parent = hwnd;
177 req->atom = atom;
Alexandre Julliard54f22872002-10-03 19:54:57 +0000178 req->tid = tid;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000179 wine_server_set_reply( req, list, (size-1) * sizeof(HWND) );
180 if (!wine_server_call( req )) count = reply->count;
Alexandre Julliard844ceb92001-10-09 23:26:40 +0000181 }
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000182 SERVER_END_REQ;
183 if (count && count < size)
184 {
185 list[count] = 0;
186 return list;
187 }
188 HeapFree( GetProcessHeap(), 0, list );
189 if (!count) break;
190 size = count + 1; /* restart with a large enough buffer */
Alexandre Julliard844ceb92001-10-09 23:26:40 +0000191 }
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000192 return NULL;
Alexandre Julliard844ceb92001-10-09 23:26:40 +0000193}
194
195
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000196/*******************************************************************
Alexandre Julliard932a65d2005-01-31 16:46:47 +0000197 * list_window_parents
198 *
199 * Build an array of all parents of a given window, starting with
200 * the immediate parent. The array must be freed with HeapFree.
201 * Returns NULL if window is a top-level window.
202 */
203static HWND *list_window_parents( HWND hwnd )
204{
205 WND *win;
206 HWND current, *list;
207 int pos = 0, size = 16, count = 0;
208
209 if (!(list = HeapAlloc( GetProcessHeap(), 0, size * sizeof(HWND) ))) return NULL;
210
211 current = hwnd;
212 for (;;)
213 {
214 if (!(win = WIN_GetPtr( current ))) goto empty;
215 if (win == WND_OTHER_PROCESS) break; /* need to do it the hard way */
216 list[pos] = win->parent;
217 WIN_ReleasePtr( win );
218 if (!(current = list[pos]))
219 {
220 if (!pos) goto empty;
221 return list;
222 }
223 if (++pos == size - 1)
224 {
225 /* need to grow the list */
226 HWND *new_list = HeapReAlloc( GetProcessHeap(), 0, list, (size+16) * sizeof(HWND) );
227 if (!new_list) goto empty;
228 list = new_list;
229 size += 16;
230 }
231 }
232
233 /* at least one parent belongs to another process, have to query the server */
234
235 for (;;)
236 {
237 count = 0;
238 SERVER_START_REQ( get_window_parents )
239 {
240 req->handle = hwnd;
241 wine_server_set_reply( req, list, (size-1) * sizeof(HWND) );
242 if (!wine_server_call( req )) count = reply->count;
243 }
244 SERVER_END_REQ;
245 if (!count) goto empty;
246 if (size > count)
247 {
248 list[count] = 0;
249 return list;
250 }
251 HeapFree( GetProcessHeap(), 0, list );
252 size = count + 1;
253 if (!(list = HeapAlloc( GetProcessHeap(), 0, size * sizeof(HWND) ))) return NULL;
254 }
255
256 empty:
257 HeapFree( GetProcessHeap(), 0, list );
258 return NULL;
259}
260
261
262/*******************************************************************
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000263 * send_parent_notify
264 */
265static void send_parent_notify( HWND hwnd, UINT msg )
266{
Dmitry Timoshkov970be642004-04-02 20:10:11 +0000267 if ((GetWindowLongW( hwnd, GWL_STYLE ) & (WS_CHILD | WS_POPUP)) == WS_CHILD &&
268 !(GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_NOPARENTNOTIFY))
269 SendMessageW( GetParent(hwnd), WM_PARENTNOTIFY,
Robert Shearmanbbdac5e2004-09-22 19:14:08 +0000270 MAKEWPARAM( msg, GetWindowLongPtrW( hwnd, GWLP_ID )), (LPARAM)hwnd );
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000271}
272
273
Alexandre Julliard805bdc52001-11-13 22:23:48 +0000274/*******************************************************************
275 * get_server_window_text
276 *
277 * Retrieve the window text from the server.
278 */
279static void get_server_window_text( HWND hwnd, LPWSTR text, INT count )
280{
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000281 size_t len = 0;
282
283 SERVER_START_REQ( get_window_text )
Alexandre Julliard805bdc52001-11-13 22:23:48 +0000284 {
285 req->handle = hwnd;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000286 wine_server_set_reply( req, text, (count - 1) * sizeof(WCHAR) );
287 if (!wine_server_call_err( req )) len = wine_server_reply_size(reply);
Alexandre Julliard805bdc52001-11-13 22:23:48 +0000288 }
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000289 SERVER_END_REQ;
Alexandre Julliard805bdc52001-11-13 22:23:48 +0000290 text[len / sizeof(WCHAR)] = 0;
291}
292
293
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000294/***********************************************************************
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000295 * WIN_GetPtr
Alexandre Julliard6bf2abf2001-08-29 00:16:00 +0000296 *
Alexandre Julliard7695d692001-09-24 01:19:59 +0000297 * Return a pointer to the WND structure if local to the process,
Andreas Mohr7df2d9f2002-07-24 19:02:50 +0000298 * or WND_OTHER_PROCESS if handle may be valid in other process.
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000299 * If ret value is a valid pointer, it must be released with WIN_ReleasePtr.
Alexandre Julliard6bf2abf2001-08-29 00:16:00 +0000300 */
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000301WND *WIN_GetPtr( HWND hwnd )
Alexandre Julliard6bf2abf2001-08-29 00:16:00 +0000302{
Alexandre Julliard37a46392001-09-12 17:19:13 +0000303 WND * ptr;
Alexandre Julliarded8a41c2004-05-28 19:35:37 +0000304 WORD index = USER_HANDLE_TO_INDEX(hwnd);
Alexandre Julliard37a46392001-09-12 17:19:13 +0000305
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000306 if (index >= NB_USER_HANDLES) return NULL;
Alexandre Julliard37a46392001-09-12 17:19:13 +0000307
308 USER_Lock();
Alexandre Julliard7695d692001-09-24 01:19:59 +0000309 if ((ptr = user_handles[index]))
Alexandre Julliard37a46392001-09-12 17:19:13 +0000310 {
311 if (ptr->dwMagic == WND_MAGIC && (!HIWORD(hwnd) || hwnd == ptr->hwndSelf))
312 return ptr;
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000313 ptr = NULL;
Alexandre Julliard37a46392001-09-12 17:19:13 +0000314 }
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000315 else ptr = WND_OTHER_PROCESS;
Alexandre Julliard37a46392001-09-12 17:19:13 +0000316 USER_Unlock();
Alexandre Julliard7695d692001-09-24 01:19:59 +0000317 return ptr;
318}
319
320
321/***********************************************************************
322 * WIN_IsCurrentProcess
323 *
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000324 * Check whether a given window belongs to the current process (and return the full handle).
Alexandre Julliard7695d692001-09-24 01:19:59 +0000325 */
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000326HWND WIN_IsCurrentProcess( HWND hwnd )
Alexandre Julliard7695d692001-09-24 01:19:59 +0000327{
328 WND *ptr;
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000329 HWND ret;
Alexandre Julliard7695d692001-09-24 01:19:59 +0000330
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000331 if (!(ptr = WIN_GetPtr( hwnd )) || ptr == WND_OTHER_PROCESS) return 0;
332 ret = ptr->hwndSelf;
333 WIN_ReleasePtr( ptr );
334 return ret;
Alexandre Julliard7695d692001-09-24 01:19:59 +0000335}
336
337
338/***********************************************************************
339 * WIN_IsCurrentThread
340 *
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000341 * Check whether a given window belongs to the current thread (and return the full handle).
Alexandre Julliard7695d692001-09-24 01:19:59 +0000342 */
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000343HWND WIN_IsCurrentThread( HWND hwnd )
Alexandre Julliard7695d692001-09-24 01:19:59 +0000344{
345 WND *ptr;
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000346 HWND ret = 0;
Alexandre Julliard7695d692001-09-24 01:19:59 +0000347
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000348 if ((ptr = WIN_GetPtr( hwnd )) && ptr != WND_OTHER_PROCESS)
Alexandre Julliard7695d692001-09-24 01:19:59 +0000349 {
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000350 if (ptr->tid == GetCurrentThreadId()) ret = ptr->hwndSelf;
351 WIN_ReleasePtr( ptr );
Alexandre Julliard7695d692001-09-24 01:19:59 +0000352 }
353 return ret;
Alexandre Julliard37a46392001-09-12 17:19:13 +0000354}
355
356
357/***********************************************************************
358 * WIN_Handle32
359 *
360 * Convert a 16-bit window handle to a full 32-bit handle.
361 */
362HWND WIN_Handle32( HWND16 hwnd16 )
363{
364 WND *ptr;
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000365 HWND hwnd = (HWND)(ULONG_PTR)hwnd16;
Alexandre Julliard37a46392001-09-12 17:19:13 +0000366
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000367 if (hwnd16 <= 1 || hwnd16 == 0xffff) return hwnd;
368 /* do sign extension for -2 and -3 */
369 if (hwnd16 >= (HWND16)-3) return (HWND)(LONG_PTR)(INT16)hwnd16;
Alexandre Julliard37a46392001-09-12 17:19:13 +0000370
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000371 if (!(ptr = WIN_GetPtr( hwnd ))) return hwnd;
372
373 if (ptr != WND_OTHER_PROCESS)
Alexandre Julliard37a46392001-09-12 17:19:13 +0000374 {
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000375 hwnd = ptr->hwndSelf;
376 WIN_ReleasePtr( ptr );
Alexandre Julliard37a46392001-09-12 17:19:13 +0000377 }
378 else /* may belong to another process */
Alexandre Julliard6bf2abf2001-08-29 00:16:00 +0000379 {
380 SERVER_START_REQ( get_window_info )
381 {
Alexandre Julliardd23a82b2001-09-19 20:37:04 +0000382 req->handle = hwnd;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000383 if (!wine_server_call_err( req )) hwnd = reply->full_handle;
Alexandre Julliard6bf2abf2001-08-29 00:16:00 +0000384 }
385 SERVER_END_REQ;
386 }
387 return hwnd;
388}
389
390
391/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000392 * WIN_FindWndPtr
393 *
394 * Return a pointer to the WND structure corresponding to a HWND.
Alexandre Julliard401710d1993-09-04 10:09:32 +0000395 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000396WND * WIN_FindWndPtr( HWND hwnd )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000397{
398 WND * ptr;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000399
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000400 if (!hwnd) return NULL;
401
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000402 if ((ptr = WIN_GetPtr( hwnd )))
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000403 {
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000404 if (ptr != WND_OTHER_PROCESS)
Alexandre Julliard7695d692001-09-24 01:19:59 +0000405 {
406 /* increment destruction monitoring */
407 ptr->irefCount++;
408 return ptr;
409 }
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000410 if (IsWindow( hwnd )) /* check other processes */
411 {
Alexandre Julliardaff7dda2002-11-22 21:22:14 +0000412 ERR( "window %p belongs to other process\n", hwnd );
Alexandre Julliard8fd26b92001-10-15 17:56:45 +0000413 /* DbgBreakPoint(); */
414 }
Alexandre Julliard37a46392001-09-12 17:19:13 +0000415 }
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000416 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
Eric Pouechb9544f11999-02-14 14:09:42 +0000417 return NULL;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000418}
419
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000420
Francois Boisvert93e3f901999-02-25 17:32:31 +0000421/***********************************************************************
422 * WIN_ReleaseWndPtr
423 *
424 * Release the pointer to the WND structure.
425 */
426void WIN_ReleaseWndPtr(WND *wndPtr)
427{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000428 if(!wndPtr) return;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000429
Andreas Mohre15badb2001-10-21 15:18:15 +0000430 /* Decrement destruction monitoring value */
Francois Boisvert93e3f901999-02-25 17:32:31 +0000431 wndPtr->irefCount--;
Andreas Mohre15badb2001-10-21 15:18:15 +0000432 /* Check if it's time to release the memory */
Francois Boisvert86e2e111999-04-03 11:13:33 +0000433 if(wndPtr->irefCount == 0 && !wndPtr->dwMagic)
Francois Boisvert93e3f901999-02-25 17:32:31 +0000434 {
Francois Boisvert86e2e111999-04-03 11:13:33 +0000435 /* Release memory */
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000436 free_window_handle( wndPtr->hwndSelf );
Francois Boisvert93e3f901999-02-25 17:32:31 +0000437 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000438 else if(wndPtr->irefCount < 0)
439 {
440 /* This else if is useful to monitor the WIN_ReleaseWndPtr function */
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000441 ERR("forgot a Lock on %p somewhere\n",wndPtr);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000442 }
Andreas Mohre15badb2001-10-21 15:18:15 +0000443 /* unlock all WND structures for thread safeness */
Alexandre Julliard6837b9c2001-08-16 18:14:22 +0000444 USER_Unlock();
Francois Boisvert93e3f901999-02-25 17:32:31 +0000445}
446
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000447
448/***********************************************************************
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000449 * WIN_UnlinkWindow
450 *
451 * Remove a window from the siblings linked list.
452 */
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000453void WIN_UnlinkWindow( HWND hwnd )
454{
455 WIN_LinkWindow( hwnd, 0, 0 );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000456}
457
458
459/***********************************************************************
460 * WIN_LinkWindow
461 *
462 * Insert a window into the siblings linked list.
463 * The window is inserted after the specified window, which can also
464 * be specified as HWND_TOP or HWND_BOTTOM.
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000465 * If parent is 0, window is unlinked from the tree.
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000466 */
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000467void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter )
468{
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000469 WND *wndPtr = WIN_GetPtr( hwnd );
470
471 if (!wndPtr) return;
472 if (wndPtr == WND_OTHER_PROCESS)
473 {
Alexandre Julliardaff7dda2002-11-22 21:22:14 +0000474 if (IsWindow(hwnd)) ERR(" cannot link other process window %p\n", hwnd );
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000475 return;
476 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000477
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000478 SERVER_START_REQ( link_window )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000479 {
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000480 req->handle = hwnd;
481 req->parent = parent;
482 req->previous = hwndInsertAfter;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000483 if (!wine_server_call( req ))
Alexandre Julliardddc33172001-10-22 19:08:33 +0000484 {
Alexandre Julliard7dafa612002-09-25 00:21:56 +0000485 if (reply->full_parent) wndPtr->parent = reply->full_parent;
Alexandre Julliardddc33172001-10-22 19:08:33 +0000486 }
487
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000488 }
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000489 SERVER_END_REQ;
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000490 WIN_ReleasePtr( wndPtr );
491}
492
493
494/***********************************************************************
495 * WIN_SetOwner
496 *
497 * Change the owner of a window.
498 */
Alexandre Julliard7dafa612002-09-25 00:21:56 +0000499HWND WIN_SetOwner( HWND hwnd, HWND owner )
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000500{
Alexandre Julliardddc33172001-10-22 19:08:33 +0000501 WND *win = WIN_GetPtr( hwnd );
Alexandre Julliard7dafa612002-09-25 00:21:56 +0000502 HWND ret = 0;
Alexandre Julliardddc33172001-10-22 19:08:33 +0000503
Alexandre Julliard7dafa612002-09-25 00:21:56 +0000504 if (!win) return 0;
Alexandre Julliardddc33172001-10-22 19:08:33 +0000505 if (win == WND_OTHER_PROCESS)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000506 {
Alexandre Julliardaff7dda2002-11-22 21:22:14 +0000507 if (IsWindow(hwnd)) ERR( "cannot set owner %p on other process window %p\n", owner, hwnd );
Alexandre Julliard7dafa612002-09-25 00:21:56 +0000508 return 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000509 }
Alexandre Julliardddc33172001-10-22 19:08:33 +0000510 SERVER_START_REQ( set_window_owner )
511 {
512 req->handle = hwnd;
513 req->owner = owner;
Alexandre Julliard7dafa612002-09-25 00:21:56 +0000514 if (!wine_server_call( req ))
515 {
516 win->owner = reply->full_owner;
517 ret = reply->prev_owner;
518 }
Alexandre Julliardddc33172001-10-22 19:08:33 +0000519 }
520 SERVER_END_REQ;
521 WIN_ReleasePtr( win );
Alexandre Julliard7dafa612002-09-25 00:21:56 +0000522 return ret;
Alexandre Julliardddc33172001-10-22 19:08:33 +0000523}
524
525
526/***********************************************************************
527 * WIN_SetStyle
528 *
529 * Change the style of a window.
530 */
Alexandre Julliardf9364282005-01-21 10:32:13 +0000531ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits )
Alexandre Julliardddc33172001-10-22 19:08:33 +0000532{
533 BOOL ok;
Alexandre Julliardf9364282005-01-21 10:32:13 +0000534 ULONG new_style, old_style = 0;
Alexandre Julliardddc33172001-10-22 19:08:33 +0000535 WND *win = WIN_GetPtr( hwnd );
536
537 if (!win) return 0;
538 if (win == WND_OTHER_PROCESS)
539 {
540 if (IsWindow(hwnd))
Alexandre Julliardf9364282005-01-21 10:32:13 +0000541 ERR( "cannot set style %lx/%lx on other process window %p\n",
542 set_bits, clear_bits, hwnd );
Alexandre Julliardddc33172001-10-22 19:08:33 +0000543 return 0;
544 }
Alexandre Julliardf9364282005-01-21 10:32:13 +0000545 new_style = (win->dwStyle | set_bits) & ~clear_bits;
546 if (new_style == win->dwStyle)
Alexandre Julliardddc33172001-10-22 19:08:33 +0000547 {
548 WIN_ReleasePtr( win );
Alexandre Julliardf9364282005-01-21 10:32:13 +0000549 return new_style;
Alexandre Julliardddc33172001-10-22 19:08:33 +0000550 }
551 SERVER_START_REQ( set_window_info )
552 {
553 req->handle = hwnd;
554 req->flags = SET_WIN_STYLE;
Alexandre Julliardf9364282005-01-21 10:32:13 +0000555 req->style = new_style;
Alexandre Julliard97903d22003-11-26 22:15:41 +0000556 req->extra_offset = -1;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +0000557 if ((ok = !wine_server_call( req )))
Alexandre Julliardddc33172001-10-22 19:08:33 +0000558 {
Alexandre Julliardf9364282005-01-21 10:32:13 +0000559 old_style = reply->old_style;
560 win->dwStyle = new_style;
Alexandre Julliardddc33172001-10-22 19:08:33 +0000561 }
562 }
563 SERVER_END_REQ;
564 WIN_ReleasePtr( win );
Alexandre Julliardf9364282005-01-21 10:32:13 +0000565 if (ok && USER_Driver.pSetWindowStyle) USER_Driver.pSetWindowStyle( hwnd, old_style );
566 return old_style;
Alexandre Julliardddc33172001-10-22 19:08:33 +0000567}
568
569
570/***********************************************************************
Alexandre Julliard5797fbb2001-12-06 22:33:58 +0000571 * WIN_GetRectangles
572 *
573 * Get the window and client rectangles.
574 */
575BOOL WIN_GetRectangles( HWND hwnd, RECT *rectWindow, RECT *rectClient )
576{
577 WND *win = WIN_GetPtr( hwnd );
578 BOOL ret = TRUE;
579
580 if (!win) return FALSE;
581 if (win == WND_OTHER_PROCESS)
582 {
583 SERVER_START_REQ( get_window_rectangles )
584 {
585 req->handle = hwnd;
586 if ((ret = !wine_server_call( req )))
587 {
588 if (rectWindow)
589 {
590 rectWindow->left = reply->window.left;
591 rectWindow->top = reply->window.top;
592 rectWindow->right = reply->window.right;
593 rectWindow->bottom = reply->window.bottom;
594 }
595 if (rectClient)
596 {
597 rectClient->left = reply->client.left;
598 rectClient->top = reply->client.top;
599 rectClient->right = reply->client.right;
600 rectClient->bottom = reply->client.bottom;
601 }
602 }
603 }
604 SERVER_END_REQ;
605 }
606 else
607 {
608 if (rectWindow) *rectWindow = win->rectWindow;
609 if (rectClient) *rectClient = win->rectClient;
610 WIN_ReleasePtr( win );
611 }
612 return ret;
613}
614
615
616/***********************************************************************
Alexandre Julliardaca05781994-10-17 18:12:41 +0000617 * WIN_DestroyWindow
618 *
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000619 * Destroy storage associated to a window. "Internals" p.358
Alexandre Julliardaca05781994-10-17 18:12:41 +0000620 */
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000621LRESULT WIN_DestroyWindow( HWND hwnd )
Alexandre Julliardaca05781994-10-17 18:12:41 +0000622{
Alexandre Julliard80593bf2001-10-11 20:49:40 +0000623 WND *wndPtr;
624 HWND *list;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000625
Alexandre Julliardaff7dda2002-11-22 21:22:14 +0000626 TRACE("%p\n", hwnd );
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000627
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000628 if (!(hwnd = WIN_IsCurrentThread( hwnd )))
629 {
630 ERR( "window doesn't belong to current thread\n" );
631 return 0;
632 }
633
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000634 /* free child windows */
Alexandre Julliard80593bf2001-10-11 20:49:40 +0000635 if ((list = WIN_ListChildren( hwnd )))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000636 {
Alexandre Julliard80593bf2001-10-11 20:49:40 +0000637 int i;
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000638 for (i = 0; list[i]; i++)
639 {
640 if (WIN_IsCurrentThread( list[i] )) WIN_DestroyWindow( list[i] );
641 else SendMessageW( list[i], WM_WINE_DESTROYWINDOW, 0, 0 );
642 }
Alexandre Julliard80593bf2001-10-11 20:49:40 +0000643 HeapFree( GetProcessHeap(), 0, list );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000644 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000645
Francis Beaudet7c2f0fe1999-03-21 08:50:41 +0000646 /*
647 * Clear the update region to make sure no WM_PAINT messages will be
648 * generated for this window while processing the WM_NCDESTROY.
649 */
Alexandre Julliard80593bf2001-10-11 20:49:40 +0000650 RedrawWindow( hwnd, NULL, 0,
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000651 RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_NOCHILDREN);
Francis Beaudet7c2f0fe1999-03-21 08:50:41 +0000652
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +0000653 /* Unlink now so we won't bother with the children later on */
654 WIN_UnlinkWindow( hwnd );
655
Francis Beaudet7c2f0fe1999-03-21 08:50:41 +0000656 /*
657 * Send the WM_NCDESTROY to the window being destroyed.
658 */
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +0000659 SendMessageW( hwnd, WM_NCDESTROY, 0, 0 );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000660
661 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
662
Alexandre Julliardde424282001-08-10 22:51:42 +0000663 WINPOS_CheckInternalPos( hwnd );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000664
665 /* free resources associated with the window */
666
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000667 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000668
669 if (!(wndPtr->dwStyle & WS_CHILD))
Alexandre Julliardddc33172001-10-22 19:08:33 +0000670 {
Robert Shearmanbbdac5e2004-09-22 19:14:08 +0000671 HMENU menu = (HMENU)SetWindowLongPtrW( hwnd, GWLP_ID, 0 );
Alexandre Julliardddc33172001-10-22 19:08:33 +0000672 if (menu) DestroyMenu( menu );
673 }
Guy Albertelli38db0982000-05-11 00:06:38 +0000674 if (wndPtr->hSysMenu)
675 {
676 DestroyMenu( wndPtr->hSysMenu );
677 wndPtr->hSysMenu = 0;
678 }
Alexandre Julliard80593bf2001-10-11 20:49:40 +0000679 DCE_FreeWindowDCE( hwnd ); /* Always do this to catch orphaned DCs */
Dmitry Timoshkov57361112004-10-18 21:25:26 +0000680 if (USER_Driver.pDestroyWindow) USER_Driver.pDestroyWindow( hwnd );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000681 wndPtr->class = NULL;
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +0000682 wndPtr->dwMagic = 0; /* Mark it as invalid */
Alexandre Julliard80593bf2001-10-11 20:49:40 +0000683 WIN_ReleaseWndPtr( wndPtr );
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000684 return 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000685}
686
Alexandre Julliardaca05781994-10-17 18:12:41 +0000687/***********************************************************************
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000688 * WIN_DestroyThreadWindows
Alexandre Julliard77b99181997-09-14 17:17:23 +0000689 *
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000690 * Destroy all children of 'wnd' owned by the current thread.
Alexandre Julliard77b99181997-09-14 17:17:23 +0000691 * Return TRUE if something was done.
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000692 */
Alexandre Julliard0801ffc2001-08-24 00:26:59 +0000693void WIN_DestroyThreadWindows( HWND hwnd )
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000694{
Alexandre Julliard0801ffc2001-08-24 00:26:59 +0000695 HWND *list;
696 int i;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000697
Alexandre Julliard9d9dac02001-08-24 19:28:21 +0000698 if (!(list = WIN_ListChildren( hwnd ))) return;
Alexandre Julliard0801ffc2001-08-24 00:26:59 +0000699 for (i = 0; list[i]; i++)
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000700 {
Alexandre Julliard7695d692001-09-24 01:19:59 +0000701 if (WIN_IsCurrentThread( list[i] ))
Alexandre Julliard0801ffc2001-08-24 00:26:59 +0000702 DestroyWindow( list[i] );
703 else
704 WIN_DestroyThreadWindows( list[i] );
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000705 }
Alexandre Julliard9d9dac02001-08-24 19:28:21 +0000706 HeapFree( GetProcessHeap(), 0, list );
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000707}
708
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000709/***********************************************************************
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000710 * WIN_CreateDesktopWindow
711 *
712 * Create the desktop window.
713 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000714BOOL WIN_CreateDesktopWindow(void)
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000715{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000716 HWND hwndDesktop;
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000717 CREATESTRUCTA cs;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000718
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000719 TRACE("Creating desktop window\n");
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000720
Alexandre Julliardbfce1512003-12-10 04:08:06 +0000721 if (!WINPOS_CreateInternalPosAtom()) return FALSE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000722
Alexandre Julliardbfce1512003-12-10 04:08:06 +0000723 pWndDesktop = create_window_handle( 0, 0, LOWORD(DESKTOP_CLASS_ATOM), 0, WIN_PROC_32W );
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000724 if (!pWndDesktop) return FALSE;
725 hwndDesktop = pWndDesktop->hwndSelf;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000726
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000727 pWndDesktop->tid = 0; /* nobody owns the desktop */
Alexandre Julliard556607a2001-10-10 20:28:17 +0000728 pWndDesktop->parent = 0;
Alexandre Julliard9d9dac02001-08-24 19:28:21 +0000729 pWndDesktop->owner = 0;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000730 pWndDesktop->text = NULL;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000731 pWndDesktop->pVScroll = NULL;
732 pWndDesktop->pHScroll = NULL;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000733 pWndDesktop->helpContext = 0;
Alexandre Julliard26320d12001-03-23 23:45:45 +0000734 pWndDesktop->flags = 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000735 pWndDesktop->hSysMenu = 0;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000736
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000737 cs.lpCreateParams = NULL;
738 cs.hInstance = 0;
739 cs.hMenu = 0;
740 cs.hwndParent = 0;
741 cs.x = 0;
742 cs.y = 0;
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000743 cs.cx = GetSystemMetrics( SM_CXSCREEN );
744 cs.cy = GetSystemMetrics( SM_CYSCREEN );
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000745 cs.style = pWndDesktop->dwStyle;
746 cs.dwExStyle = pWndDesktop->dwExStyle;
747 cs.lpszName = NULL;
748 cs.lpszClass = DESKTOP_CLASS_ATOM;
Alexandre Julliard91222da2000-12-10 23:01:33 +0000749
Alexandre Julliard7dafa612002-09-25 00:21:56 +0000750 SERVER_START_REQ( set_window_info )
751 {
752 req->handle = hwndDesktop;
753 req->flags = 0; /* don't set anything, just retrieve */
Alexandre Julliard97903d22003-11-26 22:15:41 +0000754 req->extra_offset = -1;
Alexandre Julliard7dafa612002-09-25 00:21:56 +0000755 wine_server_call( req );
756 pWndDesktop->dwStyle = reply->old_style;
757 pWndDesktop->dwExStyle = reply->old_ex_style;
Alexandre Julliarda8a422f2002-11-22 20:43:01 +0000758 pWndDesktop->hInstance = (HINSTANCE)reply->old_instance;
Alexandre Julliard7dafa612002-09-25 00:21:56 +0000759 pWndDesktop->userdata = (ULONG_PTR)reply->old_user_data;
760 pWndDesktop->wIDmenu = reply->old_id;
761 }
762 SERVER_END_REQ;
Alexandre Julliardfb0ff052001-10-16 21:58:58 +0000763
Dmitry Timoshkov57361112004-10-18 21:25:26 +0000764 if (!USER_Driver.pCreateWindow || !USER_Driver.pCreateWindow( hwndDesktop, &cs, FALSE ))
Francois Gouget69e35002002-05-19 22:20:31 +0000765 {
766 WIN_ReleaseWndPtr( pWndDesktop );
767 return FALSE;
768 }
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000769
Alexandre Julliard1a66d222001-08-28 18:44:52 +0000770 WIN_ReleaseWndPtr( pWndDesktop );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000771 return TRUE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000772}
773
774
775/***********************************************************************
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000776 * WIN_FixCoordinates
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000777 *
Gerard Patel78f52b52000-05-31 19:23:20 +0000778 * Fix the coordinates - Helper for WIN_CreateWindowEx.
779 * returns default show mode in sw.
780 * Note: the feature presented as undocumented *is* in the MSDN since 1993.
781 */
782static void WIN_FixCoordinates( CREATESTRUCTA *cs, INT *sw)
783{
Dmitry Timoshkov21222772005-03-02 12:17:17 +0000784 POINT pos[2];
785
786 if (cs->dwExStyle & WS_EX_MDICHILD)
787 {
788 UINT id = 0;
789
790 MDI_CalcDefaultChildPos(cs->hwndParent, -1, pos, 0, &id);
791 if (!(cs->style & WS_POPUP)) cs->hMenu = (HMENU)id;
792
793 TRACE("MDI child id %04x\n", id);
794 }
795
Gerard Patel78f52b52000-05-31 19:23:20 +0000796 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16 ||
797 cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
798 {
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000799 if (cs->style & (WS_CHILD | WS_POPUP))
Gerard Patel78f52b52000-05-31 19:23:20 +0000800 {
Dmitry Timoshkovdc705532004-01-20 04:29:20 +0000801 if (cs->dwExStyle & WS_EX_MDICHILD)
802 {
Dmitry Timoshkovdc705532004-01-20 04:29:20 +0000803 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
804 {
805 cs->x = pos[0].x;
806 cs->y = pos[0].y;
807 }
808 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16 || !cs->cx)
809 cs->cx = pos[1].x;
810 if (cs->cy == CW_USEDEFAULT || cs->cy == CW_USEDEFAULT16 || !cs->cy)
811 cs->cy = pos[1].y;
812 }
813 else
814 {
815 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
816 cs->x = cs->y = 0;
817 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
818 cs->cx = cs->cy = 0;
819 }
Gerard Patel78f52b52000-05-31 19:23:20 +0000820 }
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000821 else /* overlapped window */
Gerard Patel78f52b52000-05-31 19:23:20 +0000822 {
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +0000823 STARTUPINFOW info;
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000824
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +0000825 GetStartupInfoW( &info );
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000826
827 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
828 {
Alexandre Julliard0d92fe22001-09-10 23:26:42 +0000829 /* Never believe Microsoft's documentation... CreateWindowEx doc says
830 * that if an overlapped window is created with WS_VISIBLE style bit
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000831 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
832 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
833 * reveals that
834 *
Alexandre Julliard0d92fe22001-09-10 23:26:42 +0000835 * 1) not only it checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
836 * 2) it does not ignore the y parameter as the docs claim; instead, it
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000837 * uses it as second parameter to ShowWindow() unless y is either
838 * CW_USEDEFAULT or CW_USEDEFAULT16.
Alexandre Julliard0d92fe22001-09-10 23:26:42 +0000839 *
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000840 * The fact that we didn't do 2) caused bogus windows pop up when wine
Alexandre Julliard0d92fe22001-09-10 23:26:42 +0000841 * was running apps that were using this obscure feature. Example -
842 * calc.exe that comes with Win98 (only Win98, it's different from
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000843 * the one that comes with Win95 and NT)
844 */
845 if (cs->y != CW_USEDEFAULT && cs->y != CW_USEDEFAULT16) *sw = cs->y;
846 cs->x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
847 cs->y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
848 }
849
850 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
851 {
852 if (info.dwFlags & STARTF_USESIZE)
853 {
854 cs->cx = info.dwXSize;
855 cs->cy = info.dwYSize;
856 }
857 else /* if no other hint from the app, pick 3/4 of the screen real estate */
858 {
859 RECT r;
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +0000860 SystemParametersInfoW( SPI_GETWORKAREA, 0, &r, 0);
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000861 cs->cx = (((r.right - r.left) * 3) / 4) - cs->x;
862 cs->cy = (((r.bottom - r.top) * 3) / 4) - cs->y;
863 }
864 }
Ulrich Czekalla03ffadc2005-01-19 20:54:25 +0000865 /* Handle case where only the cy values is set to default */
866 else if (cs->cy == CW_USEDEFAULT || cs->cy == CW_USEDEFAULT16)
867 {
868 RECT r;
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +0000869 SystemParametersInfoW( SPI_GETWORKAREA, 0, &r, 0);
Ulrich Czekalla03ffadc2005-01-19 20:54:25 +0000870 cs->cy = (((r.bottom - r.top) * 3) / 4) - cs->y;
871 }
Gerard Patel78f52b52000-05-31 19:23:20 +0000872 }
873 }
Guy L. Albertellif1a624d2002-02-27 01:20:54 +0000874 else
875 {
876 /* neither x nor cx are default. Check the y values .
Vincent Béron9a624912002-05-31 23:06:46 +0000877 * In the trace we see Outlook and Outlook Express using
Guy L. Albertellif1a624d2002-02-27 01:20:54 +0000878 * cy set to CW_USEDEFAULT when opening the address book.
879 */
880 if (cs->cy == CW_USEDEFAULT || cs->cy == CW_USEDEFAULT16) {
881 RECT r;
882 FIXME("Strange use of CW_USEDEFAULT in nHeight\n");
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +0000883 SystemParametersInfoW( SPI_GETWORKAREA, 0, &r, 0);
Guy L. Albertellif1a624d2002-02-27 01:20:54 +0000884 cs->cy = (((r.bottom - r.top) * 3) / 4) - cs->y;
885 }
886 }
Gerard Patel78f52b52000-05-31 19:23:20 +0000887}
888
889/***********************************************************************
Dmitry Timoshkov5d3e1f72001-11-07 21:52:24 +0000890 * dump_window_styles
891 */
892static void dump_window_styles( DWORD style, DWORD exstyle )
893{
894 TRACE( "style:" );
Tony Lambregts7ce3a5a2003-03-14 04:11:17 +0000895 if(style & WS_POPUP) TRACE(" WS_POPUP");
896 if(style & WS_CHILD) TRACE(" WS_CHILD");
897 if(style & WS_MINIMIZE) TRACE(" WS_MINIMIZE");
898 if(style & WS_VISIBLE) TRACE(" WS_VISIBLE");
899 if(style & WS_DISABLED) TRACE(" WS_DISABLED");
900 if(style & WS_CLIPSIBLINGS) TRACE(" WS_CLIPSIBLINGS");
901 if(style & WS_CLIPCHILDREN) TRACE(" WS_CLIPCHILDREN");
902 if(style & WS_MAXIMIZE) TRACE(" WS_MAXIMIZE");
903 if((style & WS_CAPTION) == WS_CAPTION) TRACE(" WS_CAPTION");
Dmitry Timoshkov5d3e1f72001-11-07 21:52:24 +0000904 else
905 {
Tony Lambregts7ce3a5a2003-03-14 04:11:17 +0000906 if(style & WS_BORDER) TRACE(" WS_BORDER");
907 if(style & WS_DLGFRAME) TRACE(" WS_DLGFRAME");
Dmitry Timoshkov5d3e1f72001-11-07 21:52:24 +0000908 }
Tony Lambregts7ce3a5a2003-03-14 04:11:17 +0000909 if(style & WS_VSCROLL) TRACE(" WS_VSCROLL");
910 if(style & WS_HSCROLL) TRACE(" WS_HSCROLL");
911 if(style & WS_SYSMENU) TRACE(" WS_SYSMENU");
912 if(style & WS_THICKFRAME) TRACE(" WS_THICKFRAME");
913 if(style & WS_GROUP) TRACE(" WS_GROUP");
914 if(style & WS_TABSTOP) TRACE(" WS_TABSTOP");
915 if(style & WS_MINIMIZEBOX) TRACE(" WS_MINIMIZEBOX");
916 if(style & WS_MAXIMIZEBOX) TRACE(" WS_MAXIMIZEBOX");
Dmitry Timoshkov5d3e1f72001-11-07 21:52:24 +0000917
918 /* FIXME: Add dumping of BS_/ES_/SBS_/LBS_/CBS_/DS_/etc. styles */
919#define DUMPED_STYLES \
920 (WS_POPUP | \
921 WS_CHILD | \
922 WS_MINIMIZE | \
923 WS_VISIBLE | \
924 WS_DISABLED | \
925 WS_CLIPSIBLINGS | \
926 WS_CLIPCHILDREN | \
927 WS_MAXIMIZE | \
928 WS_BORDER | \
929 WS_DLGFRAME | \
930 WS_VSCROLL | \
931 WS_HSCROLL | \
932 WS_SYSMENU | \
933 WS_THICKFRAME | \
934 WS_GROUP | \
935 WS_TABSTOP | \
936 WS_MINIMIZEBOX | \
937 WS_MAXIMIZEBOX)
938
Tony Lambregts7ce3a5a2003-03-14 04:11:17 +0000939 if(style & ~DUMPED_STYLES) TRACE(" %08lx", style & ~DUMPED_STYLES);
940 TRACE("\n");
Dmitry Timoshkov5d3e1f72001-11-07 21:52:24 +0000941#undef DUMPED_STYLES
942
943 TRACE( "exstyle:" );
Tony Lambregts7ce3a5a2003-03-14 04:11:17 +0000944 if(exstyle & WS_EX_DLGMODALFRAME) TRACE(" WS_EX_DLGMODALFRAME");
945 if(exstyle & WS_EX_DRAGDETECT) TRACE(" WS_EX_DRAGDETECT");
946 if(exstyle & WS_EX_NOPARENTNOTIFY) TRACE(" WS_EX_NOPARENTNOTIFY");
947 if(exstyle & WS_EX_TOPMOST) TRACE(" WS_EX_TOPMOST");
948 if(exstyle & WS_EX_ACCEPTFILES) TRACE(" WS_EX_ACCEPTFILES");
949 if(exstyle & WS_EX_TRANSPARENT) TRACE(" WS_EX_TRANSPARENT");
950 if(exstyle & WS_EX_MDICHILD) TRACE(" WS_EX_MDICHILD");
951 if(exstyle & WS_EX_TOOLWINDOW) TRACE(" WS_EX_TOOLWINDOW");
952 if(exstyle & WS_EX_WINDOWEDGE) TRACE(" WS_EX_WINDOWEDGE");
953 if(exstyle & WS_EX_CLIENTEDGE) TRACE(" WS_EX_CLIENTEDGE");
954 if(exstyle & WS_EX_CONTEXTHELP) TRACE(" WS_EX_CONTEXTHELP");
955 if(exstyle & WS_EX_RIGHT) TRACE(" WS_EX_RIGHT");
956 if(exstyle & WS_EX_RTLREADING) TRACE(" WS_EX_RTLREADING");
957 if(exstyle & WS_EX_LEFTSCROLLBAR) TRACE(" WS_EX_LEFTSCROLLBAR");
958 if(exstyle & WS_EX_CONTROLPARENT) TRACE(" WS_EX_CONTROLPARENT");
959 if(exstyle & WS_EX_STATICEDGE) TRACE(" WS_EX_STATICEDGE");
960 if(exstyle & WS_EX_APPWINDOW) TRACE(" WS_EX_APPWINDOW");
961 if(exstyle & WS_EX_LAYERED) TRACE(" WS_EX_LAYERED");
Dmitry Timoshkov5d3e1f72001-11-07 21:52:24 +0000962
963#define DUMPED_EX_STYLES \
964 (WS_EX_DLGMODALFRAME | \
965 WS_EX_DRAGDETECT | \
966 WS_EX_NOPARENTNOTIFY | \
967 WS_EX_TOPMOST | \
968 WS_EX_ACCEPTFILES | \
969 WS_EX_TRANSPARENT | \
970 WS_EX_MDICHILD | \
971 WS_EX_TOOLWINDOW | \
972 WS_EX_WINDOWEDGE | \
973 WS_EX_CLIENTEDGE | \
974 WS_EX_CONTEXTHELP | \
975 WS_EX_RIGHT | \
976 WS_EX_RTLREADING | \
977 WS_EX_LEFTSCROLLBAR | \
978 WS_EX_CONTROLPARENT | \
979 WS_EX_STATICEDGE | \
980 WS_EX_APPWINDOW | \
981 WS_EX_LAYERED)
982
Tony Lambregts7ce3a5a2003-03-14 04:11:17 +0000983 if(exstyle & ~DUMPED_EX_STYLES) TRACE(" %08lx", exstyle & ~DUMPED_EX_STYLES);
984 TRACE("\n");
Dmitry Timoshkov5d3e1f72001-11-07 21:52:24 +0000985#undef DUMPED_EX_STYLES
986}
987
988
989/***********************************************************************
Gerard Patel78f52b52000-05-31 19:23:20 +0000990 * WIN_CreateWindowEx
991 *
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000992 * Implementation of CreateWindowEx().
Alexandre Julliard401710d1993-09-04 10:09:32 +0000993 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000994static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000995 WINDOWPROCTYPE type )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000996{
Alexandre Julliard0d92fe22001-09-10 23:26:42 +0000997 INT sw = SW_SHOW;
Alexandre Julliardd2e1c1a1996-03-09 16:12:43 +0000998 WND *wndPtr;
Dmitry Timoshkovdc705532004-01-20 04:29:20 +0000999 HWND hwnd, parent, owner, top_child = 0;
Gerard Patelad363032001-06-06 21:26:50 +00001000 BOOL unicode = (type == WIN_PROC_32W);
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001001
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00001002 TRACE("%s %s ex=%08lx style=%08lx %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n",
Alexandre Julliard0aa28b52002-05-17 02:55:48 +00001003 (type == WIN_PROC_32W) ? debugstr_w((LPWSTR)cs->lpszName) : debugstr_a(cs->lpszName),
1004 (type == WIN_PROC_32W) ? debugstr_w((LPWSTR)cs->lpszClass) : debugstr_a(cs->lpszClass),
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001005 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
1006 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
Alexandre Julliard401710d1993-09-04 10:09:32 +00001007
Dmitry Timoshkov5d3e1f72001-11-07 21:52:24 +00001008 if(TRACE_ON(win)) dump_window_styles( cs->style, cs->dwExStyle );
1009
Dmitry Timoshkov5956b982000-11-28 23:53:08 +00001010 TRACE("winproc type is %d (%s)\n", type, (type == WIN_PROC_16) ? "WIN_PROC_16" :
1011 ((type == WIN_PROC_32A) ? "WIN_PROC_32A" : "WIN_PROC_32W") );
1012
Dmitry Timoshkovdc705532004-01-20 04:29:20 +00001013 /* Fix the styles for MDI children */
1014 if (cs->dwExStyle & WS_EX_MDICHILD)
1015 {
1016 MDICREATESTRUCTA mdi_cs;
1017 UINT flags = 0;
1018
1019 wndPtr = WIN_GetPtr(cs->hwndParent);
1020 if (wndPtr && wndPtr != WND_OTHER_PROCESS)
1021 {
1022 flags = wndPtr->flags;
1023 WIN_ReleasePtr(wndPtr);
1024 }
1025
1026 if (!(flags & WIN_ISMDICLIENT))
1027 {
1028 WARN("WS_EX_MDICHILD, but parent %p is not MDIClient\n", cs->hwndParent);
1029 return 0;
1030 }
1031
1032 /* cs->lpCreateParams of WM_[NC]CREATE is different for MDI children.
1033 * MDICREATESTRUCT members have the originally passed values.
1034 *
1035 * Note: we rely on the fact that MDICREATESTRUCTA and MDICREATESTRUCTW
1036 * have the same layout.
1037 */
1038 mdi_cs.szClass = cs->lpszClass;
1039 mdi_cs.szTitle = cs->lpszName;
1040 mdi_cs.hOwner = cs->hInstance;
1041 mdi_cs.x = cs->x;
1042 mdi_cs.y = cs->y;
1043 mdi_cs.cx = cs->cx;
1044 mdi_cs.cy = cs->cy;
1045 mdi_cs.style = cs->style;
1046 mdi_cs.lParam = (LPARAM)cs->lpCreateParams;
1047
1048 cs->lpCreateParams = (LPVOID)&mdi_cs;
1049
1050 if (GetWindowLongW(cs->hwndParent, GWL_STYLE) & MDIS_ALLCHILDSTYLES)
1051 {
1052 if (cs->style & WS_POPUP)
1053 {
1054 TRACE("WS_POPUP with MDIS_ALLCHILDSTYLES is not allowed\n");
1055 return 0;
1056 }
1057 cs->style |= WS_CHILD | WS_CLIPSIBLINGS;
1058 }
1059 else
1060 {
1061 cs->style &= ~WS_POPUP;
1062 cs->style |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION |
1063 WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
1064 }
1065
1066 top_child = GetWindow(cs->hwndParent, GW_CHILD);
Dmitry Timoshkova1ccb922004-09-21 00:24:22 +00001067
1068 if (top_child)
1069 {
1070 /* Restore current maximized child */
1071 if((cs->style & WS_VISIBLE) && IsZoomed(top_child))
1072 {
1073 TRACE("Restoring current maximized child %p\n", top_child);
1074 SendMessageW( top_child, WM_SETREDRAW, FALSE, 0 );
1075 ShowWindow(top_child, SW_RESTORE);
1076 SendMessageW( top_child, WM_SETREDRAW, TRUE, 0 );
1077 }
1078 }
Dmitry Timoshkovdc705532004-01-20 04:29:20 +00001079 }
1080
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001081 /* Find the parent window */
Alexandre Julliard401710d1993-09-04 10:09:32 +00001082
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00001083 parent = GetDesktopWindow();
1084 owner = 0;
Juergen Schmiedeb2db1a2002-08-29 01:49:46 +00001085
1086 if (cs->hwndParent == HWND_MESSAGE)
1087 {
1088 /* native ole32.OleInitialize uses HWND_MESSAGE to create the
1089 * message window (style: WS_POPUP|WS_DISABLED)
1090 */
1091 FIXME("Parent is HWND_MESSAGE\n");
1092 }
1093 else if (cs->hwndParent)
Alexandre Julliard401710d1993-09-04 10:09:32 +00001094 {
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +00001095 /* Make sure parent is valid */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001096 if (!IsWindow( cs->hwndParent ))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001097 {
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00001098 WARN("Bad parent %p\n", cs->hwndParent );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +00001099 return 0;
Alexandre Julliardfa68b751995-04-03 16:55:37 +00001100 }
Alexandre Julliard7dafa612002-09-25 00:21:56 +00001101 if ((cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
1102 parent = WIN_GetFullHandle(cs->hwndParent);
1103 else
1104 owner = GetAncestor( cs->hwndParent, GA_ROOT );
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00001105 }
Alexandre Julliard7dafa612002-09-25 00:21:56 +00001106 else if ((cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00001107 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001108 WARN("No parent for child window\n" );
Alexandre Julliard3db94ef1997-09-28 17:43:24 +00001109 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +00001110 }
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001111
Gerard Patel78f52b52000-05-31 19:23:20 +00001112 WIN_FixCoordinates(cs, &sw); /* fix default coordinates */
Alexandre Julliardcdd09231994-01-12 11:12:51 +00001113
Bill Medland3f68bc92001-07-20 18:36:25 +00001114 if ((cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
1115 ((!(cs->dwExStyle & WS_EX_STATICEDGE)) &&
1116 (cs->style & (WS_DLGFRAME | WS_THICKFRAME))))
1117 cs->dwExStyle |= WS_EX_WINDOWEDGE;
1118 else
1119 cs->dwExStyle &= ~WS_EX_WINDOWEDGE;
1120
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001121 /* Create the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +00001122
Alexandre Julliardbfce1512003-12-10 04:08:06 +00001123 if (!(wndPtr = create_window_handle( parent, owner, classAtom, cs->hInstance, type )))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001124 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001125 TRACE("out of memory\n" );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +00001126 return 0;
1127 }
Alexandre Julliard1a66d222001-08-28 18:44:52 +00001128 hwnd = wndPtr->hwndSelf;
Alexandre Julliard401710d1993-09-04 10:09:32 +00001129
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001130 /* Fill the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +00001131
Alexandre Julliard80593bf2001-10-11 20:49:40 +00001132 wndPtr->tid = GetCurrentThreadId();
1133 wndPtr->owner = owner;
Alexandre Julliard556607a2001-10-10 20:28:17 +00001134 wndPtr->parent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001135 wndPtr->hInstance = cs->hInstance;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001136 wndPtr->text = NULL;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001137 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
1138 wndPtr->dwExStyle = cs->dwExStyle;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +00001139 wndPtr->wIDmenu = 0;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00001140 wndPtr->helpContext = 0;
Dmitry Timoshkov5956b982000-11-28 23:53:08 +00001141 wndPtr->flags = (type == WIN_PROC_16) ? 0 : WIN_ISWIN32;
Alexandre Julliardca22b331996-07-12 19:02:39 +00001142 wndPtr->pVScroll = NULL;
1143 wndPtr->pHScroll = NULL;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001144 wndPtr->userdata = 0;
Alexandre Julliard446d8322003-12-31 23:51:52 +00001145 wndPtr->hIcon = 0;
1146 wndPtr->hIconSmall = 0;
Michael Stefaniucec5612e2002-10-30 23:45:38 +00001147 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU) ? MENU_GetSysMenu( hwnd, 0 ) : 0;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001148
Robert Shearmancaec6022005-03-23 10:26:15 +00001149 /*
1150 * Correct the window styles.
1151 *
1152 * It affects only the style loaded into the WIN structure.
1153 */
1154
1155 if (!(wndPtr->dwStyle & WS_CHILD))
1156 {
1157 wndPtr->dwStyle |= WS_CLIPSIBLINGS;
1158 if (!(wndPtr->dwStyle & WS_POPUP))
1159 wndPtr->dwStyle |= WS_CAPTION;
1160 }
1161
1162 /*
1163 * WS_EX_WINDOWEDGE appears to be enforced based on the other styles, so
1164 * why does the user get to set it?
1165 */
1166
1167 if ((wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) ||
1168 (wndPtr->dwStyle & (WS_DLGFRAME | WS_THICKFRAME)))
1169 wndPtr->dwExStyle |= WS_EX_WINDOWEDGE;
1170 else
1171 wndPtr->dwExStyle &= ~WS_EX_WINDOWEDGE;
1172
1173 if (!(wndPtr->dwStyle & (WS_CHILD | WS_POPUP)))
Dmitry Timoshkov9b24af82004-02-06 05:18:56 +00001174 wndPtr->flags |= WIN_NEED_SIZE;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001175
Alexandre Julliardddc33172001-10-22 19:08:33 +00001176 SERVER_START_REQ( set_window_info )
1177 {
1178 req->handle = hwnd;
1179 req->flags = SET_WIN_STYLE | SET_WIN_EXSTYLE | SET_WIN_INSTANCE;
1180 req->style = wndPtr->dwStyle;
1181 req->ex_style = wndPtr->dwExStyle;
1182 req->instance = (void *)wndPtr->hInstance;
Alexandre Julliard97903d22003-11-26 22:15:41 +00001183 req->extra_offset = -1;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00001184 wine_server_call( req );
Alexandre Julliardddc33172001-10-22 19:08:33 +00001185 }
1186 SERVER_END_REQ;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001187
1188 /* Get class or window DC if needed */
Alexandre Julliardaca05781994-10-17 18:12:41 +00001189
Alexandre Julliardbfce1512003-12-10 04:08:06 +00001190 if (wndPtr->clsStyle & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001191
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001192 /* Set the window menu */
1193
Duane Clark632d0c22003-01-08 19:53:47 +00001194 if (((wndPtr->dwStyle & (WS_CAPTION|WS_CHILD)) == WS_CAPTION) ||
1195 (wndPtr->dwExStyle & WS_EX_APPWINDOW))
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001196 {
Huw Davies14743a02004-02-17 20:29:05 +00001197 if (cs->hMenu) MENU_SetMenu(hwnd, cs->hMenu);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001198 else
1199 {
Dmitry Timoshkov39f960b2005-02-15 21:51:06 +00001200 LPCSTR menuName = (LPCSTR)GetClassLongPtrA( hwnd, GCLP_MENUNAME );
Alexandre Julliard54c27111998-03-29 19:44:57 +00001201 if (menuName)
1202 {
Ulrich Weigand7df1fbb1998-11-01 18:01:53 +00001203 if (HIWORD(cs->hInstance))
Alexandre Julliardac7efef2000-11-27 21:54:01 +00001204 cs->hMenu = LoadMenuA(cs->hInstance,menuName);
Alexandre Julliard54c27111998-03-29 19:44:57 +00001205 else
Alexandre Julliarda8a422f2002-11-22 20:43:01 +00001206 cs->hMenu = HMENU_32(LoadMenu16(HINSTANCE_16(cs->hInstance),menuName));
Alexandre Julliard54c27111998-03-29 19:44:57 +00001207
Huw Davies14743a02004-02-17 20:29:05 +00001208 if (cs->hMenu) MENU_SetMenu( hwnd, cs->hMenu );
Alexandre Julliard54c27111998-03-29 19:44:57 +00001209 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001210 }
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001211 }
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00001212 else SetWindowLongPtrW( hwnd, GWLP_ID, (ULONG_PTR)cs->hMenu );
Alexandre Julliardddc33172001-10-22 19:08:33 +00001213 WIN_ReleaseWndPtr( wndPtr );
Alexandre Julliard490a27e1994-06-08 13:57:50 +00001214
Dmitry Timoshkov57361112004-10-18 21:25:26 +00001215 if (!USER_Driver.pCreateWindow || !USER_Driver.pCreateWindow( hwnd, cs, unicode))
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001216 {
Alexandre Julliard80593bf2001-10-11 20:49:40 +00001217 WIN_DestroyWindow( hwnd );
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001218 return 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001219 }
Alexandre Julliard401710d1993-09-04 10:09:32 +00001220
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001221 /* Notify the parent window only */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001222
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001223 send_parent_notify( hwnd, WM_CREATE );
Alexandre Julliardddc33172001-10-22 19:08:33 +00001224 if (!IsWindow( hwnd )) return 0;
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001225
1226 if (cs->style & WS_VISIBLE)
Dmitry Timoshkova1ccb922004-09-21 00:24:22 +00001227 {
1228 if (cs->style & WS_MAXIMIZE)
1229 sw = SW_SHOWMAXIMIZED;
1230 else if (cs->style & WS_MINIMIZE)
1231 sw = SW_SHOWMINIMIZED;
1232
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001233 ShowWindow( hwnd, sw );
Dmitry Timoshkova1ccb922004-09-21 00:24:22 +00001234 if (cs->dwExStyle & WS_EX_MDICHILD)
1235 {
1236 SendMessageW(cs->hwndParent, WM_MDIREFRESHMENU, 0, 0);
1237 /* ShowWindow won't activate child windows */
1238 SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE );
1239 }
1240 }
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001241
1242 /* Call WH_SHELL hook */
1243
Alexandre Julliardddc33172001-10-22 19:08:33 +00001244 if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) && !GetWindow( hwnd, GW_OWNER ))
Alexandre Julliard02861352002-10-29 00:41:42 +00001245 HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWCREATED, (WPARAM)hwnd, 0, TRUE );
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001246
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00001247 TRACE("created window %p\n", hwnd);
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00001248 return hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001249}
1250
1251
1252/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001253 * CreateWindow (USER.41)
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001254 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001255HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
1256 DWORD style, INT16 x, INT16 y, INT16 width,
1257 INT16 height, HWND16 parent, HMENU16 menu,
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00001258 HINSTANCE16 instance, LPVOID data )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001259{
1260 return CreateWindowEx16( 0, className, windowName, style,
1261 x, y, width, height, parent, menu, instance, data );
1262}
1263
1264
1265/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001266 * CreateWindowEx (USER.452)
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001267 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001268HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
1269 LPCSTR windowName, DWORD style, INT16 x,
1270 INT16 y, INT16 width, INT16 height,
1271 HWND16 parent, HMENU16 menu,
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00001272 HINSTANCE16 instance, LPVOID data )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001273{
1274 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001275 CREATESTRUCTA cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001276 char buffer[256];
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001277
1278 /* Find the class atom */
1279
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001280 if (HIWORD(className))
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001281 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001282 if (!(classAtom = GlobalFindAtomA( className )))
1283 {
Alexandre Julliard0aa28b52002-05-17 02:55:48 +00001284 ERR( "bad class name %s\n", debugstr_a(className) );
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001285 return 0;
1286 }
1287 }
1288 else
1289 {
1290 classAtom = LOWORD(className);
1291 if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
1292 {
1293 ERR( "bad atom %x\n", classAtom);
1294 return 0;
1295 }
1296 className = buffer;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001297 }
1298
1299 /* Fix the coordinates */
1300
Alexandre Julliarda3960291999-02-26 11:11:13 +00001301 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)x;
1302 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)y;
1303 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)width;
1304 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)height;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001305
1306 /* Create the window */
1307
1308 cs.lpCreateParams = data;
Alexandre Julliarda8a422f2002-11-22 20:43:01 +00001309 cs.hInstance = HINSTANCE_32(instance);
Michael Stefaniucec5612e2002-10-30 23:45:38 +00001310 cs.hMenu = HMENU_32(menu);
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00001311 cs.hwndParent = WIN_Handle32( parent );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001312 cs.style = style;
1313 cs.lpszName = windowName;
1314 cs.lpszClass = className;
1315 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001316
Michael Stefaniuc2247af32002-09-04 19:37:01 +00001317 return HWND_16( WIN_CreateWindowEx( &cs, classAtom, WIN_PROC_16 ));
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001318}
1319
1320
1321/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001322 * CreateWindowExA (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001323 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001324HWND WINAPI CreateWindowExA( DWORD exStyle, LPCSTR className,
1325 LPCSTR windowName, DWORD style, INT x,
1326 INT y, INT width, INT height,
1327 HWND parent, HMENU menu,
1328 HINSTANCE instance, LPVOID data )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001329{
1330 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001331 CREATESTRUCTA cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001332 char buffer[256];
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001333
1334 /* Find the class atom */
1335
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001336 if (HIWORD(className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001337 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001338 if (!(classAtom = GlobalFindAtomA( className )))
1339 {
Alexandre Julliard0aa28b52002-05-17 02:55:48 +00001340 ERR( "bad class name %s\n", debugstr_a(className) );
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001341 return 0;
1342 }
1343 }
1344 else
1345 {
1346 classAtom = LOWORD(className);
1347 if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
1348 {
1349 ERR( "bad atom %x\n", classAtom);
1350 return 0;
1351 }
1352 className = buffer;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001353 }
1354
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001355 /* Create the window */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001356
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001357 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001358 cs.hInstance = instance;
1359 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001360 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001361 cs.x = x;
1362 cs.y = y;
1363 cs.cx = width;
1364 cs.cy = height;
1365 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001366 cs.lpszName = windowName;
1367 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001368 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001369
Dmitry Timoshkov5956b982000-11-28 23:53:08 +00001370 return WIN_CreateWindowEx( &cs, classAtom, WIN_PROC_32A );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001371}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001372
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001373
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001374/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001375 * CreateWindowExW (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001376 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001377HWND WINAPI CreateWindowExW( DWORD exStyle, LPCWSTR className,
1378 LPCWSTR windowName, DWORD style, INT x,
1379 INT y, INT width, INT height,
1380 HWND parent, HMENU menu,
1381 HINSTANCE instance, LPVOID data )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001382{
1383 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001384 CREATESTRUCTW cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001385 WCHAR buffer[256];
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001386
1387 /* Find the class atom */
1388
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001389 if (HIWORD(className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001390 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001391 if (!(classAtom = GlobalFindAtomW( className )))
1392 {
Alexandre Julliard0aa28b52002-05-17 02:55:48 +00001393 ERR( "bad class name %s\n", debugstr_w(className) );
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001394 return 0;
1395 }
1396 }
1397 else
1398 {
1399 classAtom = LOWORD(className);
1400 if (!GlobalGetAtomNameW( classAtom, buffer, sizeof(buffer)/sizeof(WCHAR) ))
1401 {
1402 ERR( "bad atom %x\n", classAtom);
1403 return 0;
1404 }
1405 className = buffer;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001406 }
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001407
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001408 /* Create the window */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001409
1410 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001411 cs.hInstance = instance;
1412 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001413 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001414 cs.x = x;
1415 cs.y = y;
1416 cs.cx = width;
1417 cs.cy = height;
1418 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001419 cs.lpszName = windowName;
1420 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001421 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001422
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001423 /* Note: we rely on the fact that CREATESTRUCTA and */
1424 /* CREATESTRUCTW have the same layout. */
Dmitry Timoshkov5956b982000-11-28 23:53:08 +00001425 return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, classAtom, WIN_PROC_32W );
Alexandre Julliard401710d1993-09-04 10:09:32 +00001426}
1427
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001428
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001429/***********************************************************************
1430 * WIN_SendDestroyMsg
1431 */
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001432static void WIN_SendDestroyMsg( HWND hwnd )
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001433{
Alexandre Julliard11e35232002-10-17 01:24:33 +00001434 GUITHREADINFO info;
1435
1436 if (GetGUIThreadInfo( GetCurrentThreadId(), &info ))
1437 {
1438 if (hwnd == info.hwndCaret) DestroyCaret();
Dmitry Timoshkovf2616c52004-05-18 00:48:52 +00001439 if (hwnd == info.hwndActive) WINPOS_ActivateOtherWindow( hwnd );
Alexandre Julliard11e35232002-10-17 01:24:33 +00001440 }
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00001441 if (USER_Driver.pResetSelectionOwner)
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001442 USER_Driver.pResetSelectionOwner( hwnd, TRUE );
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001443
1444 /*
1445 * Send the WM_DESTROY to the window.
1446 */
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +00001447 SendMessageW( hwnd, WM_DESTROY, 0, 0);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001448
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001449 /*
1450 * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
1451 * make sure that the window still exists when we come back.
1452 */
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001453 if (IsWindow(hwnd))
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001454 {
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001455 HWND* pWndArray;
1456 int i;
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001457
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00001458 if (!(pWndArray = WIN_ListChildren( hwnd ))) return;
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001459
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +00001460 for (i = 0; pWndArray[i]; i++)
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001461 {
1462 if (IsWindow( pWndArray[i] )) WIN_SendDestroyMsg( pWndArray[i] );
1463 }
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00001464 HeapFree( GetProcessHeap(), 0, pWndArray );
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001465 }
1466 else
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001467 WARN("\tdestroyed itself while in WM_DESTROY!\n");
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001468}
1469
1470
1471/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001472 * DestroyWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001473 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001474BOOL WINAPI DestroyWindow( HWND hwnd )
Alexandre Julliard401710d1993-09-04 10:09:32 +00001475{
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001476 BOOL is_child;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00001477
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001478 if (!(hwnd = WIN_IsCurrentThread( hwnd )) || (hwnd == GetDesktopWindow()))
1479 {
1480 SetLastError( ERROR_ACCESS_DENIED );
1481 return FALSE;
1482 }
1483
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00001484 TRACE("(%p)\n", hwnd);
Alexandre Julliard1f029ea2000-11-02 20:08:59 +00001485
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001486 /* Call hooks */
1487
Alexandre Julliard02861352002-10-29 00:41:42 +00001488 if (HOOK_CallHooks( WH_CBT, HCBT_DESTROYWND, (WPARAM)hwnd, 0, TRUE )) return FALSE;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001489
Dmitry Timoshkov2abf2c72004-09-20 21:45:45 +00001490 if (MENU_IsMenuActive() == hwnd)
1491 EndMenu();
1492
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001493 is_child = (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) != 0;
1494
1495 if (is_child)
1496 {
1497 if (!USER_IsExitingThread( GetCurrentThreadId() ))
1498 send_parent_notify( hwnd, WM_DESTROY );
1499 }
1500 else if (!GetWindow( hwnd, GW_OWNER ))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001501 {
Alexandre Julliard02861352002-10-29 00:41:42 +00001502 HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L, TRUE );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001503 /* FIXME: clean up palette - see "Internals" p.352 */
1504 }
1505
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001506 if (!IsWindow(hwnd)) return TRUE;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001507
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00001508 if (USER_Driver.pResetSelectionOwner)
1509 USER_Driver.pResetSelectionOwner( hwnd, FALSE ); /* before the window is unmapped */
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001510
Alexandre Julliard58199531994-04-21 01:20:00 +00001511 /* Hide the window */
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +00001512 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)
1513 {
1514 /* Only child windows receive WM_SHOWWINDOW in DestroyWindow() */
1515 if (is_child)
1516 ShowWindow( hwnd, SW_HIDE );
1517 else
1518 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
1519 SWP_NOZORDER | SWP_NOACTIVATE | SWP_HIDEWINDOW );
1520 }
Dmitry Timoshkovf2616c52004-05-18 00:48:52 +00001521
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001522 if (!IsWindow(hwnd)) return TRUE;
Alexandre Julliard0e607781993-11-03 19:23:37 +00001523
Alexandre Julliard22945d51995-03-02 17:44:29 +00001524 /* Recursively destroy owned windows */
1525
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001526 if (!is_child)
Alexandre Julliard22945d51995-03-02 17:44:29 +00001527 {
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001528 for (;;)
1529 {
1530 int i, got_one = 0;
1531 HWND *list = WIN_ListChildren( GetDesktopWindow() );
1532 if (list)
1533 {
1534 for (i = 0; list[i]; i++)
1535 {
1536 if (GetWindow( list[i], GW_OWNER ) != hwnd) continue;
1537 if (WIN_IsCurrentThread( list[i] ))
1538 {
1539 DestroyWindow( list[i] );
1540 got_one = 1;
1541 continue;
1542 }
1543 WIN_SetOwner( list[i], 0 );
1544 }
1545 HeapFree( GetProcessHeap(), 0, list );
1546 }
1547 if (!got_one) break;
1548 }
Alexandre Julliard22945d51995-03-02 17:44:29 +00001549 }
1550
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001551 /* Send destroy messages */
Alexandre Julliard0e607781993-11-03 19:23:37 +00001552
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001553 WIN_SendDestroyMsg( hwnd );
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001554 if (!IsWindow( hwnd )) return TRUE;
Alexandre Julliard401710d1993-09-04 10:09:32 +00001555
Ulrich Czekallab2df5f92003-06-23 23:02:02 +00001556 if (GetClipboardOwner() == hwnd)
1557 CLIPBOARD_ReleaseOwner();
1558
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001559 /* Destroy the window storage */
1560
Alexandre Julliard80593bf2001-10-11 20:49:40 +00001561 WIN_DestroyWindow( hwnd );
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001562 return TRUE;
Alexandre Julliard401710d1993-09-04 10:09:32 +00001563}
1564
1565
1566/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001567 * CloseWindow (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001568 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001569BOOL WINAPI CloseWindow( HWND hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001570{
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001571 if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) return FALSE;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001572 ShowWindow( hwnd, SW_MINIMIZE );
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001573 return TRUE;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001574}
1575
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00001576
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001577/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001578 * OpenIcon (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001579 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001580BOOL WINAPI OpenIcon( HWND hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001581{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001582 if (!IsIconic( hwnd )) return FALSE;
1583 ShowWindow( hwnd, SW_SHOWNORMAL );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001584 return TRUE;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001585}
1586
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001587
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001588/***********************************************************************
1589 * WIN_FindWindow
1590 *
1591 * Implementation of FindWindow() and FindWindowEx().
1592 */
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001593static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001594{
Alexandre Julliard844ceb92001-10-09 23:26:40 +00001595 HWND *list = NULL;
1596 HWND retvalue = 0;
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001597 int i = 0, len = 0;
1598 WCHAR *buffer = NULL;
1599
1600 if (!parent) parent = GetDesktopWindow();
1601 if (title)
1602 {
1603 len = strlenW(title) + 1; /* one extra char to check for chars beyond the end */
1604 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return 0;
1605 }
1606
Alexandre Julliard844ceb92001-10-09 23:26:40 +00001607 if (!(list = list_window_children( parent, className, 0 ))) goto done;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001608
1609 if (child)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001610 {
Alexandre Julliardf44bbb82001-09-14 00:24:39 +00001611 child = WIN_GetFullHandle( child );
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001612 while (list[i] && list[i] != child) i++;
Alexandre Julliard844ceb92001-10-09 23:26:40 +00001613 if (!list[i]) goto done;
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001614 i++; /* start from next window */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001615 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001616
Alexandre Julliard844ceb92001-10-09 23:26:40 +00001617 if (title)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001618 {
Alexandre Julliard844ceb92001-10-09 23:26:40 +00001619 while (list[i])
1620 {
Mike Hearn9a1e0a02003-12-30 19:09:50 +00001621 if (GetWindowTextW( list[i], buffer, len + 1 ) && !strcmpiW( buffer, title )) break;
Alexandre Julliard844ceb92001-10-09 23:26:40 +00001622 i++;
1623 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001624 }
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001625 retvalue = list[i];
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00001626
Alexandre Julliard844ceb92001-10-09 23:26:40 +00001627 done:
Michael Stefaniuc5ad7d852004-12-23 17:06:43 +00001628 HeapFree( GetProcessHeap(), 0, list );
1629 HeapFree( GetProcessHeap(), 0, buffer );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001630 return retvalue;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001631}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001632
1633
1634
1635/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001636 * FindWindowA (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001637 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001638HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001639{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001640 HWND ret = FindWindowExA( 0, 0, className, title );
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001641 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1642 return ret;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001643}
1644
1645
1646/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001647 * FindWindowExA (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001648 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001649HWND WINAPI FindWindowExA( HWND parent, HWND child,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001650 LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001651{
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001652 ATOM atom = 0;
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001653 LPWSTR buffer;
1654 HWND hwnd;
Alexandre Julliard193cf502002-01-01 00:24:30 +00001655 INT len;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001656
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001657 if (className)
1658 {
1659 /* If the atom doesn't exist, then no class */
1660 /* with this name exists either. */
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00001661 if (!(atom = GlobalFindAtomA( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001662 {
1663 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1664 return 0;
1665 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001666 }
Alexandre Julliard193cf502002-01-01 00:24:30 +00001667 if (!title) return WIN_FindWindow( parent, child, atom, NULL );
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001668
Alexandre Julliard193cf502002-01-01 00:24:30 +00001669 len = MultiByteToWideChar( CP_ACP, 0, title, -1, NULL, 0 );
1670 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return 0;
1671 MultiByteToWideChar( CP_ACP, 0, title, -1, buffer, len );
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001672 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1673 HeapFree( GetProcessHeap(), 0, buffer );
1674 return hwnd;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001675}
1676
1677
1678/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001679 * FindWindowExW (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001680 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001681HWND WINAPI FindWindowExW( HWND parent, HWND child,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001682 LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001683{
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001684 ATOM atom = 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001685
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001686 if (className)
1687 {
1688 /* If the atom doesn't exist, then no class */
1689 /* with this name exists either. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001690 if (!(atom = GlobalFindAtomW( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001691 {
1692 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1693 return 0;
1694 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001695 }
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001696 return WIN_FindWindow( parent, child, atom, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001697}
1698
1699
1700/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001701 * FindWindowW (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001702 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001703HWND WINAPI FindWindowW( LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001704{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001705 return FindWindowExW( 0, 0, className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001706}
1707
1708
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001709/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001710 * GetDesktopWindow (USER32.@)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001711 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001712HWND WINAPI GetDesktopWindow(void)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001713{
Uwe Bonnes73619161999-10-24 20:42:39 +00001714 if (pWndDesktop) return pWndDesktop->hwndSelf;
Gerard Patele717b1b2001-11-19 02:07:11 +00001715 ERR( "Wine init error: either you're trying to use an invalid native USER.EXE config, or some graphics/GUI libraries or DLLs didn't initialize properly. Aborting.\n" );
Uwe Bonnes73619161999-10-24 20:42:39 +00001716 ExitProcess(1);
Huw D M Davies238b6d71999-10-31 01:56:51 +00001717 return 0;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001718}
1719
1720
Alexandre Julliard01d63461997-01-20 19:43:45 +00001721/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001722 * EnableWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001723 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001724BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001725{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001726 BOOL retvalue;
Alexandre Julliardddc33172001-10-22 19:08:33 +00001727 HWND full_handle;
1728
Alexandre Julliardd0af1232003-05-19 19:00:02 +00001729 if (is_broadcast(hwnd))
1730 {
1731 SetLastError( ERROR_INVALID_PARAMETER );
1732 return FALSE;
1733 }
1734
Alexandre Julliardddc33172001-10-22 19:08:33 +00001735 if (!(full_handle = WIN_IsCurrentThread( hwnd )))
1736 return SendMessageW( hwnd, WM_WINE_ENABLEWINDOW, enable, 0 );
1737
1738 hwnd = full_handle;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001739
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00001740 TRACE("( %p, %d )\n", hwnd, enable);
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001741
Alexandre Julliardf9364282005-01-21 10:32:13 +00001742 retvalue = !IsWindowEnabled( hwnd );
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001743
Alexandre Julliardddc33172001-10-22 19:08:33 +00001744 if (enable && retvalue)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001745 {
Alexandre Julliardf9364282005-01-21 10:32:13 +00001746 WIN_SetStyle( hwnd, 0, WS_DISABLED );
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +00001747 SendMessageW( hwnd, WM_ENABLE, TRUE, 0 );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001748 }
Alexandre Julliardddc33172001-10-22 19:08:33 +00001749 else if (!enable && !retvalue)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001750 {
Ulrich Czekallae32e1f02004-06-03 00:08:55 +00001751 HWND capture_wnd;
Aric Stewart6fcf4012003-06-23 20:02:01 +00001752
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +00001753 SendMessageW( hwnd, WM_CANCELMODE, 0, 0);
Alex Korobka4f1ac051999-03-28 09:37:57 +00001754
Alexandre Julliardf9364282005-01-21 10:32:13 +00001755 WIN_SetStyle( hwnd, WS_DISABLED, 0 );
Alex Korobka4f1ac051999-03-28 09:37:57 +00001756
Ulrich Czekallae32e1f02004-06-03 00:08:55 +00001757 if (hwnd == GetFocus())
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001758 SetFocus( 0 ); /* A disabled window can't have the focus */
Alex Korobka4f1ac051999-03-28 09:37:57 +00001759
Aric Stewart6fcf4012003-06-23 20:02:01 +00001760 capture_wnd = GetCapture();
1761 if (hwnd == capture_wnd || IsChild(hwnd, capture_wnd))
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001762 ReleaseCapture(); /* A disabled window can't capture the mouse */
1763
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +00001764 SendMessageW( hwnd, WM_ENABLE, FALSE, 0 );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001765 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001766 return retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001767}
1768
1769
1770/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001771 * IsWindowEnabled (USER32.@)
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00001772 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001773BOOL WINAPI IsWindowEnabled(HWND hWnd)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001774{
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00001775 return !(GetWindowLongW( hWnd, GWL_STYLE ) & WS_DISABLED);
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001776}
1777
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001778
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001779/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001780 * IsWindowUnicode (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001781 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001782BOOL WINAPI IsWindowUnicode( HWND hwnd )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001783{
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00001784 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001785 BOOL retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001786
Alexandre Julliard6382ffa2005-01-20 20:07:42 +00001787 if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001788 retvalue = (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
Alexandre Julliard6382ffa2005-01-20 20:07:42 +00001789 WIN_ReleasePtr( wndPtr );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001790 return retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001791}
1792
1793
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001794/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001795 * GetWindowWord (USER32.@)
Alexandre Julliard21979011997-03-05 08:22:35 +00001796 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001797WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001798{
Alexandre Julliard3051b641996-07-05 17:14:13 +00001799 if (offset >= 0)
1800 {
Alexandre Julliardddc33172001-10-22 19:08:33 +00001801 WORD retvalue = 0;
1802 WND *wndPtr = WIN_GetPtr( hwnd );
1803 if (!wndPtr)
1804 {
1805 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1806 return 0;
1807 }
1808 if (wndPtr == WND_OTHER_PROCESS)
1809 {
Alexandre Julliardebf12432003-12-10 01:34:51 +00001810 SERVER_START_REQ( set_window_info )
1811 {
1812 req->handle = hwnd;
1813 req->flags = 0; /* don't set anything, just retrieve */
1814 req->extra_offset = offset;
1815 req->extra_size = sizeof(retvalue);
1816 if (!wine_server_call_err( req ))
1817 memcpy( &retvalue, &reply->old_extra_value, sizeof(retvalue) );
1818 }
1819 SERVER_END_REQ;
1820 return retvalue;
Alexandre Julliardddc33172001-10-22 19:08:33 +00001821 }
Alexandre Julliarda8175682002-11-13 19:49:29 +00001822 if (offset > (int)(wndPtr->cbWndExtra - sizeof(WORD)))
Alexandre Julliard3051b641996-07-05 17:14:13 +00001823 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001824 WARN("Invalid offset %d\n", offset );
Alexandre Julliardddc33172001-10-22 19:08:33 +00001825 SetLastError( ERROR_INVALID_INDEX );
Alexandre Julliard3051b641996-07-05 17:14:13 +00001826 }
Alexandre Julliardebf12432003-12-10 01:34:51 +00001827 else memcpy( &retvalue, (char *)wndPtr->wExtra + offset, sizeof(retvalue) );
Alexandre Julliardddc33172001-10-22 19:08:33 +00001828 WIN_ReleasePtr( wndPtr );
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00001829 return retvalue;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001830 }
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00001831
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001832 switch(offset)
1833 {
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00001834 case GWLP_HWNDPARENT:
1835 return GetWindowLongPtrW( hwnd, offset );
1836 case GWLP_ID:
1837 case GWLP_HINSTANCE:
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00001838 {
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00001839 LONG_PTR ret = GetWindowLongPtrW( hwnd, offset );
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00001840 if (HIWORD(ret))
1841 WARN("%d: discards high bits of 0x%08lx!\n", offset, ret );
1842 return LOWORD(ret);
1843 }
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001844 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001845 WARN("Invalid offset %d\n", offset );
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00001846 return 0;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001847 }
Alexandre Julliard21979011997-03-05 08:22:35 +00001848}
1849
1850
1851/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001852 * SetWindowWord (USER32.@)
Alexandre Julliard21979011997-03-05 08:22:35 +00001853 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001854WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001855{
Alexandre Julliard97903d22003-11-26 22:15:41 +00001856 WORD retval = 0;
Alexandre Julliardddc33172001-10-22 19:08:33 +00001857 WND * wndPtr;
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00001858
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00001859 switch(offset)
1860 {
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00001861 case GWLP_ID:
1862 case GWLP_HINSTANCE:
1863 case GWLP_HWNDPARENT:
1864 return SetWindowLongPtrW( hwnd, offset, (ULONG_PTR)newval );
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00001865 default:
Alexandre Julliardddc33172001-10-22 19:08:33 +00001866 if (offset < 0)
1867 {
1868 WARN("Invalid offset %d\n", offset );
1869 SetLastError( ERROR_INVALID_INDEX );
1870 return 0;
1871 }
1872 }
1873
1874 wndPtr = WIN_GetPtr( hwnd );
1875 if (wndPtr == WND_OTHER_PROCESS)
1876 {
1877 if (IsWindow(hwnd))
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00001878 FIXME( "set %d <- %x not supported yet on other process window %p\n",
Alexandre Julliardddc33172001-10-22 19:08:33 +00001879 offset, newval, hwnd );
1880 wndPtr = NULL;
1881 }
1882 if (!wndPtr)
1883 {
1884 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1885 return 0;
1886 }
1887
Alexandre Julliarda8175682002-11-13 19:49:29 +00001888 if (offset > (int)(wndPtr->cbWndExtra - sizeof(WORD)))
Alexandre Julliardddc33172001-10-22 19:08:33 +00001889 {
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00001890 WARN("Invalid offset %d\n", offset );
Alexandre Julliardddc33172001-10-22 19:08:33 +00001891 WIN_ReleasePtr(wndPtr);
1892 SetLastError( ERROR_INVALID_INDEX );
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00001893 return 0;
1894 }
Alexandre Julliard97903d22003-11-26 22:15:41 +00001895
1896 SERVER_START_REQ( set_window_info )
1897 {
1898 req->handle = hwnd;
Alexandre Julliardebf12432003-12-10 01:34:51 +00001899 req->flags = SET_WIN_EXTRA;
Alexandre Julliard97903d22003-11-26 22:15:41 +00001900 req->extra_offset = offset;
Alexandre Julliardebf12432003-12-10 01:34:51 +00001901 req->extra_size = sizeof(newval);
1902 memcpy( &req->extra_value, &newval, sizeof(newval) );
Alexandre Julliard97903d22003-11-26 22:15:41 +00001903 if (!wine_server_call_err( req ))
1904 {
Alexandre Julliardebf12432003-12-10 01:34:51 +00001905 void *ptr = (char *)wndPtr->wExtra + offset;
1906 memcpy( &retval, ptr, sizeof(retval) );
1907 memcpy( ptr, &newval, sizeof(newval) );
Alexandre Julliard97903d22003-11-26 22:15:41 +00001908 }
1909 }
1910 SERVER_END_REQ;
1911 WIN_ReleasePtr( wndPtr );
Alexandre Julliardddc33172001-10-22 19:08:33 +00001912 return retval;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001913}
1914
1915
1916/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001917 * WIN_GetWindowLong
1918 *
1919 * Helper function for GetWindowLong().
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001920 */
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00001921static LONG_PTR WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001922{
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00001923 LONG_PTR retvalue = 0;
Alexandre Julliardddc33172001-10-22 19:08:33 +00001924 WND *wndPtr;
1925
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00001926 if (offset == GWLP_HWNDPARENT)
Alexandre Julliard7dafa612002-09-25 00:21:56 +00001927 {
1928 HWND parent = GetAncestor( hwnd, GA_PARENT );
1929 if (parent == GetDesktopWindow()) parent = GetWindow( hwnd, GW_OWNER );
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00001930 return (ULONG_PTR)parent;
Alexandre Julliard7dafa612002-09-25 00:21:56 +00001931 }
Alexandre Julliardddc33172001-10-22 19:08:33 +00001932
1933 if (!(wndPtr = WIN_GetPtr( hwnd )))
1934 {
1935 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1936 return 0;
1937 }
1938
1939 if (wndPtr == WND_OTHER_PROCESS)
1940 {
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00001941 if (offset == GWLP_WNDPROC)
Alexandre Julliardddc33172001-10-22 19:08:33 +00001942 {
1943 SetLastError( ERROR_ACCESS_DENIED );
1944 return 0;
1945 }
1946 SERVER_START_REQ( set_window_info )
1947 {
1948 req->handle = hwnd;
1949 req->flags = 0; /* don't set anything, just retrieve */
Alexandre Julliard97903d22003-11-26 22:15:41 +00001950 req->extra_offset = (offset >= 0) ? offset : -1;
Alexandre Julliardebf12432003-12-10 01:34:51 +00001951 req->extra_size = (offset >= 0) ? sizeof(retvalue) : 0;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00001952 if (!wine_server_call_err( req ))
Alexandre Julliardddc33172001-10-22 19:08:33 +00001953 {
1954 switch(offset)
1955 {
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00001956 case GWL_STYLE: retvalue = reply->old_style; break;
1957 case GWL_EXSTYLE: retvalue = reply->old_ex_style; break;
1958 case GWLP_ID: retvalue = reply->old_id; break;
1959 case GWLP_HINSTANCE: retvalue = (ULONG_PTR)reply->old_instance; break;
1960 case GWLP_USERDATA: retvalue = (ULONG_PTR)reply->old_user_data; break;
Alexandre Julliardddc33172001-10-22 19:08:33 +00001961 default:
Alexandre Julliard97903d22003-11-26 22:15:41 +00001962 if (offset >= 0) retvalue = reply->old_extra_value;
1963 else SetLastError( ERROR_INVALID_INDEX );
Alexandre Julliardddc33172001-10-22 19:08:33 +00001964 break;
1965 }
1966 }
1967 }
1968 SERVER_END_REQ;
1969 return retvalue;
1970 }
1971
1972 /* now we have a valid wndPtr */
1973
Alexandre Julliard3051b641996-07-05 17:14:13 +00001974 if (offset >= 0)
1975 {
Alexandre Julliarda8175682002-11-13 19:49:29 +00001976 if (offset > (int)(wndPtr->cbWndExtra - sizeof(LONG)))
Alexandre Julliard3051b641996-07-05 17:14:13 +00001977 {
Jukka Heinonen3fead8f2002-02-15 18:22:23 +00001978 /*
1979 * Some programs try to access last element from 16 bit
1980 * code using illegal offset value. Hopefully this is
1981 * what those programs really expect.
1982 */
Vincent Béron9a624912002-05-31 23:06:46 +00001983 if (type == WIN_PROC_16 &&
Jukka Heinonen3fead8f2002-02-15 18:22:23 +00001984 wndPtr->cbWndExtra >= 4 &&
1985 offset == wndPtr->cbWndExtra - sizeof(WORD))
1986 {
1987 INT offset2 = wndPtr->cbWndExtra - sizeof(LONG);
Vincent Béron9a624912002-05-31 23:06:46 +00001988
Jukka Heinonen3fead8f2002-02-15 18:22:23 +00001989 ERR( "- replaced invalid offset %d with %d\n",
1990 offset, offset2 );
Vincent Béron9a624912002-05-31 23:06:46 +00001991
Dmitry Timoshkov39f960b2005-02-15 21:51:06 +00001992 retvalue = *(LONG_PTR *)(((char *)wndPtr->wExtra) + offset2);
Jukka Heinonen3fead8f2002-02-15 18:22:23 +00001993 WIN_ReleasePtr( wndPtr );
1994 return retvalue;
1995 }
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001996 WARN("Invalid offset %d\n", offset );
Alexandre Julliardddc33172001-10-22 19:08:33 +00001997 WIN_ReleasePtr( wndPtr );
1998 SetLastError( ERROR_INVALID_INDEX );
1999 return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002000 }
Dmitry Timoshkov39f960b2005-02-15 21:51:06 +00002001 retvalue = *(LONG_PTR *)(((char *)wndPtr->wExtra) + offset);
Alexandre Julliard3051b641996-07-05 17:14:13 +00002002 /* Special case for dialog window procedure */
Dmitry Timoshkov39f960b2005-02-15 21:51:06 +00002003 if ((offset == DWLP_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
2004 retvalue = (LONG_PTR)WINPROC_GetProc( (WNDPROC)retvalue, type );
Alexandre Julliardddc33172001-10-22 19:08:33 +00002005 WIN_ReleasePtr( wndPtr );
2006 return retvalue;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002007 }
Alexandre Julliardddc33172001-10-22 19:08:33 +00002008
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002009 switch(offset)
2010 {
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002011 case GWLP_USERDATA: retvalue = wndPtr->userdata; break;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002012 case GWL_STYLE: retvalue = wndPtr->dwStyle; break;
2013 case GWL_EXSTYLE: retvalue = wndPtr->dwExStyle; break;
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002014 case GWLP_ID: retvalue = (ULONG_PTR)wndPtr->wIDmenu; break;
2015 case GWLP_WNDPROC: retvalue = (ULONG_PTR)WINPROC_GetProc( wndPtr->winproc, type ); break;
2016 case GWLP_HINSTANCE: retvalue = (ULONG_PTR)wndPtr->hInstance; break;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002017 default:
2018 WARN("Unknown offset %d\n", offset );
2019 SetLastError( ERROR_INVALID_INDEX );
2020 break;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002021 }
Alexandre Julliardddc33172001-10-22 19:08:33 +00002022 WIN_ReleasePtr(wndPtr);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002023 return retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002024}
2025
2026
2027/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002028 * WIN_SetWindowLong
2029 *
2030 * Helper function for SetWindowLong().
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002031 *
2032 * 0 is the failure code. However, in the case of failure SetLastError
2033 * must be set to distinguish between a 0 return value and a failure.
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00002034 */
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002035static LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, LONG_PTR newval,
2036 WINDOWPROCTYPE type )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002037{
Alexandre Julliard97903d22003-11-26 22:15:41 +00002038 STYLESTRUCT style;
2039 BOOL ok;
Dmitry Timoshkov39f960b2005-02-15 21:51:06 +00002040 LONG_PTR retval = 0;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002041 WND *wndPtr;
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00002042
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00002043 TRACE( "%p %d %lx %x\n", hwnd, offset, newval, type );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002044
Alexandre Julliardd0af1232003-05-19 19:00:02 +00002045 if (is_broadcast(hwnd))
2046 {
2047 SetLastError( ERROR_INVALID_PARAMETER );
2048 return FALSE;
2049 }
Alexandre Julliard55557312001-10-23 00:26:10 +00002050 if (!WIN_IsCurrentProcess( hwnd ))
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002051 {
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002052 if (offset == GWLP_WNDPROC)
Alexandre Julliard55557312001-10-23 00:26:10 +00002053 {
2054 SetLastError( ERROR_ACCESS_DENIED );
2055 return 0;
2056 }
Alexandre Julliardddc33172001-10-22 19:08:33 +00002057 return SendMessageW( hwnd, WM_WINE_SETWINDOWLONG, offset, newval );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002058 }
2059
Alexandre Julliardddc33172001-10-22 19:08:33 +00002060 wndPtr = WIN_GetPtr( hwnd );
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002061 if (wndPtr->hwndSelf == GetDesktopWindow())
2062 {
2063 /* can't change anything on the desktop window */
Alexandre Julliard02b8cb72002-09-25 03:25:43 +00002064 WIN_ReleasePtr( wndPtr );
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002065 SetLastError( ERROR_ACCESS_DENIED );
2066 return 0;
2067 }
Alexandre Julliardddc33172001-10-22 19:08:33 +00002068
Alexandre Julliard97903d22003-11-26 22:15:41 +00002069 /* first some special cases */
2070 switch( offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002071 {
Alexandre Julliard97903d22003-11-26 22:15:41 +00002072 case GWL_STYLE:
2073 case GWL_EXSTYLE:
2074 style.styleOld =
2075 offset == GWL_STYLE ? wndPtr->dwStyle : wndPtr->dwExStyle;
2076 style.styleNew = newval;
2077 WIN_ReleasePtr( wndPtr );
2078 SendMessageW( hwnd, WM_STYLECHANGING, offset, (LPARAM)&style );
2079 if (!(wndPtr = WIN_GetPtr( hwnd )) || wndPtr == WND_OTHER_PROCESS) return 0;
2080 newval = style.styleNew;
2081 break;
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002082 case GWLP_HWNDPARENT:
Alexandre Julliard97903d22003-11-26 22:15:41 +00002083 if (wndPtr->parent == GetDesktopWindow())
2084 {
2085 WIN_ReleasePtr( wndPtr );
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002086 return (ULONG_PTR)WIN_SetOwner( hwnd, (HWND)newval );
Alexandre Julliard97903d22003-11-26 22:15:41 +00002087 }
2088 else
2089 {
2090 WIN_ReleasePtr( wndPtr );
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002091 return (ULONG_PTR)SetParent( hwnd, (HWND)newval );
Alexandre Julliard97903d22003-11-26 22:15:41 +00002092 }
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002093 case GWLP_WNDPROC:
2094 retval = (ULONG_PTR)WINPROC_GetProc( wndPtr->winproc, type );
Alexandre Julliard648994c2004-11-24 18:43:18 +00002095 wndPtr->winproc = WINPROC_AllocProc( (WNDPROC)newval, type );
Alexandre Julliard97903d22003-11-26 22:15:41 +00002096 WIN_ReleasePtr( wndPtr );
2097 return retval;
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002098 case GWLP_ID:
2099 case GWLP_HINSTANCE:
2100 case GWLP_USERDATA:
Alexandre Julliard97903d22003-11-26 22:15:41 +00002101 break;
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002102 case DWLP_DLGPROC:
Dmitry Timoshkov39f960b2005-02-15 21:51:06 +00002103 if ((wndPtr->cbWndExtra + sizeof(LONG_PTR) >= DWLP_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
Alexandre Julliard97903d22003-11-26 22:15:41 +00002104 {
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002105 WNDPROC *ptr = (WNDPROC *)((char *)wndPtr->wExtra + DWLP_DLGPROC);
2106 retval = (ULONG_PTR)WINPROC_GetProc( *ptr, type );
Alexandre Julliard648994c2004-11-24 18:43:18 +00002107 *ptr = WINPROC_AllocProc( (WNDPROC)newval, type );
Alexandre Julliard97903d22003-11-26 22:15:41 +00002108 WIN_ReleasePtr( wndPtr );
2109 return retval;
2110 }
2111 /* fall through */
2112 default:
Dmitry Timoshkov39f960b2005-02-15 21:51:06 +00002113 if (offset < 0 || offset > (int)(wndPtr->cbWndExtra - sizeof(LONG_PTR)))
Alexandre Julliard3051b641996-07-05 17:14:13 +00002114 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002115 WARN("Invalid offset %d\n", offset );
Alexandre Julliardddc33172001-10-22 19:08:33 +00002116 WIN_ReleasePtr( wndPtr );
2117 SetLastError( ERROR_INVALID_INDEX );
2118 return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002119 }
Alexandre Julliard97903d22003-11-26 22:15:41 +00002120 else
Alexandre Julliard3051b641996-07-05 17:14:13 +00002121 {
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002122 LONG_PTR *ptr = (LONG_PTR *)((char *)wndPtr->wExtra + offset);
Alexandre Julliard97903d22003-11-26 22:15:41 +00002123 if (*ptr == newval) /* already set to the same value */
2124 {
2125 WIN_ReleasePtr( wndPtr );
2126 return newval;
2127 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002128 }
Alexandre Julliard97903d22003-11-26 22:15:41 +00002129 break;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002130 }
Alexandre Julliardddc33172001-10-22 19:08:33 +00002131
Alexandre Julliard97903d22003-11-26 22:15:41 +00002132 SERVER_START_REQ( set_window_info )
2133 {
2134 req->handle = hwnd;
2135 req->extra_offset = -1;
2136 switch(offset)
Alexandre Julliardddc33172001-10-22 19:08:33 +00002137 {
2138 case GWL_STYLE:
Alexandre Julliard97903d22003-11-26 22:15:41 +00002139 req->flags = SET_WIN_STYLE;
2140 req->style = newval;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002141 break;
Alexandre Julliard97903d22003-11-26 22:15:41 +00002142 case GWL_EXSTYLE:
2143 req->flags = SET_WIN_EXSTYLE;
2144 req->ex_style = newval;
2145 break;
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002146 case GWLP_ID:
Alexandre Julliard97903d22003-11-26 22:15:41 +00002147 req->flags = SET_WIN_ID;
2148 req->id = newval;
2149 break;
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002150 case GWLP_HINSTANCE:
Alexandre Julliard97903d22003-11-26 22:15:41 +00002151 req->flags = SET_WIN_INSTANCE;
2152 req->instance = (void *)newval;
2153 break;
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002154 case GWLP_USERDATA:
Alexandre Julliard97903d22003-11-26 22:15:41 +00002155 req->flags = SET_WIN_USERDATA;
2156 req->user_data = (void *)newval;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002157 break;
2158 default:
Alexandre Julliardebf12432003-12-10 01:34:51 +00002159 req->flags = SET_WIN_EXTRA;
Alexandre Julliard97903d22003-11-26 22:15:41 +00002160 req->extra_offset = offset;
Alexandre Julliardebf12432003-12-10 01:34:51 +00002161 req->extra_size = sizeof(newval);
2162 memcpy( &req->extra_value, &newval, sizeof(newval) );
Alexandre Julliardddc33172001-10-22 19:08:33 +00002163 }
Alexandre Julliard97903d22003-11-26 22:15:41 +00002164 if ((ok = !wine_server_call_err( req )))
Alexandre Julliardddc33172001-10-22 19:08:33 +00002165 {
Alexandre Julliardddc33172001-10-22 19:08:33 +00002166 switch(offset)
2167 {
2168 case GWL_STYLE:
Alexandre Julliard97903d22003-11-26 22:15:41 +00002169 wndPtr->dwStyle = newval;
2170 retval = reply->old_style;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002171 break;
2172 case GWL_EXSTYLE:
Alexandre Julliard97903d22003-11-26 22:15:41 +00002173 wndPtr->dwExStyle = newval;
2174 retval = reply->old_ex_style;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002175 break;
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002176 case GWLP_ID:
Alexandre Julliard97903d22003-11-26 22:15:41 +00002177 wndPtr->wIDmenu = newval;
2178 retval = reply->old_id;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002179 break;
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002180 case GWLP_HINSTANCE:
Alexandre Julliard97903d22003-11-26 22:15:41 +00002181 wndPtr->hInstance = (HINSTANCE)newval;
2182 retval = (ULONG_PTR)reply->old_instance;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002183 break;
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002184 case GWLP_USERDATA:
Alexandre Julliard97903d22003-11-26 22:15:41 +00002185 wndPtr->userdata = newval;
2186 retval = (ULONG_PTR)reply->old_user_data;
2187 break;
2188 default:
2189 {
Alexandre Julliardebf12432003-12-10 01:34:51 +00002190 void *ptr = (char *)wndPtr->wExtra + offset;
2191 memcpy( &retval, ptr, sizeof(retval) );
2192 memcpy( ptr, &newval, sizeof(newval) );
Alexandre Julliard97903d22003-11-26 22:15:41 +00002193 }
Alexandre Julliardddc33172001-10-22 19:08:33 +00002194 break;
2195 }
Alexandre Julliardddc33172001-10-22 19:08:33 +00002196 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002197 }
Alexandre Julliard97903d22003-11-26 22:15:41 +00002198 SERVER_END_REQ;
2199 WIN_ReleasePtr( wndPtr );
2200
2201 if (!ok) return 0;
2202
2203 if (offset == GWL_STYLE && USER_Driver.pSetWindowStyle)
2204 USER_Driver.pSetWindowStyle( hwnd, retval );
2205
2206 if (offset == GWL_STYLE || offset == GWL_EXSTYLE)
2207 SendMessageW( hwnd, WM_STYLECHANGED, offset, (LPARAM)&style );
2208
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002209 return retval;
2210}
2211
2212
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002213/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002214 * GetWindowLong (USER.135)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002215 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002216LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002217{
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00002218 return WIN_GetWindowLong( WIN_Handle32(hwnd), offset, WIN_PROC_16 );
Alexandre Julliard3051b641996-07-05 17:14:13 +00002219}
2220
2221
2222/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002223 * GetWindowLongA (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002224 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002225LONG WINAPI GetWindowLongA( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002226{
2227 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
2228}
2229
2230
2231/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002232 * GetWindowLongW (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002233 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002234LONG WINAPI GetWindowLongW( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002235{
2236 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
2237}
2238
2239
2240/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002241 * SetWindowLong (USER.136)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002242 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002243LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002244{
Alexandre Julliardd23a82b2001-09-19 20:37:04 +00002245 return WIN_SetWindowLong( WIN_Handle32(hwnd), offset, newval, WIN_PROC_16 );
Alexandre Julliard3051b641996-07-05 17:14:13 +00002246}
2247
2248
2249/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002250 * SetWindowLongA (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002251 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002252LONG WINAPI SetWindowLongA( HWND hwnd, INT offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002253{
2254 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
2255}
2256
2257
2258/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002259 * SetWindowLongW (USER32.@) Set window attribute
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002260 *
2261 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00002262 * value in a window's extra memory.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002263 *
2264 * The _hwnd_ parameter specifies the window. is the handle to a
2265 * window that has extra memory. The _newval_ parameter contains the
2266 * new attribute or extra memory value. If positive, the _offset_
2267 * parameter is the byte-addressed location in the window's extra
2268 * memory to set. If negative, _offset_ specifies the window
2269 * attribute to set, and should be one of the following values:
2270 *
2271 * GWL_EXSTYLE The window's extended window style
2272 *
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00002273 * GWL_STYLE The window's window style.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002274 *
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002275 * GWLP_WNDPROC Pointer to the window's window procedure.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002276 *
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002277 * GWLP_HINSTANCE The window's pplication instance handle.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002278 *
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002279 * GWLP_ID The window's identifier.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002280 *
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002281 * GWLP_USERDATA The window's user-specified data.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002282 *
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00002283 * If the window is a dialog box, the _offset_ parameter can be one of
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002284 * the following values:
2285 *
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002286 * DWLP_DLGPROC The address of the window's dialog box procedure.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002287 *
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002288 * DWLP_MSGRESULT The return value of a message
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002289 * that the dialog box procedure processed.
2290 *
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002291 * DWLP_USER Application specific information.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002292 *
2293 * RETURNS
2294 *
2295 * If successful, returns the previous value located at _offset_. Otherwise,
2296 * returns 0.
2297 *
2298 * NOTES
2299 *
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00002300 * Extra memory for a window class is specified by a nonzero cbWndExtra
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002301 * parameter of the WNDCLASS structure passed to RegisterClass() at the
2302 * time of class creation.
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00002303 *
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002304 * Using GWL_WNDPROC to set a new window procedure effectively creates
2305 * a window subclass. Use CallWindowProc() in the new windows procedure
2306 * to pass messages to the superclass's window procedure.
2307 *
2308 * The user data is reserved for use by the application which created
2309 * the window.
2310 *
Gerard Patele717b1b2001-11-19 02:07:11 +00002311 * Do not use GWL_STYLE to change the window's WS_DISABLED style;
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002312 * instead, call the EnableWindow() function to change the window's
2313 * disabled state.
2314 *
2315 * Do not use GWL_HWNDPARENT to reset the window's parent, use
2316 * SetParent() instead.
2317 *
Alexandre Julliard638f1691999-01-17 16:32:32 +00002318 * Win95:
2319 * When offset is GWL_STYLE and the calling app's ver is 4.0,
2320 * it sends WM_STYLECHANGING before changing the settings
2321 * and WM_STYLECHANGED afterwards.
2322 * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002323 */
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00002324LONG WINAPI SetWindowLongW(
Patrik Stridvall2b3aa612000-12-01 23:58:28 +00002325 HWND hwnd, /* [in] window to alter */
2326 INT offset, /* [in] offset, in bytes, of location to alter */
2327 LONG newval /* [in] new value of location */
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002328) {
Alexandre Julliard3051b641996-07-05 17:14:13 +00002329 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002330}
2331
2332
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002333/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002334 * GetWindowTextA (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002335 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002336INT WINAPI GetWindowTextA( HWND hwnd, LPSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002337{
Alexandre Julliard805bdc52001-11-13 22:23:48 +00002338 WCHAR *buffer;
2339
2340 if (WIN_IsCurrentProcess( hwnd ))
2341 return (INT)SendMessageA( hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString );
2342
2343 /* when window belongs to other process, don't send a message */
2344 if (nMaxCount <= 0) return 0;
2345 if (!(buffer = HeapAlloc( GetProcessHeap(), 0, nMaxCount * sizeof(WCHAR) ))) return 0;
2346 get_server_window_text( hwnd, buffer, nMaxCount );
2347 if (!WideCharToMultiByte( CP_ACP, 0, buffer, -1, lpString, nMaxCount, NULL, NULL ))
2348 lpString[nMaxCount-1] = 0;
2349 HeapFree( GetProcessHeap(), 0, buffer );
2350 return strlen(lpString);
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002351}
2352
Alexandre Julliard805bdc52001-11-13 22:23:48 +00002353
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002354/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002355 * InternalGetWindowText (USER32.@)
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002356 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002357INT WINAPI InternalGetWindowText(HWND hwnd,LPWSTR lpString,INT nMaxCount )
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002358{
Alexandre Julliard805bdc52001-11-13 22:23:48 +00002359 WND *win;
2360
2361 if (nMaxCount <= 0) return 0;
2362 if (!(win = WIN_GetPtr( hwnd ))) return 0;
2363 if (win != WND_OTHER_PROCESS)
2364 {
2365 if (win->text) lstrcpynW( lpString, win->text, nMaxCount );
2366 else lpString[0] = 0;
2367 WIN_ReleasePtr( win );
2368 }
2369 else
2370 {
2371 get_server_window_text( hwnd, lpString, nMaxCount );
2372 }
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00002373 return strlenW(lpString);
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002374}
2375
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002376
2377/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002378 * GetWindowTextW (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002379 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002380INT WINAPI GetWindowTextW( HWND hwnd, LPWSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002381{
Alexandre Julliard805bdc52001-11-13 22:23:48 +00002382 if (WIN_IsCurrentProcess( hwnd ))
2383 return (INT)SendMessageW( hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString );
2384
2385 /* when window belongs to other process, don't send a message */
2386 if (nMaxCount <= 0) return 0;
2387 get_server_window_text( hwnd, lpString, nMaxCount );
2388 return strlenW(lpString);
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002389}
2390
2391
2392/*******************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +00002393 * SetWindowText (USER32.@)
2394 * SetWindowTextA (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002395 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002396BOOL WINAPI SetWindowTextA( HWND hwnd, LPCSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002397{
Alexandre Julliardd0af1232003-05-19 19:00:02 +00002398 if (is_broadcast(hwnd))
2399 {
2400 SetLastError( ERROR_INVALID_PARAMETER );
2401 return FALSE;
2402 }
Alexandre Julliard805bdc52001-11-13 22:23:48 +00002403 if (!WIN_IsCurrentProcess( hwnd ))
2404 {
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00002405 FIXME( "cannot set text %s of other process window %p\n", debugstr_a(lpString), hwnd );
Alexandre Julliard805bdc52001-11-13 22:23:48 +00002406 SetLastError( ERROR_ACCESS_DENIED );
2407 return FALSE;
2408 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00002409 return (BOOL)SendMessageA( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002410}
2411
2412
2413/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002414 * SetWindowTextW (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002415 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002416BOOL WINAPI SetWindowTextW( HWND hwnd, LPCWSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002417{
Alexandre Julliardd0af1232003-05-19 19:00:02 +00002418 if (is_broadcast(hwnd))
2419 {
2420 SetLastError( ERROR_INVALID_PARAMETER );
2421 return FALSE;
2422 }
Alexandre Julliard805bdc52001-11-13 22:23:48 +00002423 if (!WIN_IsCurrentProcess( hwnd ))
2424 {
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00002425 FIXME( "cannot set text %s of other process window %p\n", debugstr_w(lpString), hwnd );
Alexandre Julliard805bdc52001-11-13 22:23:48 +00002426 SetLastError( ERROR_ACCESS_DENIED );
2427 return FALSE;
2428 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00002429 return (BOOL)SendMessageW( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002430}
2431
2432
Alexandre Julliard0e607781993-11-03 19:23:37 +00002433/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002434 * GetWindowTextLengthA (USER32.@)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002435 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002436INT WINAPI GetWindowTextLengthA( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002437{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002438 return SendMessageA( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002439}
2440
2441/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002442 * GetWindowTextLengthW (USER32.@)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002443 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002444INT WINAPI GetWindowTextLengthW( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002445{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002446 return SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002447}
2448
Alexandre Julliard21979011997-03-05 08:22:35 +00002449
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002450/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002451 * IsWindow (USER32.@)
Alexandre Julliard21979011997-03-05 08:22:35 +00002452 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002453BOOL WINAPI IsWindow( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002454{
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002455 WND *ptr;
Alexandre Julliard37a46392001-09-12 17:19:13 +00002456 BOOL ret;
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002457
Alexandre Julliard8fd26b92001-10-15 17:56:45 +00002458 if (!(ptr = WIN_GetPtr( hwnd ))) return FALSE;
2459
2460 if (ptr != WND_OTHER_PROCESS)
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002461 {
Alexandre Julliard8fd26b92001-10-15 17:56:45 +00002462 WIN_ReleasePtr( ptr );
Alexandre Julliard7695d692001-09-24 01:19:59 +00002463 return TRUE;
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002464 }
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002465
Alexandre Julliard37a46392001-09-12 17:19:13 +00002466 /* check other processes */
2467 SERVER_START_REQ( get_window_info )
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002468 {
Alexandre Julliard37a46392001-09-12 17:19:13 +00002469 req->handle = hwnd;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002470 ret = !wine_server_call_err( req );
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002471 }
Alexandre Julliard37a46392001-09-12 17:19:13 +00002472 SERVER_END_REQ;
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002473 return ret;
2474}
2475
2476
2477/***********************************************************************
2478 * GetWindowThreadProcessId (USER32.@)
2479 */
2480DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process )
2481{
2482 WND *ptr;
2483 DWORD tid = 0;
2484
Alexandre Julliard8fd26b92001-10-15 17:56:45 +00002485 if (!(ptr = WIN_GetPtr( hwnd )))
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002486 {
Alexandre Julliard8fd26b92001-10-15 17:56:45 +00002487 SetLastError( ERROR_INVALID_WINDOW_HANDLE);
2488 return 0;
2489 }
2490
2491 if (ptr != WND_OTHER_PROCESS)
2492 {
2493 /* got a valid window */
2494 tid = ptr->tid;
2495 if (process) *process = GetCurrentProcessId();
2496 WIN_ReleasePtr( ptr );
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002497 return tid;
2498 }
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002499
2500 /* check other processes */
2501 SERVER_START_REQ( get_window_info )
2502 {
2503 req->handle = hwnd;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002504 if (!wine_server_call_err( req ))
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002505 {
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002506 tid = (DWORD)reply->tid;
2507 if (process) *process = (DWORD)reply->pid;
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002508 }
2509 }
2510 SERVER_END_REQ;
2511 return tid;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002512}
2513
2514
2515/*****************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002516 * GetParent (USER32.@)
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002517 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002518HWND WINAPI GetParent( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002519{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002520 WND *wndPtr;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002521 HWND retvalue = 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002522
Alexandre Julliardddc33172001-10-22 19:08:33 +00002523 if (!(wndPtr = WIN_GetPtr( hwnd )))
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002524 {
Alexandre Julliardddc33172001-10-22 19:08:33 +00002525 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
2526 return 0;
2527 }
2528 if (wndPtr == WND_OTHER_PROCESS)
2529 {
2530 LONG style = GetWindowLongW( hwnd, GWL_STYLE );
2531 if (style & (WS_POPUP | WS_CHILD))
2532 {
2533 SERVER_START_REQ( get_window_tree )
2534 {
2535 req->handle = hwnd;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002536 if (!wine_server_call_err( req ))
Alexandre Julliardddc33172001-10-22 19:08:33 +00002537 {
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002538 if (style & WS_POPUP) retvalue = reply->owner;
2539 else if (style & WS_CHILD) retvalue = reply->parent;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002540 }
2541 }
2542 SERVER_END_REQ;
2543 }
2544 }
2545 else
2546 {
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002547 if (wndPtr->dwStyle & WS_POPUP) retvalue = wndPtr->owner;
2548 else if (wndPtr->dwStyle & WS_CHILD) retvalue = wndPtr->parent;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002549 WIN_ReleasePtr( wndPtr );
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002550 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002551 return retvalue;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002552}
2553
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002554
2555/*****************************************************************
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00002556 * GetAncestor (USER32.@)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002557 */
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00002558HWND WINAPI GetAncestor( HWND hwnd, UINT type )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002559{
Alexandre Julliardddc33172001-10-22 19:08:33 +00002560 WND *win;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002561 HWND *list, ret = 0;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002562
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002563 switch(type)
Alexandre Julliardddc33172001-10-22 19:08:33 +00002564 {
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002565 case GA_PARENT:
Alexandre Julliardddc33172001-10-22 19:08:33 +00002566 if (!(win = WIN_GetPtr( hwnd )))
2567 {
2568 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
2569 return 0;
2570 }
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002571 if (win != WND_OTHER_PROCESS)
Alexandre Julliardddc33172001-10-22 19:08:33 +00002572 {
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002573 ret = win->parent;
2574 WIN_ReleasePtr( win );
Alexandre Julliardddc33172001-10-22 19:08:33 +00002575 }
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002576 else /* need to query the server */
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002577 {
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002578 SERVER_START_REQ( get_window_tree )
Alexandre Julliard556607a2001-10-10 20:28:17 +00002579 {
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002580 req->handle = hwnd;
2581 if (!wine_server_call_err( req )) ret = reply->parent;
Alexandre Julliard556607a2001-10-10 20:28:17 +00002582 }
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002583 SERVER_END_REQ;
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002584 }
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002585 break;
Alexandre Julliard556607a2001-10-10 20:28:17 +00002586
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002587 case GA_ROOT:
Alexandre Julliard932a65d2005-01-31 16:46:47 +00002588 if (!(list = list_window_parents( hwnd ))) return 0;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002589
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002590 if (!list[0] || !list[1]) ret = WIN_GetFullHandle( hwnd ); /* top-level window */
2591 else
2592 {
2593 int count = 2;
2594 while (list[count]) count++;
2595 ret = list[count - 2]; /* get the one before the desktop */
2596 }
2597 HeapFree( GetProcessHeap(), 0, list );
2598 break;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002599
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002600 case GA_ROOTOWNER:
2601 if ((ret = WIN_GetFullHandle( hwnd )) == GetDesktopWindow()) return 0;
Alexandre Julliard556607a2001-10-10 20:28:17 +00002602 for (;;)
2603 {
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002604 HWND parent = GetParent( ret );
2605 if (!parent) break;
2606 ret = parent;
Alexandre Julliard556607a2001-10-10 20:28:17 +00002607 }
Alexandre Julliard7dafa612002-09-25 00:21:56 +00002608 break;
Alexandre Julliard556607a2001-10-10 20:28:17 +00002609 }
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00002610 return ret;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002611}
2612
2613
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002614/*****************************************************************
Alexandre Julliardddc33172001-10-22 19:08:33 +00002615 * SetParent (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002616 */
Alexandre Julliardddc33172001-10-22 19:08:33 +00002617HWND WINAPI SetParent( HWND hwnd, HWND parent )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002618{
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002619 WND *wndPtr;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002620 HWND retvalue, full_handle;
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00002621 BOOL was_visible;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002622
Alexandre Julliardd0af1232003-05-19 19:00:02 +00002623 if (is_broadcast(hwnd) || is_broadcast(parent))
2624 {
2625 SetLastError(ERROR_INVALID_PARAMETER);
2626 return 0;
2627 }
2628
Alexandre Julliardddc33172001-10-22 19:08:33 +00002629 if (!parent) parent = GetDesktopWindow();
2630 else parent = WIN_GetFullHandle( parent );
2631
2632 if (!IsWindow( parent ))
2633 {
2634 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
2635 return 0;
2636 }
2637
Dmitry Timoshkov8f0984c2005-03-02 10:11:06 +00002638 /* Some applications try to set a child as a parent */
2639 if (IsChild(hwnd, parent))
2640 {
2641 SetLastError( ERROR_INVALID_PARAMETER );
2642 return 0;
2643 }
2644
Alexandre Julliardddc33172001-10-22 19:08:33 +00002645 if (!(full_handle = WIN_IsCurrentThread( hwnd )))
Michael Stefaniuc2247af32002-09-04 19:37:01 +00002646 return (HWND)SendMessageW( hwnd, WM_WINE_SETPARENT, (WPARAM)parent, 0 );
Alexandre Julliardddc33172001-10-22 19:08:33 +00002647
2648 hwnd = full_handle;
2649
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002650 if (USER_Driver.pSetParent)
2651 return USER_Driver.pSetParent( hwnd, parent );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002652
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002653 /* Windows hides the window first, then shows it again
2654 * including the WM_SHOWWINDOW messages and all */
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00002655 was_visible = ShowWindow( hwnd, SW_HIDE );
2656
2657 if (!IsWindow( parent )) return 0;
2658 if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS) return 0;
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002659
Alexandre Julliard556607a2001-10-10 20:28:17 +00002660 retvalue = wndPtr->parent; /* old parent */
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002661 if (parent != retvalue)
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002662 {
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002663 WIN_LinkWindow( hwnd, parent, HWND_TOP );
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002664
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002665 if (parent != GetDesktopWindow()) /* a child window */
2666 {
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00002667 if (!(wndPtr->dwStyle & WS_CHILD))
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002668 {
Robert Shearmanbbdac5e2004-09-22 19:14:08 +00002669 HMENU menu = (HMENU)SetWindowLongPtrW( hwnd, GWLP_ID, 0 );
Alexandre Julliard1a66d222001-08-28 18:44:52 +00002670 if (menu) DestroyMenu( menu );
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002671 }
2672 }
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002673 }
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00002674 WIN_ReleasePtr( wndPtr );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002675
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002676 /* SetParent additionally needs to make hwnd the topmost window
2677 in the x-order and send the expected WM_WINDOWPOSCHANGING and
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00002678 WM_WINDOWPOSCHANGED notification messages.
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002679 */
2680 SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
Alexandre Julliardfb0ff052001-10-16 21:58:58 +00002681 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) );
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002682 /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
2683 * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
2684 return retvalue;
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002685}
2686
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002687
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002688/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002689 * IsChild (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002690 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002691BOOL WINAPI IsChild( HWND parent, HWND child )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002692{
Alexandre Julliard932a65d2005-01-31 16:46:47 +00002693 HWND *list = list_window_parents( child );
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002694 int i;
2695 BOOL ret;
2696
2697 if (!list) return FALSE;
Alexandre Julliardf44bbb82001-09-14 00:24:39 +00002698 parent = WIN_GetFullHandle( parent );
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002699 for (i = 0; list[i]; i++) if (list[i] == parent) break;
2700 ret = (list[i] != 0);
2701 HeapFree( GetProcessHeap(), 0, list );
2702 return ret;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002703}
2704
2705
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002706/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002707 * IsWindowVisible (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002708 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002709BOOL WINAPI IsWindowVisible( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002710{
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002711 HWND *list;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002712 BOOL retval;
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002713 int i;
2714
2715 if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)) return FALSE;
Alexandre Julliard932a65d2005-01-31 16:46:47 +00002716 if (!(list = list_window_parents( hwnd ))) return TRUE;
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002717 for (i = 0; list[i]; i++)
2718 if (!(GetWindowLongW( list[i], GWL_STYLE ) & WS_VISIBLE)) break;
2719 retval = !list[i];
2720 HeapFree( GetProcessHeap(), 0, list );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002721 return retval;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002722}
2723
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002724
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002725/***********************************************************************
2726 * WIN_IsWindowDrawable
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002727 *
2728 * hwnd is drawable when it is visible, all parents are not
2729 * minimized, and it is itself not minimized unless we are
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002730 * trying to draw its default class icon.
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002731 */
Alexandre Julliard8fd26b92001-10-15 17:56:45 +00002732BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL icon )
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002733{
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002734 HWND *list;
2735 BOOL retval;
2736 int i;
Alexandre Julliard8fd26b92001-10-15 17:56:45 +00002737 LONG style = GetWindowLongW( hwnd, GWL_STYLE );
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002738
Alexandre Julliard8fd26b92001-10-15 17:56:45 +00002739 if (!(style & WS_VISIBLE)) return FALSE;
Dmitry Timoshkov39f960b2005-02-15 21:51:06 +00002740 if ((style & WS_MINIMIZE) && icon && GetClassLongPtrW( hwnd, GCLP_HICON )) return FALSE;
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002741
Alexandre Julliard932a65d2005-01-31 16:46:47 +00002742 if (!(list = list_window_parents( hwnd ))) return TRUE;
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002743 for (i = 0; list[i]; i++)
2744 if ((GetWindowLongW( list[i], GWL_STYLE ) & (WS_VISIBLE|WS_MINIMIZE)) != WS_VISIBLE)
2745 break;
2746 retval = !list[i];
2747 HeapFree( GetProcessHeap(), 0, list );
2748 return retval;
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002749}
2750
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002751
Alexandre Julliard0e607781993-11-03 19:23:37 +00002752/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002753 * GetTopWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002754 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002755HWND WINAPI GetTopWindow( HWND hwnd )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002756{
Alexandre Julliardfa42aa82001-08-21 17:13:55 +00002757 if (!hwnd) hwnd = GetDesktopWindow();
2758 return GetWindow( hwnd, GW_CHILD );
Alexandre Julliard0e607781993-11-03 19:23:37 +00002759}
2760
2761
2762/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002763 * GetWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002764 */
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00002765HWND WINAPI GetWindow( HWND hwnd, UINT rel )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002766{
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00002767 HWND retval = 0;
Alexandre Julliard0d92fe22001-09-10 23:26:42 +00002768
Alexandre Julliardddc33172001-10-22 19:08:33 +00002769 if (rel == GW_OWNER) /* this one may be available locally */
Alexandre Julliard0e607781993-11-03 19:23:37 +00002770 {
Alexandre Julliardddc33172001-10-22 19:08:33 +00002771 WND *wndPtr = WIN_GetPtr( hwnd );
2772 if (!wndPtr)
2773 {
2774 SetLastError( ERROR_INVALID_HANDLE );
2775 return 0;
2776 }
2777 if (wndPtr != WND_OTHER_PROCESS)
2778 {
2779 retval = wndPtr->owner;
2780 WIN_ReleasePtr( wndPtr );
2781 return retval;
2782 }
2783 /* else fall through to server call */
Alexandre Julliard0e607781993-11-03 19:23:37 +00002784 }
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00002785
2786 SERVER_START_REQ( get_window_tree )
2787 {
2788 req->handle = hwnd;
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002789 if (!wine_server_call_err( req ))
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00002790 {
2791 switch(rel)
2792 {
2793 case GW_HWNDFIRST:
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002794 retval = reply->first_sibling;
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00002795 break;
2796 case GW_HWNDLAST:
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002797 retval = reply->last_sibling;
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00002798 break;
2799 case GW_HWNDNEXT:
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002800 retval = reply->next_sibling;
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00002801 break;
2802 case GW_HWNDPREV:
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002803 retval = reply->prev_sibling;
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00002804 break;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002805 case GW_OWNER:
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002806 retval = reply->owner;
Alexandre Julliardddc33172001-10-22 19:08:33 +00002807 break;
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00002808 case GW_CHILD:
Alexandre Julliard9caa71e2001-11-30 18:46:42 +00002809 retval = reply->first_child;
Alexandre Julliarda09da0c2001-09-21 21:08:40 +00002810 break;
2811 }
2812 }
2813 }
2814 SERVER_END_REQ;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002815 return retval;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002816}
2817
2818
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002819/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002820 * ShowOwnedPopups (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002821 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002822BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL fShow )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002823{
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002824 int count = 0;
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00002825 WND *pWnd;
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002826 HWND *win_array = WIN_ListChildren( GetDesktopWindow() );
Noomen Hamzaa018d851999-09-28 16:26:09 +00002827
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002828 if (!win_array) return TRUE;
Noomen Hamzaa018d851999-09-28 16:26:09 +00002829
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002830 while (win_array[count]) count++;
2831 while (--count >= 0)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002832 {
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00002833 if (GetWindow( win_array[count], GW_OWNER ) != owner) continue;
Alexandre Julliarde4e55662005-01-27 10:47:28 +00002834 if (!(pWnd = WIN_GetPtr( win_array[count] ))) continue;
2835 if (pWnd == WND_OTHER_PROCESS) continue;
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002836
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00002837 if (pWnd->dwStyle & WS_POPUP)
Noomen Hamzaff727762000-02-18 19:11:04 +00002838 {
2839 if (fShow)
2840 {
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002841 if (pWnd->flags & WIN_NEEDS_SHOW_OWNEDPOPUP)
Noomen Hamzaff727762000-02-18 19:11:04 +00002842 {
Alexandre Julliarde4e55662005-01-27 10:47:28 +00002843 pWnd->flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
2844 WIN_ReleasePtr( pWnd );
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002845 /* In Windows, ShowOwnedPopups(TRUE) generates
2846 * WM_SHOWWINDOW messages with SW_PARENTOPENING,
Louis Philippe Gagnon06057e72000-08-20 03:40:59 +00002847 * regardless of the state of the owner
2848 */
Alexandre Julliarde4e55662005-01-27 10:47:28 +00002849 SendMessageW(win_array[count], WM_SHOWWINDOW, SW_SHOW, SW_PARENTOPENING);
2850 continue;
Noomen Hamzaff727762000-02-18 19:11:04 +00002851 }
2852 }
2853 else
2854 {
Alexandre Julliarde4e55662005-01-27 10:47:28 +00002855 if (pWnd->dwStyle & WS_VISIBLE)
Noomen Hamzaff727762000-02-18 19:11:04 +00002856 {
Alexandre Julliarde4e55662005-01-27 10:47:28 +00002857 pWnd->flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
2858 WIN_ReleasePtr( pWnd );
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002859 /* In Windows, ShowOwnedPopups(FALSE) generates
2860 * WM_SHOWWINDOW messages with SW_PARENTCLOSING,
Louis Philippe Gagnon06057e72000-08-20 03:40:59 +00002861 * regardless of the state of the owner
2862 */
Alexandre Julliarde4e55662005-01-27 10:47:28 +00002863 SendMessageW(win_array[count], WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING);
2864 continue;
Noomen Hamzaff727762000-02-18 19:11:04 +00002865 }
2866 }
2867 }
Alexandre Julliarde4e55662005-01-27 10:47:28 +00002868 WIN_ReleasePtr( pWnd );
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002869 }
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002870 HeapFree( GetProcessHeap(), 0, win_array );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002871 return TRUE;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002872}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002873
2874
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002875/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002876 * GetLastActivePopup (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002877 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002878HWND WINAPI GetLastActivePopup( HWND hwnd )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002879{
Alexandre Julliard0b850f92002-10-12 01:23:05 +00002880 HWND retval = hwnd;
2881
2882 SERVER_START_REQ( get_window_info )
2883 {
2884 req->handle = hwnd;
2885 if (!wine_server_call_err( req )) retval = reply->last_active;
2886 }
2887 SERVER_END_REQ;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002888 return retval;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002889}
2890
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002891
2892/*******************************************************************
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002893 * WIN_ListChildren
2894 *
2895 * Build an array of the children of a given window. The array must be
2896 * freed with HeapFree. Returns NULL when no windows are found.
2897 */
2898HWND *WIN_ListChildren( HWND hwnd )
2899{
Alexandre Julliard844ceb92001-10-09 23:26:40 +00002900 return list_window_children( hwnd, 0, 0 );
Alexandre Julliard3051b641996-07-05 17:14:13 +00002901}
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002902
Alexandre Julliard3051b641996-07-05 17:14:13 +00002903
2904/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002905 * EnumWindows (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002906 */
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002907BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002908{
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002909 HWND *list;
2910 BOOL ret = TRUE;
2911 int i, iWndsLocks;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002912
Alexandre Julliard594997c1995-04-30 10:05:20 +00002913 /* We have to build a list of all windows first, to avoid */
Andreas Mohr1c20b392000-02-20 19:17:35 +00002914 /* unpleasant side-effects, for instance if the callback */
2915 /* function changes the Z-order of the windows. */
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002916
Tommy Schultz Lassen440adc12002-01-22 00:50:07 +00002917 if (!(list = WIN_ListChildren( GetDesktopWindow() ))) return TRUE;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002918
Alexandre Julliard3051b641996-07-05 17:14:13 +00002919 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002920
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002921 iWndsLocks = WIN_SuspendWndsLock();
2922 for (i = 0; list[i]; i++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002923 {
Alexandre Julliard3051b641996-07-05 17:14:13 +00002924 /* Make sure that the window still exists */
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002925 if (!IsWindow( list[i] )) continue;
2926 if (!(ret = lpEnumFunc( list[i], lParam ))) break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002927 }
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002928 WIN_RestoreWndsLock(iWndsLocks);
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002929 HeapFree( GetProcessHeap(), 0, list );
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002930 return ret;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002931}
2932
2933
Alexandre Julliard3051b641996-07-05 17:14:13 +00002934/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002935 * EnumThreadWindows (USER32.@)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002936 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002937BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002938{
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002939 HWND *list;
2940 int i, iWndsLocks;
2941
Alexandre Julliard4f716152002-10-17 18:21:29 +00002942 if (!(list = list_window_children( GetDesktopWindow(), 0, id ))) return TRUE;
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002943
2944 /* Now call the callback function for every window */
2945
2946 iWndsLocks = WIN_SuspendWndsLock();
2947 for (i = 0; list[i]; i++)
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002948 if (!func( list[i], lParam )) break;
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002949 WIN_RestoreWndsLock(iWndsLocks);
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002950 HeapFree( GetProcessHeap(), 0, list );
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002951 return TRUE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002952}
2953
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002954
Alexandre Julliard3051b641996-07-05 17:14:13 +00002955/**********************************************************************
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002956 * WIN_EnumChildWindows
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002957 *
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002958 * Helper function for EnumChildWindows().
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002959 */
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002960static BOOL WIN_EnumChildWindows( HWND *list, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002961{
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002962 HWND *childList;
2963 BOOL ret = FALSE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002964
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002965 for ( ; *list; list++)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002966 {
2967 /* Make sure that the window still exists */
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002968 if (!IsWindow( *list )) continue;
2969 /* skip owned windows */
2970 if (GetWindow( *list, GW_OWNER )) continue;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002971 /* Build children list first */
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002972 childList = WIN_ListChildren( *list );
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002973
2974 ret = func( *list, lParam );
Francois Boisvertd96bc151999-04-02 10:34:43 +00002975
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002976 if (childList)
2977 {
2978 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002979 HeapFree( GetProcessHeap(), 0, childList );
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002980 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002981 if (!ret) return FALSE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002982 }
2983 return TRUE;
2984}
2985
2986
2987/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002988 * EnumChildWindows (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002989 */
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002990BOOL WINAPI EnumChildWindows( HWND parent, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002991{
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002992 HWND *list;
2993 int iWndsLocks;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002994
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002995 if (!(list = WIN_ListChildren( parent ))) return FALSE;
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002996 iWndsLocks = WIN_SuspendWndsLock();
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002997 WIN_EnumChildWindows( list, func, lParam );
Alexandre Julliard4ff32c82001-08-18 18:08:26 +00002998 WIN_RestoreWndsLock(iWndsLocks);
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00002999 HeapFree( GetProcessHeap(), 0, list );
Alexandre Julliard3051b641996-07-05 17:14:13 +00003000 return TRUE;
3001}
3002
3003
Alexandre Julliard58199531994-04-21 01:20:00 +00003004/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003005 * AnyPopup (USER.52)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003006 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003007BOOL16 WINAPI AnyPopup16(void)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003008{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003009 return AnyPopup();
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003010}
3011
3012
3013/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003014 * AnyPopup (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003015 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003016BOOL WINAPI AnyPopup(void)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003017{
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00003018 int i;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003019 BOOL retvalue;
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00003020 HWND *list = WIN_ListChildren( GetDesktopWindow() );
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00003021
3022 if (!list) return FALSE;
3023 for (i = 0; list[i]; i++)
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003024 {
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00003025 if (IsWindowVisible( list[i] ) && GetWindow( list[i], GW_OWNER )) break;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003026 }
Alexandre Julliard0801ffc2001-08-24 00:26:59 +00003027 retvalue = (list[i] != 0);
Alexandre Julliard9d9dac02001-08-24 19:28:21 +00003028 HeapFree( GetProcessHeap(), 0, list );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003029 return retvalue;
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003030}
3031
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003032
Alexandre Julliard73450d61994-05-18 18:29:32 +00003033/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003034 * FlashWindow (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003035 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003036BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert )
Alexandre Julliard73450d61994-05-18 18:29:32 +00003037{
Alexandre Julliarde4e55662005-01-27 10:47:28 +00003038 WND *wndPtr;
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003039
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00003040 TRACE("%p\n", hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003041
Alexandre Julliarde4e55662005-01-27 10:47:28 +00003042 if (IsIconic( hWnd ))
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003043 {
Alexandre Julliard5defa492004-12-07 17:31:53 +00003044 RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_FRAME );
Alexandre Julliarde4e55662005-01-27 10:47:28 +00003045
3046 wndPtr = WIN_GetPtr(hWnd);
3047 if (!wndPtr || wndPtr == WND_OTHER_PROCESS) return FALSE;
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003048 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
3049 {
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003050 wndPtr->flags |= WIN_NCACTIVATED;
3051 }
3052 else
3053 {
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003054 wndPtr->flags &= ~WIN_NCACTIVATED;
3055 }
Alexandre Julliarde4e55662005-01-27 10:47:28 +00003056 WIN_ReleasePtr( wndPtr );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003057 return TRUE;
3058 }
3059 else
3060 {
Alexandre Julliarde4e55662005-01-27 10:47:28 +00003061 WPARAM wparam;
3062
3063 wndPtr = WIN_GetPtr(hWnd);
3064 if (!wndPtr || wndPtr == WND_OTHER_PROCESS) return FALSE;
3065 hWnd = wndPtr->hwndSelf; /* make it a full handle */
3066
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003067 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
Alexandre Julliard5030bda2002-10-11 23:41:06 +00003068 else wparam = (hWnd == GetForegroundWindow());
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003069
Alexandre Julliarde4e55662005-01-27 10:47:28 +00003070 WIN_ReleasePtr( wndPtr );
Alexandre Julliardf44bbb82001-09-14 00:24:39 +00003071 SendMessageW( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003072 return wparam;
3073 }
Alexandre Julliard73450d61994-05-18 18:29:32 +00003074}
3075
Mike McCormack0e27c972003-08-12 20:33:26 +00003076/*******************************************************************
3077 * FlashWindowEx (USER32.@)
3078 */
3079BOOL WINAPI FlashWindowEx( PFLASHWINFO pfwi )
3080{
3081 FIXME("%p\n", pfwi);
3082 return TRUE;
3083}
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003084
3085/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003086 * GetWindowContextHelpId (USER32.@)
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003087 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003088DWORD WINAPI GetWindowContextHelpId( HWND hwnd )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003089{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003090 DWORD retval;
Alexandre Julliard6382ffa2005-01-20 20:07:42 +00003091 WND *wnd = WIN_GetPtr( hwnd );
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003092 if (!wnd) return 0;
Alexandre Julliard6382ffa2005-01-20 20:07:42 +00003093 if (wnd == WND_OTHER_PROCESS)
3094 {
3095 if (IsWindow( hwnd )) FIXME( "not supported on other process window %p\n", hwnd );
3096 return 0;
3097 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003098 retval = wnd->helpContext;
Alexandre Julliard6382ffa2005-01-20 20:07:42 +00003099 WIN_ReleasePtr( wnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003100 return retval;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003101}
3102
3103
3104/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003105 * SetWindowContextHelpId (USER32.@)
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003106 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003107BOOL WINAPI SetWindowContextHelpId( HWND hwnd, DWORD id )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003108{
Alexandre Julliard6382ffa2005-01-20 20:07:42 +00003109 WND *wnd = WIN_GetPtr( hwnd );
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003110 if (!wnd) return FALSE;
Alexandre Julliard6382ffa2005-01-20 20:07:42 +00003111 if (wnd == WND_OTHER_PROCESS)
3112 {
3113 if (IsWindow( hwnd )) FIXME( "not supported on other process window %p\n", hwnd );
3114 return 0;
3115 }
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003116 wnd->helpContext = id;
Alexandre Julliard6382ffa2005-01-20 20:07:42 +00003117 WIN_ReleasePtr( wnd );
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003118 return TRUE;
3119}
3120
3121
3122/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003123 * DragDetect (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003124 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003125BOOL WINAPI DragDetect( HWND hWnd, POINT pt )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003126{
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003127 MSG msg;
3128 RECT rect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003129
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003130 rect.left = pt.x - wDragWidth;
3131 rect.right = pt.x + wDragWidth;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003132
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003133 rect.top = pt.y - wDragHeight;
3134 rect.bottom = pt.y + wDragHeight;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003135
Alexandre Julliarda3960291999-02-26 11:11:13 +00003136 SetCapture(hWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003137
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003138 while(1)
3139 {
Dmitry Timoshkov53ccd492005-02-18 20:01:41 +00003140 while (PeekMessageW( &msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003141 {
3142 if( msg.message == WM_LBUTTONUP )
3143 {
3144 ReleaseCapture();
3145 return 0;
3146 }
3147 if( msg.message == WM_MOUSEMOVE )
3148 {
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003149 POINT tmp;
3150 tmp.x = LOWORD(msg.lParam);
3151 tmp.y = HIWORD(msg.lParam);
3152 if( !PtInRect( &rect, tmp ))
Alexandre Julliardade697e1995-11-26 13:59:11 +00003153 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003154 ReleaseCapture();
3155 return 1;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003156 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003157 }
3158 }
3159 WaitMessage();
3160 }
3161 return 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003162}
3163
3164/******************************************************************************
Eric Kohlca6c9a62001-03-20 01:53:51 +00003165 * GetWindowModuleFileNameA (USER32.@)
3166 */
3167UINT WINAPI GetWindowModuleFileNameA( HWND hwnd, LPSTR lpszFileName, UINT cchFileNameMax)
3168{
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00003169 FIXME("GetWindowModuleFileNameA(hwnd %p, lpszFileName %p, cchFileNameMax %u) stub!\n",
Eric Kohlca6c9a62001-03-20 01:53:51 +00003170 hwnd, lpszFileName, cchFileNameMax);
3171 return 0;
3172}
3173
3174/******************************************************************************
3175 * GetWindowModuleFileNameW (USER32.@)
3176 */
Alexandre Julliardb7976c02003-11-26 04:09:00 +00003177UINT WINAPI GetWindowModuleFileNameW( HWND hwnd, LPWSTR lpszFileName, UINT cchFileNameMax)
Eric Kohlca6c9a62001-03-20 01:53:51 +00003178{
Alexandre Julliardaff7dda2002-11-22 21:22:14 +00003179 FIXME("GetWindowModuleFileNameW(hwnd %p, lpszFileName %p, cchFileNameMax %u) stub!\n",
Eric Kohlca6c9a62001-03-20 01:53:51 +00003180 hwnd, lpszFileName, cchFileNameMax);
3181 return 0;
3182}
David Hammertonca30e482002-05-06 20:11:18 +00003183
3184/******************************************************************************
3185 * GetWindowInfo (USER32.@)
Dmitry Timoshkovf7451682004-05-11 22:17:19 +00003186 *
3187 * Note: tests show that Windows doesn't check cbSize of the structure.
David Hammertonca30e482002-05-06 20:11:18 +00003188 */
3189BOOL WINAPI GetWindowInfo( HWND hwnd, PWINDOWINFO pwi)
3190{
David Hammertonca30e482002-05-06 20:11:18 +00003191 if (!pwi) return FALSE;
Dmitry Timoshkovcb84de92003-08-05 18:26:28 +00003192 if (!IsWindow(hwnd)) return FALSE;
David Hammertonca30e482002-05-06 20:11:18 +00003193
Dmitry Timoshkovcb84de92003-08-05 18:26:28 +00003194 GetWindowRect(hwnd, &pwi->rcWindow);
3195 GetClientRect(hwnd, &pwi->rcClient);
3196 /* translate to screen coordinates */
3197 MapWindowPoints(hwnd, 0, (LPPOINT)&pwi->rcClient, 2);
3198
3199 pwi->dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
3200 pwi->dwExStyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
David Hammertonca30e482002-05-06 20:11:18 +00003201 pwi->dwWindowStatus = ((GetActiveWindow() == hwnd) ? WS_ACTIVECAPTION : 0);
David Hammertonca30e482002-05-06 20:11:18 +00003202
Dmitry Timoshkovcb84de92003-08-05 18:26:28 +00003203 pwi->cxWindowBorders = pwi->rcClient.left - pwi->rcWindow.left;
3204 pwi->cyWindowBorders = pwi->rcWindow.bottom - pwi->rcClient.bottom;
David Hammertonca30e482002-05-06 20:11:18 +00003205
Dmitry Timoshkovcb84de92003-08-05 18:26:28 +00003206 pwi->atomWindowType = GetClassLongW( hwnd, GCW_ATOM );
3207 pwi->wCreatorVersion = 0x0400;
David Hammertonca30e482002-05-06 20:11:18 +00003208
David Hammertonca30e482002-05-06 20:11:18 +00003209 return TRUE;
3210}
Steven Edwards4d563e02004-09-14 19:29:11 +00003211
3212/******************************************************************************
3213 * SwitchDesktop (USER32.@)
3214 *
3215 * NOTES: Sets the current input or interactive desktop.
3216 */
3217BOOL WINAPI SwitchDesktop( HDESK hDesktop)
3218{
3219 FIXME("SwitchDesktop(hwnd %p) stub!\n", hDesktop);
3220 return TRUE;
3221}