blob: 99acd4bb084611f1235984151f1d2a8dac2d01e4 [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 Julliard401710d1993-09-04 10:09:32 +00005 */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00006
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00007#include <stdlib.h>
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00008#include <string.h>
Jeremy Whited3e22d92000-02-10 19:03:02 +00009#include "windef.h"
10#include "wingdi.h"
Marcus Meissner317af321999-02-17 13:51:06 +000011#include "wine/winbase16.h"
Michael Veksler9d14a001999-05-08 12:40:24 +000012#include "wine/winuser16.h"
Alexandre Julliard36ca1361994-06-02 22:38:20 +000013#include "options.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000014#include "class.h"
15#include "win.h"
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000016#include "heap.h"
Alexandre Julliardf0b23541993-09-29 12:21:49 +000017#include "user.h"
Alexandre Julliard5f721f81994-01-04 20:14:34 +000018#include "dce.h"
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000019#include "cursoricon.h"
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000020#include "hook.h"
Alexandre Julliard1285c2f1996-05-06 16:06:24 +000021#include "menu.h"
Alexandre Julliardef702d81996-05-28 18:54:58 +000022#include "message.h"
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000023#include "nonclient.h"
Alexandre Julliardb817f4f1996-03-14 18:08:34 +000024#include "queue.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000025#include "winpos.h"
Alexandre Julliard1e9ac791996-06-06 18:38:27 +000026#include "clipboard.h"
Alexandre Julliard2d93d001996-05-21 15:01:41 +000027#include "winproc.h"
Ulrich Weiganda8441891998-12-24 15:17:02 +000028#include "task.h"
Alexandre Julliard01d63461997-01-20 19:43:45 +000029#include "thread.h"
Alexandre Julliard767e6f61998-08-09 12:47:43 +000030#include "winerror.h"
Rein Klazes5c6fc1b1998-11-01 14:50:06 +000031#include "mdi.h"
Patrik Stridvall8d8703c1999-02-04 14:05:38 +000032#include "local.h"
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000033#include "syslevel.h"
Alexandre Julliard4220b291999-07-11 17:20:01 +000034#include "stackframe.h"
35#include "debugtools.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000036
Alexandre Julliardb8774f92000-05-30 17:50:41 +000037DEFAULT_DEBUG_CHANNEL(win);
38DECLARE_DEBUG_CHANNEL(msg);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000039
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000040/**********************************************************************/
41
42WND_DRIVER *WND_Driver = NULL;
Patrik Stridvalle35d6361998-12-07 09:13:40 +000043
Alexandre Julliard59730ae1996-03-24 16:20:51 +000044/* Desktop window */
45static WND *pWndDesktop = NULL;
46
Alexandre Julliarda3960291999-02-26 11:11:13 +000047static HWND hwndSysModal = 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +000048
Alexandre Julliardd4719651995-12-12 18:49:11 +000049static WORD wDragWidth = 4;
50static WORD wDragHeight= 3;
Alexandre Julliardade697e1995-11-26 13:59:11 +000051
Francois Boisvert93e3f901999-02-25 17:32:31 +000052/* thread safeness */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000053static SYSLEVEL WIN_SysLevel;
Francois Boisvert93e3f901999-02-25 17:32:31 +000054
55/***********************************************************************
Ulrich Weigandef61c0b1999-05-08 09:45:50 +000056 * WIN_Init
57 */
58void WIN_Init( void )
59{
60 /* Initialisation of the critical section for thread safeness */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000061 _CreateSysLevel( &WIN_SysLevel, 2 );
Ulrich Weigandef61c0b1999-05-08 09:45:50 +000062}
63
64/***********************************************************************
Francois Boisvert93e3f901999-02-25 17:32:31 +000065 * WIN_LockWnds
66 *
67 * Locks access to all WND structures for thread safeness
68 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000069void WIN_LockWnds( void )
Francois Boisvert93e3f901999-02-25 17:32:31 +000070{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000071 _EnterSysLevel( &WIN_SysLevel );
Francois Boisvert93e3f901999-02-25 17:32:31 +000072}
73
74/***********************************************************************
75 * WIN_UnlockWnds
76 *
77 * Unlocks access to all WND structures
78 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000079void WIN_UnlockWnds( void )
Ove Kaavenbcb4bb61999-05-12 10:07:02 +000080{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000081 _LeaveSysLevel( &WIN_SysLevel );
Francois Boisvert93e3f901999-02-25 17:32:31 +000082}
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000083
Francois Boisvert93e3f901999-02-25 17:32:31 +000084/***********************************************************************
85 * WIN_SuspendWndsLock
86 *
87 * Suspend the lock on WND structures.
88 * Returns the number of locks suspended
89 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000090int WIN_SuspendWndsLock( void )
Francois Boisvert93e3f901999-02-25 17:32:31 +000091{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000092 int isuspendedLocks = _ConfirmSysLevel( &WIN_SysLevel );
93 int count = isuspendedLocks;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +000094
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000095 while ( count-- > 0 )
96 _LeaveSysLevel( &WIN_SysLevel );
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +000097
Francois Boisvert93e3f901999-02-25 17:32:31 +000098 return isuspendedLocks;
Francois Boisvert93e3f901999-02-25 17:32:31 +000099}
100
101/***********************************************************************
102 * WIN_RestoreWndsLock
103 *
104 * Restore the suspended locks on WND structures
105 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +0000106void WIN_RestoreWndsLock( int ipreviousLocks )
Francois Boisvert93e3f901999-02-25 17:32:31 +0000107{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +0000108 while ( ipreviousLocks-- > 0 )
109 _EnterSysLevel( &WIN_SysLevel );
Francois Boisvert93e3f901999-02-25 17:32:31 +0000110}
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000111
Alexandre Julliard401710d1993-09-04 10:09:32 +0000112/***********************************************************************
113 * WIN_FindWndPtr
114 *
115 * Return a pointer to the WND structure corresponding to a HWND.
Alexandre Julliard401710d1993-09-04 10:09:32 +0000116 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000117WND * WIN_FindWndPtr( HWND hwnd )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000118{
119 WND * ptr;
120
Francois Boisvert93e3f901999-02-25 17:32:31 +0000121 if (!hwnd || HIWORD(hwnd)) goto error2;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000122 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000123 /* Lock all WND structures for thread safeness*/
124 WIN_LockWnds();
125 /*and increment destruction monitoring*/
Francois Boisvert93e3f901999-02-25 17:32:31 +0000126 ptr->irefCount++;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000127
Eric Pouechb9544f11999-02-14 14:09:42 +0000128 if (ptr->dwMagic != WND_MAGIC) goto error;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000129 if (ptr->hwndSelf != hwnd)
130 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000131 ERR("Can't happen: hwnd %04x self pointer is %04x\n",hwnd, ptr->hwndSelf );
Eric Pouechb9544f11999-02-14 14:09:42 +0000132 goto error;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000133 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000134 /* returns a locked pointer */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000135 return ptr;
Eric Pouechb9544f11999-02-14 14:09:42 +0000136 error:
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000137 /* Unlock all WND structures for thread safeness*/
138 WIN_UnlockWnds();
139 /* and decrement destruction monitoring value */
Francois Boisvert93e3f901999-02-25 17:32:31 +0000140 ptr->irefCount--;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000141
Francois Boisvert93e3f901999-02-25 17:32:31 +0000142error2:
Juergen Schmied1e0bc841999-02-28 11:08:13 +0000143 if ( hwnd!=0 )
144 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
Eric Pouechb9544f11999-02-14 14:09:42 +0000145 return NULL;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000146}
147
Francois Boisvert93e3f901999-02-25 17:32:31 +0000148/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000149 * WIN_LockWndPtr
150 *
151 * Use in case the wnd ptr is not initialized with WIN_FindWndPtr
152 * but by initWndPtr;
153 * Returns the locked initialisation pointer
154 */
155WND *WIN_LockWndPtr(WND *initWndPtr)
156{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000157 if(!initWndPtr) return 0;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000158
159 /* Lock all WND structures for thread safeness*/
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000160 WIN_LockWnds();
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000161 /*and increment destruction monitoring*/
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000162 initWndPtr->irefCount++;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000163
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000164 return initWndPtr;
165
166}
167
168/***********************************************************************
Francois Boisvert93e3f901999-02-25 17:32:31 +0000169 * WIN_ReleaseWndPtr
170 *
171 * Release the pointer to the WND structure.
172 */
173void WIN_ReleaseWndPtr(WND *wndPtr)
174{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000175 if(!wndPtr) return;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000176
177 /*Decrement destruction monitoring value*/
Francois Boisvert93e3f901999-02-25 17:32:31 +0000178 wndPtr->irefCount--;
Francois Boisvert86e2e111999-04-03 11:13:33 +0000179 /* Check if it's time to release the memory*/
180 if(wndPtr->irefCount == 0 && !wndPtr->dwMagic)
Francois Boisvert93e3f901999-02-25 17:32:31 +0000181 {
Francois Boisvert86e2e111999-04-03 11:13:33 +0000182 /* Release memory */
183 USER_HEAP_FREE( wndPtr->hwndSelf);
Francis Beaudet48126471999-05-22 19:21:01 +0000184 wndPtr->hwndSelf = 0;
Francois Boisvert93e3f901999-02-25 17:32:31 +0000185 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000186 else if(wndPtr->irefCount < 0)
187 {
188 /* This else if is useful to monitor the WIN_ReleaseWndPtr function */
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000189 ERR("forgot a Lock on %p somewhere\n",wndPtr);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000190 }
191 /*unlock all WND structures for thread safeness*/
Francois Boisvert93e3f901999-02-25 17:32:31 +0000192 WIN_UnlockWnds();
Francois Boisvert93e3f901999-02-25 17:32:31 +0000193}
194
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000195/***********************************************************************
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000196 * WIN_UpdateWndPtr
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000197 *
198 * Updates the value of oldPtr to newPtr.
199 */
200void WIN_UpdateWndPtr(WND **oldPtr, WND *newPtr)
201{
202 WND *tmpWnd = NULL;
203
204 tmpWnd = WIN_LockWndPtr(newPtr);
205 WIN_ReleaseWndPtr(*oldPtr);
206 *oldPtr = tmpWnd;
207
208}
Alexandre Julliard401710d1993-09-04 10:09:32 +0000209
210/***********************************************************************
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000211 * WIN_DumpWindow
212 *
213 * Dump the content of a window structure to stderr.
214 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000215void WIN_DumpWindow( HWND hwnd )
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000216{
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000217 WND *ptr;
218 char className[80];
219 int i;
220
221 if (!(ptr = WIN_FindWndPtr( hwnd )))
222 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000223 WARN("%04x is not a window handle\n", hwnd );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000224 return;
225 }
226
Alexandre Julliarda3960291999-02-26 11:11:13 +0000227 if (!GetClassNameA( hwnd, className, sizeof(className ) ))
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000228 strcpy( className, "#NULL#" );
229
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000230 TRACE("Window %04x (%p):\n", hwnd, ptr );
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000231 DPRINTF( "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000232 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000233 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000234 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000235 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000236 ptr->next, ptr->child, ptr->parent, ptr->owner,
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000237 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000238 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000239 ptr->dwStyle, ptr->dwExStyle, (UINT)ptr->winproc,
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +0000240 ptr->text ? debugstr_w(ptr->text) : "",
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000241 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
242 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000243 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000244 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000245
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000246 if (ptr->class->cbWndExtra)
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000247 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000248 DPRINTF( "extra bytes:" );
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000249 for (i = 0; i < ptr->class->cbWndExtra; i++)
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000250 DPRINTF( " %02x", *((BYTE*)ptr->wExtra+i) );
251 DPRINTF( "\n" );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000252 }
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000253 DPRINTF( "\n" );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000254 WIN_ReleaseWndPtr(ptr);
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000255}
256
257
258/***********************************************************************
259 * WIN_WalkWindows
260 *
261 * Walk the windows tree and print each window on stderr.
262 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000263void WIN_WalkWindows( HWND hwnd, int indent )
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000264{
265 WND *ptr;
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000266 char className[80];
267
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000268 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : WIN_GetDesktop();
269
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000270 if (!ptr)
271 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000272 WARN("Invalid window handle %04x\n", hwnd );
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000273 return;
274 }
275
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000276 if (!indent) /* first time around */
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000277 DPRINTF( "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
Rein Klazesd62c62b1998-10-11 14:05:34 +0000278 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc"
279 " Text");
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000280
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000281 while (ptr)
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000282 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000283 DPRINTF( "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000284
Alexandre Julliardb849d792000-02-13 13:56:13 +0000285 GlobalGetAtomNameA(ptr->class->atomName,className,sizeof(className));
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000286
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000287 DPRINTF( "%08lx %-6.4x %-17.17s %08x %08x %.14s\n",
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000288 (DWORD)ptr, ptr->hmemTaskQ, className,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000289 (UINT)ptr->dwStyle, (UINT)ptr->winproc,
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +0000290 ptr->text ? debugstr_w(ptr->text) : "<null>");
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000291
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000292 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000293 WIN_UpdateWndPtr(&ptr,ptr->next);
294
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000295 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000296
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000297}
298
Alexandre Julliardaca05781994-10-17 18:12:41 +0000299/***********************************************************************
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000300 * WIN_UnlinkWindow
301 *
302 * Remove a window from the siblings linked list.
303 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000304BOOL WIN_UnlinkWindow( HWND hwnd )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000305{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000306 WND *wndPtr, **ppWnd;
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000307 BOOL ret = FALSE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000308
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000309 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
310 else if(!wndPtr->parent)
311 {
312 WIN_ReleaseWndPtr(wndPtr);
313 return FALSE;
314 }
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000315
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000316 ppWnd = &wndPtr->parent->child;
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000317 while (*ppWnd && *ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
318 if (*ppWnd)
319 {
320 *ppWnd = wndPtr->next;
321 ret = TRUE;
322 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000323 WIN_ReleaseWndPtr(wndPtr);
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000324 return ret;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000325}
326
327
328/***********************************************************************
329 * WIN_LinkWindow
330 *
331 * Insert a window into the siblings linked list.
332 * The window is inserted after the specified window, which can also
333 * be specified as HWND_TOP or HWND_BOTTOM.
334 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000335BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000336{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000337 WND *wndPtr, **ppWnd;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000338
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000339 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
340 else if(!wndPtr->parent)
341 {
342 WIN_ReleaseWndPtr(wndPtr);
343 return FALSE;
344 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000345 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
346 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000347 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000348 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000349 while (*ppWnd) ppWnd = &(*ppWnd)->next;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000350 }
351 else /* Normal case */
352 {
353 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000354 if (!afterPtr)
355 {
356 WIN_ReleaseWndPtr(wndPtr);
357 return FALSE;
358 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000359 ppWnd = &afterPtr->next;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000360 WIN_ReleaseWndPtr(afterPtr);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000361 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000362 wndPtr->next = *ppWnd;
363 *ppWnd = wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000364 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000365 return TRUE;
366}
367
368
369/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000370 * WIN_FindWinToRepaint
371 *
372 * Find a window that needs repaint.
373 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000374HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE16 hQueue )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000375{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000376 HWND hwndRet;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000377 WND *pWnd;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000378
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000379 /* Note: the desktop window never gets WM_PAINT messages
380 * The real reason why is because Windows DesktopWndProc
381 * does ValidateRgn inside WM_ERASEBKGND handler.
382 */
383
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000384 pWnd = hwnd ? WIN_FindWndPtr(hwnd) : WIN_LockWndPtr(pWndDesktop->child);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000385
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000386 for ( ; pWnd ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard401710d1993-09-04 10:09:32 +0000387 {
Alexandre Julliarde658d821997-11-30 17:45:40 +0000388 if (!(pWnd->dwStyle & WS_VISIBLE))
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000389 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000390 TRACE("skipping window %04x\n",
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000391 pWnd->hwndSelf );
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000392 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000393 else if ((pWnd->hmemTaskQ == hQueue) &&
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000394 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)))
395 break;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000396
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000397 else if (pWnd->child )
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000398 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000399 {
400 WIN_ReleaseWndPtr(pWnd);
401 return hwndRet;
402 }
403
Alexandre Julliard401710d1993-09-04 10:09:32 +0000404 }
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000405
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000406 if(!pWnd)
407 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000408 return 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000409 }
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000410
411 hwndRet = pWnd->hwndSelf;
412
413 /* look among siblings if we got a transparent window */
414 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
415 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
416 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000417 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000418 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000419 if (pWnd)
420 {
421 hwndRet = pWnd->hwndSelf;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000422 WIN_ReleaseWndPtr(pWnd);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000423 }
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000424 TRACE("found %04x\n",hwndRet);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000425 return hwndRet;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000426}
427
428
429/***********************************************************************
Alexandre Julliardaca05781994-10-17 18:12:41 +0000430 * WIN_DestroyWindow
431 *
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000432 * Destroy storage associated to a window. "Internals" p.358
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000433 * returns a locked wndPtr->next
Alexandre Julliardaca05781994-10-17 18:12:41 +0000434 */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000435static WND* WIN_DestroyWindow( WND* wndPtr )
Alexandre Julliardaca05781994-10-17 18:12:41 +0000436{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000437 HWND hwnd = wndPtr->hwndSelf;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000438 WND *pWnd;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000439
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000440 TRACE("%04x\n", wndPtr->hwndSelf );
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000441
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000442 /* free child windows */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000443 WIN_LockWndPtr(wndPtr->child);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000444 while ((pWnd = wndPtr->child))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000445 {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000446 wndPtr->child = WIN_DestroyWindow( pWnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000447 WIN_ReleaseWndPtr(pWnd);
448 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000449
Francis Beaudet7c2f0fe1999-03-21 08:50:41 +0000450 /*
451 * Clear the update region to make sure no WM_PAINT messages will be
452 * generated for this window while processing the WM_NCDESTROY.
453 */
454 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
455 {
456 if (wndPtr->hrgnUpdate > 1)
457 DeleteObject( wndPtr->hrgnUpdate );
458
459 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
460
461 wndPtr->hrgnUpdate = 0;
462 }
463
464 /*
465 * Send the WM_NCDESTROY to the window being destroyed.
466 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000467 SendMessageA( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000468
469 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
470
Noel Borthwickb4278561999-02-05 10:37:53 +0000471 WINPOS_CheckInternalPos( wndPtr );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000472 if( hwnd == GetCapture()) ReleaseCapture();
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000473
474 /* free resources associated with the window */
475
476 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000477 PROPERTY_RemoveWindowProps( wndPtr );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000478
Alexandre Julliardaca05781994-10-17 18:12:41 +0000479 wndPtr->dwMagic = 0; /* Mark it as invalid */
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000480
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000481 /* toss stale messages from the queue */
482
483 if( wndPtr->hmemTaskQ )
Alexandre Julliardaca05781994-10-17 18:12:41 +0000484 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000485 BOOL bPostQuit = FALSE;
486 WPARAM wQuitParam = 0;
Stephane Lussier1c4786f1999-01-28 10:54:11 +0000487 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) QUEUE_Lock(wndPtr->hmemTaskQ);
Stephane Lussiera4c84451999-01-26 09:30:05 +0000488 QMSG *qmsg;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000489
Stephane Lussiera4c84451999-01-26 09:30:05 +0000490 while( (qmsg = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != 0 )
Alexandre Julliard491502b1997-11-01 19:08:16 +0000491 {
Stephane Lussiera4c84451999-01-26 09:30:05 +0000492 if( qmsg->msg.message == WM_QUIT )
Alexandre Julliard491502b1997-11-01 19:08:16 +0000493 {
494 bPostQuit = TRUE;
Stephane Lussiera4c84451999-01-26 09:30:05 +0000495 wQuitParam = qmsg->msg.wParam;
Alexandre Julliard491502b1997-11-01 19:08:16 +0000496 }
Stephane Lussiera4c84451999-01-26 09:30:05 +0000497 QUEUE_RemoveMsg(msgQ, qmsg);
Alexandre Julliard491502b1997-11-01 19:08:16 +0000498 }
Stephane Lussier1c4786f1999-01-28 10:54:11 +0000499
500 QUEUE_Unlock(msgQ);
501
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +0000502 /* repost WM_QUIT to make sure this app exits its message loop */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000503 if( bPostQuit ) PostQuitMessage(wQuitParam);
Alexandre Julliard491502b1997-11-01 19:08:16 +0000504 wndPtr->hmemTaskQ = 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000505 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000506
507 if (!(wndPtr->dwStyle & WS_CHILD))
Guy Albertelli38db0982000-05-11 00:06:38 +0000508 if (wndPtr->wIDmenu)
509 {
510 DestroyMenu( wndPtr->wIDmenu );
511 wndPtr->wIDmenu = 0;
512 }
513 if (wndPtr->hSysMenu)
514 {
515 DestroyMenu( wndPtr->hSysMenu );
516 wndPtr->hSysMenu = 0;
517 }
Patrik Stridvalle35d6361998-12-07 09:13:40 +0000518 wndPtr->pDriver->pDestroyWindow( wndPtr );
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000519 DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000520 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000521 wndPtr->class->cWindows--;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000522 wndPtr->class = NULL;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000523
524 WIN_UpdateWndPtr(&pWnd,wndPtr->next);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000525
Patrik Stridvall151170c1998-12-26 12:00:43 +0000526 wndPtr->pDriver->pFinalize(wndPtr);
Francois Boisvert86e2e111999-04-03 11:13:33 +0000527
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000528 return pWnd;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000529}
530
Alexandre Julliardaca05781994-10-17 18:12:41 +0000531/***********************************************************************
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000532 * WIN_ResetQueueWindows
Alexandre Julliard77b99181997-09-14 17:17:23 +0000533 *
534 * Reset the queue of all the children of a given window.
535 * Return TRUE if something was done.
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000536 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000537BOOL WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000538{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000539 BOOL ret = FALSE;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000540
Alexandre Julliard77b99181997-09-14 17:17:23 +0000541 if (hNew) /* Set a new queue */
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000542 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000543 for (wnd = WIN_LockWndPtr(wnd->child); (wnd);WIN_UpdateWndPtr(&wnd,wnd->next))
Alexandre Julliard77b99181997-09-14 17:17:23 +0000544 {
545 if (wnd->hmemTaskQ == hQueue)
546 {
547 wnd->hmemTaskQ = hNew;
548 ret = TRUE;
549 }
550 if (wnd->child)
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000551 {
Ulrich Weigand7af95ae1998-12-07 10:24:42 +0000552 ret |= WIN_ResetQueueWindows( wnd, hQueue, hNew );
Alexandre Julliard77b99181997-09-14 17:17:23 +0000553 }
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000554 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000555 }
Alexandre Julliard77b99181997-09-14 17:17:23 +0000556 else /* Queue is being destroyed */
557 {
558 while (wnd->child)
559 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000560 WND *tmp = WIN_LockWndPtr(wnd->child);
561 WND *tmp2;
Alexandre Julliard77b99181997-09-14 17:17:23 +0000562 ret = FALSE;
563 while (tmp)
564 {
565 if (tmp->hmemTaskQ == hQueue)
566 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000567 DestroyWindow( tmp->hwndSelf );
Alexandre Julliard77b99181997-09-14 17:17:23 +0000568 ret = TRUE;
569 break;
570 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000571 tmp2 = WIN_LockWndPtr(tmp->child);
572 if (tmp2 && WIN_ResetQueueWindows(tmp2,hQueue,0))
Alexandre Julliard77b99181997-09-14 17:17:23 +0000573 ret = TRUE;
574 else
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000575 {
576 WIN_UpdateWndPtr(&tmp,tmp->next);
577 }
578 WIN_ReleaseWndPtr(tmp2);
Alexandre Julliard77b99181997-09-14 17:17:23 +0000579 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000580 WIN_ReleaseWndPtr(tmp);
Alexandre Julliard77b99181997-09-14 17:17:23 +0000581 if (!ret) break;
582 }
583 }
584 return ret;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000585}
586
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000587/***********************************************************************
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000588 * WIN_CreateDesktopWindow
589 *
590 * Create the desktop window.
591 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000592BOOL WIN_CreateDesktopWindow(void)
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000593{
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000594 CLASS *class;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000595 HWND hwndDesktop;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000596
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000597 TRACE("Creating desktop window\n");
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000598
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000599
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000600 if (!ICONTITLE_Init() ||
601 !WINPOS_CreateInternalPosAtom() ||
602 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000603 return FALSE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000604
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000605 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000606 if (!hwndDesktop) return FALSE;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000607 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000608
Alexandre Julliard28c3a1b2000-03-20 18:21:19 +0000609 pWndDesktop->pDriver = WND_Driver;
Patrik Stridvall151170c1998-12-26 12:00:43 +0000610 pWndDesktop->pDriver->pInitialize(pWndDesktop);
611
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000612 pWndDesktop->next = NULL;
613 pWndDesktop->child = NULL;
614 pWndDesktop->parent = NULL;
615 pWndDesktop->owner = NULL;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000616 pWndDesktop->class = class;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000617 pWndDesktop->dwMagic = WND_MAGIC;
618 pWndDesktop->hwndSelf = hwndDesktop;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000619 pWndDesktop->hInstance = 0;
620 pWndDesktop->rectWindow.left = 0;
621 pWndDesktop->rectWindow.top = 0;
Marcus Meissnerddca3151999-05-22 11:33:23 +0000622 pWndDesktop->rectWindow.right = GetSystemMetrics(SM_CXSCREEN);
623 pWndDesktop->rectWindow.bottom = GetSystemMetrics(SM_CYSCREEN);
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000624 pWndDesktop->rectClient = pWndDesktop->rectWindow;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000625 pWndDesktop->text = NULL;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000626 pWndDesktop->hmemTaskQ = GetFastQueue16();
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000627 pWndDesktop->hrgnUpdate = 0;
628 pWndDesktop->hwndLastActive = hwndDesktop;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000629 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
630 WS_CLIPSIBLINGS;
631 pWndDesktop->dwExStyle = 0;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000632 pWndDesktop->dce = NULL;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000633 pWndDesktop->pVScroll = NULL;
634 pWndDesktop->pHScroll = NULL;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000635 pWndDesktop->pProp = NULL;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000636 pWndDesktop->wIDmenu = 0;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000637 pWndDesktop->helpContext = 0;
Alex Korobka98447491999-05-08 17:57:09 +0000638 pWndDesktop->flags = Options.desktopGeometry ? WIN_NATIVE : 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000639 pWndDesktop->hSysMenu = 0;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000640 pWndDesktop->userdata = 0;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000641 pWndDesktop->winproc = (WNDPROC16)class->winproc;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000642 pWndDesktop->irefCount = 0;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000643
Patrik Stridvalle35d6361998-12-07 09:13:40 +0000644 /* FIXME: How do we know if it should be Unicode or not */
645 if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop, class, FALSE))
646 return FALSE;
647
Alexandre Julliarda3960291999-02-26 11:11:13 +0000648 SendMessageA( hwndDesktop, WM_NCCREATE, 0, 0 );
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000649 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000650 return TRUE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000651}
652
653
654/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000655 * WIN_CreateWindowEx
656 *
Gerard Patel78f52b52000-05-31 19:23:20 +0000657 * Fix the coordinates - Helper for WIN_CreateWindowEx.
658 * returns default show mode in sw.
659 * Note: the feature presented as undocumented *is* in the MSDN since 1993.
660 */
661static void WIN_FixCoordinates( CREATESTRUCTA *cs, INT *sw)
662{
663 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16 ||
664 cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
665 {
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000666 if (cs->style & (WS_CHILD | WS_POPUP))
Gerard Patel78f52b52000-05-31 19:23:20 +0000667 {
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000668 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16) cs->x = cs->y = 0;
669 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16) cs->cx = cs->cy = 0;
Gerard Patel78f52b52000-05-31 19:23:20 +0000670 }
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000671 else /* overlapped window */
Gerard Patel78f52b52000-05-31 19:23:20 +0000672 {
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000673 STARTUPINFOA info;
674
675 GetStartupInfoA( &info );
676
677 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
678 {
679 /* Never believe Microsoft's documentation... CreateWindowEx doc says
680 * that if an overlapped window is created with WS_VISIBLE style bit
681 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
682 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
683 * reveals that
684 *
685 * 1) not only it checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
686 * 2) it does not ignore the y parameter as the docs claim; instead, it
687 * uses it as second parameter to ShowWindow() unless y is either
688 * CW_USEDEFAULT or CW_USEDEFAULT16.
689 *
690 * The fact that we didn't do 2) caused bogus windows pop up when wine
691 * was running apps that were using this obscure feature. Example -
692 * calc.exe that comes with Win98 (only Win98, it's different from
693 * the one that comes with Win95 and NT)
694 */
695 if (cs->y != CW_USEDEFAULT && cs->y != CW_USEDEFAULT16) *sw = cs->y;
696 cs->x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
697 cs->y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
698 }
699
700 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
701 {
702 if (info.dwFlags & STARTF_USESIZE)
703 {
704 cs->cx = info.dwXSize;
705 cs->cy = info.dwYSize;
706 }
707 else /* if no other hint from the app, pick 3/4 of the screen real estate */
708 {
709 RECT r;
710 SystemParametersInfoA( SPI_GETWORKAREA, 0, &r, 0);
711 cs->cx = (((r.right - r.left) * 3) / 4) - cs->x;
712 cs->cy = (((r.bottom - r.top) * 3) / 4) - cs->y;
713 }
714 }
Gerard Patel78f52b52000-05-31 19:23:20 +0000715 }
716 }
717}
718
719/***********************************************************************
720 * WIN_CreateWindowEx
721 *
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000722 * Implementation of CreateWindowEx().
Alexandre Julliard401710d1993-09-04 10:09:32 +0000723 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000724static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
725 BOOL win32, BOOL unicode )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000726{
Slava Monicha27807d1999-06-05 11:46:35 +0000727 INT sw = SW_SHOW;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000728 CLASS *classPtr;
Alexandre Julliardd2e1c1a1996-03-09 16:12:43 +0000729 WND *wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000730 HWND retvalue;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000731 HWND16 hwnd, hwndLinkAfter;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000732 POINT maxSize, maxPos, minTrack, maxTrack;
733 LRESULT (CALLBACK *localSend32)(HWND, UINT, WPARAM, LPARAM);
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000734
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000735 TRACE("%s %s %08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000736 unicode ? debugres_w((LPWSTR)cs->lpszName) : debugres_a(cs->lpszName),
737 unicode ? debugres_w((LPWSTR)cs->lpszClass) : debugres_a(cs->lpszClass),
738 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
739 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000740
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000741 /* Find the parent window */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000742
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000743 if (cs->hwndParent)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000744 {
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000745 /* Make sure parent is valid */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000746 if (!IsWindow( cs->hwndParent ))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000747 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000748 WARN("Bad parent %04x\n", cs->hwndParent );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000749 return 0;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000750 }
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000751 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000752 WARN("No parent for child window\n" );
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000753 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000754 }
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000755
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000756 /* Find the window class */
Alexandre Julliard77b99181997-09-14 17:17:23 +0000757 if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
Alexandre Julliard808cb041995-08-17 17:11:36 +0000758 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +0000759 WARN("Bad class '%s'\n", cs->lpszClass );
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000760 return 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000761 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000762
Gerard Patel78f52b52000-05-31 19:23:20 +0000763 WIN_FixCoordinates(cs, &sw); /* fix default coordinates */
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000764
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000765 /* Create the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000766
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000767 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
768 - sizeof(wndPtr->wExtra) )))
769 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000770 TRACE("out of memory\n" );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000771 return 0;
772 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000773
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000774 /* Fill the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000775
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000776 wndPtr = WIN_LockWndPtr((WND *) USER_HEAP_LIN_ADDR( hwnd ));
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000777 wndPtr->next = NULL;
778 wndPtr->child = NULL;
779
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000780 if ((cs->style & WS_CHILD) && cs->hwndParent)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000781 {
782 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
783 wndPtr->owner = NULL;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000784 WIN_ReleaseWndPtr(wndPtr->parent);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000785 }
786 else
787 {
788 wndPtr->parent = pWndDesktop;
789 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
790 wndPtr->owner = NULL;
791 else
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000792 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000793 WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
794 wndPtr->owner = WIN_GetTopParentPtr(tmpWnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000795 WIN_ReleaseWndPtr(wndPtr->owner);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000796 WIN_ReleaseWndPtr(tmpWnd);
Slava Monicha27807d1999-06-05 11:46:35 +0000797 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000798 }
Slava Monicha27807d1999-06-05 11:46:35 +0000799
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000800
Patrik Stridvall151170c1998-12-26 12:00:43 +0000801 wndPtr->pDriver = wndPtr->parent->pDriver;
802 wndPtr->pDriver->pInitialize(wndPtr);
803
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000804 wndPtr->class = classPtr;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000805 wndPtr->winproc = classPtr->winproc;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000806 wndPtr->dwMagic = WND_MAGIC;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000807 wndPtr->hwndSelf = hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000808 wndPtr->hInstance = cs->hInstance;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000809 wndPtr->text = NULL;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000810 wndPtr->hmemTaskQ = GetFastQueue16();
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000811 wndPtr->hrgnUpdate = 0;
Huw D M Daviesa14ca862000-07-29 11:31:29 +0000812 wndPtr->hrgnWnd = 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000813 wndPtr->hwndLastActive = hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000814 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
815 wndPtr->dwExStyle = cs->dwExStyle;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000816 wndPtr->wIDmenu = 0;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000817 wndPtr->helpContext = 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000818 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000819 wndPtr->pVScroll = NULL;
820 wndPtr->pHScroll = NULL;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000821 wndPtr->pProp = NULL;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000822 wndPtr->userdata = 0;
Alexandre Julliard7ff1c411997-05-25 13:58:18 +0000823 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
824 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000825 wndPtr->irefCount = 1;
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000826
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000827 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000828
829 /* Call the WH_CBT hook */
830
NF Stevens181fa7c1998-12-14 14:37:06 +0000831 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
832 ? HWND_BOTTOM : HWND_TOP;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000833
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000834 if (HOOK_IsHooked( WH_CBT ))
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000835 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000836 CBT_CREATEWNDA cbtc;
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000837 LRESULT ret;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000838
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000839 cbtc.lpcs = cs;
840 cbtc.hwndInsertAfter = hwndLinkAfter;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000841 ret = unicode ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc)
842 : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc);
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000843 if (ret)
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000844 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000845 TRACE("CBT-hook returned 0\n");
Patrik Stridvall151170c1998-12-26 12:00:43 +0000846 wndPtr->pDriver->pFinalize(wndPtr);
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000847 USER_HEAP_FREE( hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000848 retvalue = 0;
849 goto end;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000850 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000851 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000852
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000853 /* Increment class window counter */
Alexandre Julliard3051b641996-07-05 17:14:13 +0000854
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000855 classPtr->cWindows++;
Alexandre Julliard3051b641996-07-05 17:14:13 +0000856
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000857 /* Correct the window style */
858
Alex Korobka44a1b591999-04-01 12:03:52 +0000859 if (!(cs->style & WS_CHILD))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000860 {
Alex Korobka44a1b591999-04-01 12:03:52 +0000861 wndPtr->dwStyle |= WS_CLIPSIBLINGS;
862 if (!(cs->style & WS_POPUP))
863 {
864 wndPtr->dwStyle |= WS_CAPTION;
865 wndPtr->flags |= WIN_NEED_SIZE;
866 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000867 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000868
869 /* Get class or window DC if needed */
Alexandre Julliardaca05781994-10-17 18:12:41 +0000870
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000871 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
872 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
873 else wndPtr->dce = NULL;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000874
Alexandre Julliard5e9dab52000-06-07 02:03:19 +0000875 /* Initialize the dimensions before sending WM_GETMINMAXINFO */
876
877 wndPtr->rectWindow.left = cs->x;
878 wndPtr->rectWindow.top = cs->y;
879 wndPtr->rectWindow.right = cs->x + cs->cx;
880 wndPtr->rectWindow.bottom = cs->y + cs->cy;
881 wndPtr->rectClient = wndPtr->rectWindow;
882
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000883 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
Alexandre Julliard988ca971994-06-21 16:15:21 +0000884
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000885 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000886 {
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000887 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000888 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
889 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000890 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
891 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000892 }
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000893
Lawson Whitney68dd6792000-06-25 12:53:27 +0000894 if (cs->cx < 0) cs->cx = 0;
895 if (cs->cy < 0) cs->cy = 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000896
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000897 wndPtr->rectWindow.left = cs->x;
898 wndPtr->rectWindow.top = cs->y;
899 wndPtr->rectWindow.right = cs->x + cs->cx;
900 wndPtr->rectWindow.bottom = cs->y + cs->cy;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000901 wndPtr->rectClient = wndPtr->rectWindow;
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000902
Patrik Stridvalle35d6361998-12-07 09:13:40 +0000903 if(!wndPtr->pDriver->pCreateWindow(wndPtr, classPtr, cs, unicode))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000904 {
905 retvalue = FALSE;
906 goto end;
907 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000908
909 /* Set the window menu */
910
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000911 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000912 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000913 if (cs->hMenu) SetMenu(hwnd, cs->hMenu);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000914 else
915 {
916#if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
917 if (classPtr->menuNameA)
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000918 cs->hMenu = HIWORD(classPtr->menuNameA) ?
919 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
920 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000921#else
Alexandre Julliard77b99181997-09-14 17:17:23 +0000922 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
Alexandre Julliard54c27111998-03-29 19:44:57 +0000923 if (menuName)
924 {
Ulrich Weigand7df1fbb1998-11-01 18:01:53 +0000925 if (HIWORD(cs->hInstance))
Alexandre Julliarda3960291999-02-26 11:11:13 +0000926 cs->hMenu = LoadMenuA(cs->hInstance,PTR_SEG_TO_LIN(menuName));
Alexandre Julliard54c27111998-03-29 19:44:57 +0000927 else
Alexandre Julliard54c27111998-03-29 19:44:57 +0000928 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
929
Alexandre Julliarda3960291999-02-26 11:11:13 +0000930 if (cs->hMenu) SetMenu( hwnd, cs->hMenu );
Alexandre Julliard54c27111998-03-29 19:44:57 +0000931 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000932#endif
933 }
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000934 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000935 else wndPtr->wIDmenu = (UINT)cs->hMenu;
Alexandre Julliard490a27e1994-06-08 13:57:50 +0000936
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000937 /* Send the WM_CREATE message
938 * Perhaps we shouldn't allow width/height changes as well.
939 * See p327 in "Internals".
940 */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000941
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000942 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000943
Alexandre Julliarda3960291999-02-26 11:11:13 +0000944 localSend32 = unicode ? SendMessageW : SendMessageA;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000945 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000946 {
Rein Klazesbf1bc511998-10-31 12:09:32 +0000947 /* Insert the window in the linked list */
948
949 WIN_LinkWindow( hwnd, hwndLinkAfter );
950
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000951 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
952 NULL, NULL, 0, &wndPtr->rectClient );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000953 OffsetRect(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000954 maxPos.y - wndPtr->rectWindow.top);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000955 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
956 {
957 /* Send the size messages */
958
959 if (!(wndPtr->flags & WIN_NEED_SIZE))
960 {
961 /* send it anyway */
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000962 if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
963 ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000964 WARN("sending bogus WM_SIZE message 0x%08lx\n",
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000965 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
966 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
Alexandre Julliarda3960291999-02-26 11:11:13 +0000967 SendMessageA( hwnd, WM_SIZE, SIZE_RESTORED,
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000968 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
969 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
Alexandre Julliarda3960291999-02-26 11:11:13 +0000970 SendMessageA( hwnd, WM_MOVE, 0,
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000971 MAKELONG( wndPtr->rectClient.left,
972 wndPtr->rectClient.top ) );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000973 }
974
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000975 /* Show the window, maximizing or minimizing if needed */
976
Alexandre Julliard77b99181997-09-14 17:17:23 +0000977 if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000978 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000979 RECT16 newPos;
Alexandre Julliard77b99181997-09-14 17:17:23 +0000980 UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000981 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
Alexandre Julliard77b99181997-09-14 17:17:23 +0000982 WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000983 swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow())
NF Stevens181fa7c1998-12-14 14:37:06 +0000984 ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
985 : SWP_NOZORDER | SWP_FRAMECHANGED;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000986 SetWindowPos( hwnd, 0, newPos.left, newPos.top,
NF Stevens181fa7c1998-12-14 14:37:06 +0000987 newPos.right, newPos.bottom, swFlag );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000988 }
Alexandre Julliard77b99181997-09-14 17:17:23 +0000989
Huw D M Daviesa14ca862000-07-29 11:31:29 +0000990 if( (wndPtr->dwStyle & WS_CHILD) && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
Alexandre Julliard77b99181997-09-14 17:17:23 +0000991 {
992 /* Notify the parent window only */
993
Alexandre Julliarda3960291999-02-26 11:11:13 +0000994 SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
Alexandre Julliard77b99181997-09-14 17:17:23 +0000995 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000996 if( !IsWindow(hwnd) )
997 {
998 retvalue = 0;
999 goto end;
1000 }
Alexandre Julliard77b99181997-09-14 17:17:23 +00001001 }
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001002
Slava Monicha27807d1999-06-05 11:46:35 +00001003 if (cs->style & WS_VISIBLE) ShowWindow( hwnd, sw );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001004
1005 /* Call WH_SHELL hook */
1006
1007 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1008 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
1009
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001010 TRACE("created window %04x\n", hwnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001011 retvalue = hwnd;
1012 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001013 }
Rein Klazesbf1bc511998-10-31 12:09:32 +00001014 WIN_UnlinkWindow( hwnd );
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001015 }
Alexandre Julliard401710d1993-09-04 10:09:32 +00001016
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001017 /* Abort window creation */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001018
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001019 WARN("aborted by WM_xxCREATE!\n");
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001020 WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001021 retvalue = 0;
1022end:
1023 WIN_ReleaseWndPtr(wndPtr);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001024
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001025 return retvalue;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001026}
1027
1028
1029/***********************************************************************
1030 * CreateWindow16 (USER.41)
1031 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001032HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
1033 DWORD style, INT16 x, INT16 y, INT16 width,
1034 INT16 height, HWND16 parent, HMENU16 menu,
1035 HINSTANCE16 instance, LPVOID data )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001036{
1037 return CreateWindowEx16( 0, className, windowName, style,
1038 x, y, width, height, parent, menu, instance, data );
1039}
1040
1041
1042/***********************************************************************
1043 * CreateWindowEx16 (USER.452)
1044 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001045HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
1046 LPCSTR windowName, DWORD style, INT16 x,
1047 INT16 y, INT16 width, INT16 height,
1048 HWND16 parent, HMENU16 menu,
1049 HINSTANCE16 instance, LPVOID data )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001050{
1051 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001052 CREATESTRUCTA cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001053 char buffer[256];
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001054
1055 /* Find the class atom */
1056
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001057 if (HIWORD(className))
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001058 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001059 if (!(classAtom = GlobalFindAtomA( className )))
1060 {
1061 ERR( "bad class name %s\n", debugres_a(className) );
1062 return 0;
1063 }
1064 }
1065 else
1066 {
1067 classAtom = LOWORD(className);
1068 if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
1069 {
1070 ERR( "bad atom %x\n", classAtom);
1071 return 0;
1072 }
1073 className = buffer;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001074 }
1075
1076 /* Fix the coordinates */
1077
Alexandre Julliarda3960291999-02-26 11:11:13 +00001078 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)x;
1079 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)y;
1080 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)width;
1081 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)height;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001082
1083 /* Create the window */
1084
1085 cs.lpCreateParams = data;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001086 cs.hInstance = (HINSTANCE)instance;
1087 cs.hMenu = (HMENU)menu;
1088 cs.hwndParent = (HWND)parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001089 cs.style = style;
1090 cs.lpszName = windowName;
1091 cs.lpszClass = className;
1092 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001093
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001094 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001095}
1096
1097
1098/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001099 * CreateWindowExA (USER32.83)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001100 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001101HWND WINAPI CreateWindowExA( DWORD exStyle, LPCSTR className,
1102 LPCSTR windowName, DWORD style, INT x,
1103 INT y, INT width, INT height,
1104 HWND parent, HMENU menu,
1105 HINSTANCE instance, LPVOID data )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001106{
1107 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001108 CREATESTRUCTA cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001109 char buffer[256];
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001110
Rein Klazesd4a2cee1999-10-23 13:57:36 +00001111 if(!instance)
1112 instance=GetModuleHandleA(NULL);
1113
Rein Klazes5c6fc1b1998-11-01 14:50:06 +00001114 if(exStyle & WS_EX_MDICHILD)
Alexandre Julliarda3960291999-02-26 11:11:13 +00001115 return MDI_CreateMDIWindowA(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001116
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001117 /* Find the class atom */
1118
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001119 if (HIWORD(className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001120 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001121 if (!(classAtom = GlobalFindAtomA( className )))
1122 {
1123 ERR( "bad class name %s\n", debugres_a(className) );
1124 return 0;
1125 }
1126 }
1127 else
1128 {
1129 classAtom = LOWORD(className);
1130 if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
1131 {
1132 ERR( "bad atom %x\n", classAtom);
1133 return 0;
1134 }
1135 className = buffer;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001136 }
1137
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001138 /* Create the window */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001139
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001140 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001141 cs.hInstance = instance;
1142 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001143 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001144 cs.x = x;
1145 cs.y = y;
1146 cs.cx = width;
1147 cs.cy = height;
1148 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001149 cs.lpszName = windowName;
1150 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001151 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001152
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001153 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001154}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001155
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001156
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001157/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001158 * CreateWindowExW (USER32.84)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001159 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001160HWND WINAPI CreateWindowExW( DWORD exStyle, LPCWSTR className,
1161 LPCWSTR windowName, DWORD style, INT x,
1162 INT y, INT width, INT height,
1163 HWND parent, HMENU menu,
1164 HINSTANCE instance, LPVOID data )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001165{
1166 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001167 CREATESTRUCTW cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001168 WCHAR buffer[256];
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001169
Rein Klazesd4a2cee1999-10-23 13:57:36 +00001170 if(!instance)
1171 instance=GetModuleHandleA(NULL);
1172
Rein Klazes5c6fc1b1998-11-01 14:50:06 +00001173 if(exStyle & WS_EX_MDICHILD)
Alexandre Julliarda3960291999-02-26 11:11:13 +00001174 return MDI_CreateMDIWindowW(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
Rein Klazes5c6fc1b1998-11-01 14:50:06 +00001175
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001176 /* Find the class atom */
1177
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001178 if (HIWORD(className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001179 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001180 if (!(classAtom = GlobalFindAtomW( className )))
1181 {
1182 ERR( "bad class name %s\n", debugres_w(className) );
1183 return 0;
1184 }
1185 }
1186 else
1187 {
1188 classAtom = LOWORD(className);
1189 if (!GlobalGetAtomNameW( classAtom, buffer, sizeof(buffer)/sizeof(WCHAR) ))
1190 {
1191 ERR( "bad atom %x\n", classAtom);
1192 return 0;
1193 }
1194 className = buffer;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001195 }
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001196
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001197 /* Create the window */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001198
1199 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001200 cs.hInstance = instance;
1201 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001202 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001203 cs.x = x;
1204 cs.y = y;
1205 cs.cx = width;
1206 cs.cy = height;
1207 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001208 cs.lpszName = windowName;
1209 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001210 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001211
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001212 /* Note: we rely on the fact that CREATESTRUCTA and */
1213 /* CREATESTRUCTW have the same layout. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001214 return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, classAtom, TRUE, TRUE );
Alexandre Julliard401710d1993-09-04 10:09:32 +00001215}
1216
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001217
Alexandre Julliard401710d1993-09-04 10:09:32 +00001218/***********************************************************************
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001219 * WIN_CheckFocus
1220 */
1221static void WIN_CheckFocus( WND* pWnd )
1222{
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001223 if( GetFocus16() == pWnd->hwndSelf )
1224 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001225}
1226
1227/***********************************************************************
1228 * WIN_SendDestroyMsg
1229 */
1230static void WIN_SendDestroyMsg( WND* pWnd )
1231{
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001232 WIN_CheckFocus(pWnd);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001233
Alexandre Julliarda3960291999-02-26 11:11:13 +00001234 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret();
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +00001235 CLIPBOARD_Driver->pResetOwner( pWnd, TRUE );
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001236
1237 /*
1238 * Send the WM_DESTROY to the window.
1239 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001240 SendMessageA( pWnd->hwndSelf, WM_DESTROY, 0, 0);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001241
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001242 /*
1243 * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
1244 * make sure that the window still exists when we come back.
1245 */
1246 if (IsWindow(pWnd->hwndSelf))
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001247 {
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001248 HWND* pWndArray = NULL;
1249 WND* pChild = NULL;
1250 int nKidCount = 0;
1251
1252 /*
1253 * Now, if the window has kids, we have to send WM_DESTROY messages
1254 * recursively to it's kids. It seems that those calls can also
1255 * trigger re-entrant calls to DestroyWindow for the kids so we must
1256 * protect against corruption of the list of siblings. We first build
1257 * a list of HWNDs representing all the kids.
1258 */
1259 pChild = WIN_LockWndPtr(pWnd->child);
1260 while( pChild )
1261 {
1262 nKidCount++;
1263 WIN_UpdateWndPtr(&pChild,pChild->next);
1264 }
1265
1266 /*
1267 * If there are no kids, we're done.
1268 */
1269 if (nKidCount==0)
1270 return;
1271
1272 pWndArray = HeapAlloc(GetProcessHeap(), 0, nKidCount*sizeof(HWND));
1273
1274 /*
1275 * Sanity check
1276 */
1277 if (pWndArray==NULL)
1278 return;
1279
1280 /*
1281 * Now, enumerate all the kids in a list, since we wait to make the SendMessage
1282 * call, our linked list of siblings should be safe.
1283 */
1284 nKidCount = 0;
1285 pChild = WIN_LockWndPtr(pWnd->child);
1286 while( pChild )
1287 {
1288 pWndArray[nKidCount] = pChild->hwndSelf;
1289 nKidCount++;
1290 WIN_UpdateWndPtr(&pChild,pChild->next);
1291 }
1292
1293 /*
1294 * Now that we have a list, go through that list again and send the destroy
1295 * message to those windows. We are using the HWND to retrieve the
1296 * WND pointer so we are effectively checking that all the kid windows are
1297 * still valid before sending the message.
1298 */
1299 while (nKidCount>0)
1300 {
Pavel Roskinc5012071999-03-19 16:59:18 +00001301 pChild = WIN_FindWndPtr(pWndArray[--nKidCount]);
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001302
1303 if (pChild!=NULL)
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001304 {
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001305 WIN_SendDestroyMsg( pChild );
1306 WIN_ReleaseWndPtr(pChild);
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001307 }
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001308 }
1309
1310 /*
1311 * Cleanup
1312 */
1313 HeapFree(GetProcessHeap(), 0, pWndArray);
1314 WIN_CheckFocus(pWnd);
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001315 }
1316 else
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001317 WARN("\tdestroyed itself while in WM_DESTROY!\n");
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001318}
1319
1320
1321/***********************************************************************
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001322 * DestroyWindow16 (USER.53)
Alexandre Julliard401710d1993-09-04 10:09:32 +00001323 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001324BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00001325{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001326 return DestroyWindow(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00001327}
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001328
1329
Alexandre Julliard01d63461997-01-20 19:43:45 +00001330/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001331 * DestroyWindow (USER32.135)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001332 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001333BOOL WINAPI DestroyWindow( HWND hwnd )
Alexandre Julliard401710d1993-09-04 10:09:32 +00001334{
Alexandre Julliard0e607781993-11-03 19:23:37 +00001335 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001336 BOOL retvalue;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00001337
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001338 TRACE("(%04x)\n", hwnd);
Alexandre Julliard401710d1993-09-04 10:09:32 +00001339
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001340 /* Initialization */
Alexandre Julliard401710d1993-09-04 10:09:32 +00001341
Alexandre Julliard0e607781993-11-03 19:23:37 +00001342 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001343 if (wndPtr == pWndDesktop)
1344 {
Andreas Mohr1c20b392000-02-20 19:17:35 +00001345 retvalue = FALSE; /* Can't destroy desktop */
1346 goto end;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001347 }
Alexandre Julliard58199531994-04-21 01:20:00 +00001348
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001349 /* Call hooks */
1350
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +00001351 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001352 {
1353 retvalue = FALSE;
1354 goto end;
1355 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001356
1357 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1358 {
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +00001359 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001360 /* FIXME: clean up palette - see "Internals" p.352 */
1361 }
1362
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001363 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
Alexandre Julliard77b99181997-09-14 17:17:23 +00001364 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
1365 {
1366 /* Notify the parent window only */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001367 SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
Alexandre Julliard77b99181997-09-14 17:17:23 +00001368 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001369 if( !IsWindow(hwnd) )
1370 {
1371 retvalue = TRUE;
1372 goto end;
1373 }
Alexandre Julliard77b99181997-09-14 17:17:23 +00001374 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001375
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +00001376 CLIPBOARD_Driver->pResetOwner( wndPtr, FALSE ); /* before the window is unmapped */
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001377
Alexandre Julliard58199531994-04-21 01:20:00 +00001378 /* Hide the window */
1379
1380 if (wndPtr->dwStyle & WS_VISIBLE)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001381 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001382 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
Alexandre Julliard01d63461997-01-20 19:43:45 +00001383 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001384 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001385 if (!IsWindow(hwnd))
1386 {
1387 retvalue = TRUE;
1388 goto end;
1389 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001390 }
Alexandre Julliard0e607781993-11-03 19:23:37 +00001391
Alexandre Julliard22945d51995-03-02 17:44:29 +00001392 /* Recursively destroy owned windows */
1393
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001394 if( !(wndPtr->dwStyle & WS_CHILD) )
Alexandre Julliard22945d51995-03-02 17:44:29 +00001395 {
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001396 /* make sure top menu popup doesn't get destroyed */
Alexandre Julliard77b99181997-09-14 17:17:23 +00001397 MENU_PatchResidentPopup( (HQUEUE16)0xFFFF, wndPtr );
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001398
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001399 for (;;)
1400 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001401 WND *siblingPtr = WIN_LockWndPtr(wndPtr->parent->child); /* First sibling */
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001402 while (siblingPtr)
Alexandre Julliard22945d51995-03-02 17:44:29 +00001403 {
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001404 if (siblingPtr->owner == wndPtr)
Patrik Stridvallea584721998-11-01 16:22:07 +00001405 {
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001406 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1407 break;
1408 else
1409 siblingPtr->owner = NULL;
Patrik Stridvallea584721998-11-01 16:22:07 +00001410 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001411 WIN_UpdateWndPtr(&siblingPtr,siblingPtr->next);
Alexandre Julliard22945d51995-03-02 17:44:29 +00001412 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001413 if (siblingPtr)
1414 {
1415 DestroyWindow( siblingPtr->hwndSelf );
1416 WIN_ReleaseWndPtr(siblingPtr);
1417 }
Alexandre Julliard22945d51995-03-02 17:44:29 +00001418 else break;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001419 }
1420
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001421 if( !Options.managed || EVENT_CheckFocus() )
1422 WINPOS_ActivateOtherWindow(wndPtr);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001423
1424 if( wndPtr->owner &&
1425 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1426 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
Alexandre Julliard22945d51995-03-02 17:44:29 +00001427 }
1428
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001429 /* Send destroy messages */
Alexandre Julliard0e607781993-11-03 19:23:37 +00001430
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001431 WIN_SendDestroyMsg( wndPtr );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001432 if (!IsWindow(hwnd))
1433 {
1434 retvalue = TRUE;
1435 goto end;
1436 }
Alexandre Julliard401710d1993-09-04 10:09:32 +00001437
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001438 /* Unlink now so we won't bother with the children later on */
Alexandre Julliard401710d1993-09-04 10:09:32 +00001439
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001440 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1441
1442 /* Destroy the window storage */
1443
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001444 WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001445 retvalue = TRUE;
1446end:
1447 WIN_ReleaseWndPtr(wndPtr);
1448 return retvalue;
Alexandre Julliard401710d1993-09-04 10:09:32 +00001449}
1450
1451
1452/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001453 * CloseWindow16 (USER.43)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001454 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001455BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001456{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001457 return CloseWindow( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001458}
1459
1460
1461/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001462 * CloseWindow (USER32.56)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001463 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001464BOOL WINAPI CloseWindow( HWND hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001465{
1466 WND * wndPtr = WIN_FindWndPtr( hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001467 BOOL retvalue;
1468
1469 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD))
1470 {
1471 retvalue = FALSE;
1472 goto end;
1473 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00001474 ShowWindow( hwnd, SW_MINIMIZE );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001475 retvalue = TRUE;
1476end:
1477 WIN_ReleaseWndPtr(wndPtr);
1478 return retvalue;
1479
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001480}
1481
1482
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001483/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001484 * OpenIcon16 (USER.44)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001485 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001486BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001487{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001488 return OpenIcon( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001489}
1490
1491
1492/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001493 * OpenIcon (USER32.410)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001494 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001495BOOL WINAPI OpenIcon( HWND hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001496{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001497 if (!IsIconic( hwnd )) return FALSE;
1498 ShowWindow( hwnd, SW_SHOWNORMAL );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001499 return TRUE;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001500}
1501
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001502
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001503/***********************************************************************
1504 * WIN_FindWindow
1505 *
1506 * Implementation of FindWindow() and FindWindowEx().
1507 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001508static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className,
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001509 LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001510{
1511 WND *pWnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001512 HWND retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001513
1514 if (child)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001515 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001516 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1517 if (parent)
1518 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001519 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent))
1520 {
1521 retvalue = 0;
1522 goto end;
1523 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001524 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001525 else if (pWnd->parent != pWndDesktop)
1526 {
1527 retvalue = 0;
1528 goto end;
1529 }
1530 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001531 }
1532 else
1533 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001534 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : WIN_LockWndPtr(pWndDesktop)))
1535 {
1536 retvalue = 0;
1537 goto end;
1538 }
1539 WIN_UpdateWndPtr(&pWnd,pWnd->child);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001540 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001541 if (!pWnd)
1542 {
1543 retvalue = 0;
1544 goto end;
1545 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001546
Pavel Roskin598993f1999-03-16 09:53:10 +00001547 for ( ; pWnd ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001548 {
Alexandre Julliard4f152392000-02-25 20:45:23 +00001549 if (className && (pWnd->class->atomName != className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001550 continue; /* Not the right class */
1551
1552 /* Now check the title */
1553
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001554 if (!title)
1555 {
1556 retvalue = pWnd->hwndSelf;
1557 goto end;
Pavel Roskin598993f1999-03-16 09:53:10 +00001558 }
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001559 if (pWnd->text && !lstrcmpW( pWnd->text, title ))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001560 {
1561 retvalue = pWnd->hwndSelf;
1562 goto end;
Pavel Roskin598993f1999-03-16 09:53:10 +00001563 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001564 }
1565 retvalue = 0;
1566end:
1567 WIN_ReleaseWndPtr(pWnd);
1568 return retvalue;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001569}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001570
1571
1572
1573/***********************************************************************
1574 * FindWindow16 (USER.50)
1575 */
Alexandre Julliardb849d792000-02-13 13:56:13 +00001576HWND16 WINAPI FindWindow16( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001577{
Alexandre Julliardb849d792000-02-13 13:56:13 +00001578 return FindWindowA( className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001579}
1580
1581
1582/***********************************************************************
1583 * FindWindowEx16 (USER.427)
1584 */
Alexandre Julliardb849d792000-02-13 13:56:13 +00001585HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child, LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001586{
Alexandre Julliardb849d792000-02-13 13:56:13 +00001587 return FindWindowExA( parent, child, className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001588}
1589
1590
1591/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001592 * FindWindowA (USER32.198)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001593 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001594HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001595{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001596 HWND ret = FindWindowExA( 0, 0, className, title );
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001597 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1598 return ret;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001599}
1600
1601
1602/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001603 * FindWindowExA (USER32.199)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001604 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001605HWND WINAPI FindWindowExA( HWND parent, HWND child,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001606 LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001607{
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001608 ATOM atom = 0;
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001609 LPWSTR buffer;
1610 HWND hwnd;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001611
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001612 if (className)
1613 {
1614 /* If the atom doesn't exist, then no class */
1615 /* with this name exists either. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001616 if (!(atom = GlobalFindAtomA( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001617 {
1618 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1619 return 0;
1620 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001621 }
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001622
1623 buffer = HEAP_strdupAtoW( GetProcessHeap(), 0, title );
1624 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1625 HeapFree( GetProcessHeap(), 0, buffer );
1626 return hwnd;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001627}
1628
1629
1630/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001631 * FindWindowExW (USER32.200)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001632 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001633HWND WINAPI FindWindowExW( HWND parent, HWND child,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001634 LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001635{
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001636 ATOM atom = 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001637
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001638 if (className)
1639 {
1640 /* If the atom doesn't exist, then no class */
1641 /* with this name exists either. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001642 if (!(atom = GlobalFindAtomW( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001643 {
1644 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1645 return 0;
1646 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001647 }
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001648 return WIN_FindWindow( parent, child, atom, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001649}
1650
1651
1652/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001653 * FindWindowW (USER32.201)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001654 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001655HWND WINAPI FindWindowW( LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001656{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001657 return FindWindowExW( 0, 0, className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001658}
1659
1660
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001661/**********************************************************************
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001662 * WIN_GetDesktop
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001663 * returns a locked pointer
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001664 */
1665WND *WIN_GetDesktop(void)
1666{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001667 return WIN_LockWndPtr(pWndDesktop);
1668}
1669/**********************************************************************
1670 * WIN_ReleaseDesktop
1671 * unlock the desktop pointer
1672 */
1673void WIN_ReleaseDesktop(void)
1674{
1675 WIN_ReleaseWndPtr(pWndDesktop);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001676}
1677
1678
1679/**********************************************************************
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001680 * GetDesktopWindow16 (USER.286)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001681 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001682HWND16 WINAPI GetDesktopWindow16(void)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001683{
1684 return (HWND16)pWndDesktop->hwndSelf;
1685}
1686
1687
1688/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001689 * GetDesktopWindow (USER32.232)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001690 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001691HWND WINAPI GetDesktopWindow(void)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001692{
Uwe Bonnes73619161999-10-24 20:42:39 +00001693 if (pWndDesktop) return pWndDesktop->hwndSelf;
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001694 ERR( "You need the -desktop option when running with native USER\n" );
Uwe Bonnes73619161999-10-24 20:42:39 +00001695 ExitProcess(1);
Huw D M Davies238b6d71999-10-31 01:56:51 +00001696 return 0;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001697}
1698
1699
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001700/**********************************************************************
1701 * GetDesktopHwnd (USER.278)
1702 *
1703 * Exactly the same thing as GetDesktopWindow(), but not documented.
1704 * Don't ask me why...
1705 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001706HWND16 WINAPI GetDesktopHwnd16(void)
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001707{
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001708 return (HWND16)pWndDesktop->hwndSelf;
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001709}
1710
1711
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001712/*******************************************************************
Alexandre Julliard01d63461997-01-20 19:43:45 +00001713 * EnableWindow16 (USER.34)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001714 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001715BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
Alexandre Julliard01d63461997-01-20 19:43:45 +00001716{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001717 return EnableWindow( hwnd, enable );
Alexandre Julliard01d63461997-01-20 19:43:45 +00001718}
1719
1720
1721/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001722 * EnableWindow (USER32.172)
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{
1726 WND *wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001727 BOOL retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001728
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001729 TRACE("EnableWindow32: ( %x, %d )\n", hwnd, enable);
Noel Borthwickb4278561999-02-05 10:37:53 +00001730
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001731 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1732 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1733 {
1734 /* Enable window */
1735 wndPtr->dwStyle &= ~WS_DISABLED;
Alex Korobka4f1ac051999-03-28 09:37:57 +00001736
1737 if( wndPtr->flags & WIN_NATIVE )
1738 wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ACCEPTFOCUS, TRUE );
1739
Alexandre Julliarda3960291999-02-26 11:11:13 +00001740 SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001741 retvalue = TRUE;
1742 goto end;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001743 }
1744 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1745 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00001746 SendMessageA( wndPtr->hwndSelf, WM_CANCELMODE, 0, 0);
1747
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001748 /* Disable window */
1749 wndPtr->dwStyle |= WS_DISABLED;
Alex Korobka4f1ac051999-03-28 09:37:57 +00001750
1751 if( wndPtr->flags & WIN_NATIVE )
1752 wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ACCEPTFOCUS, FALSE );
1753
Francis Beaudet21d50f81999-05-29 14:10:02 +00001754 if (hwnd == GetFocus())
Noel Borthwickb4278561999-02-05 10:37:53 +00001755 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001756 SetFocus( 0 ); /* A disabled window can't have the focus */
Noel Borthwickb4278561999-02-05 10:37:53 +00001757 }
Pascal Lessard31c58541999-06-26 10:17:10 +00001758 if (hwnd == GetCapture())
Noel Borthwickb4278561999-02-05 10:37:53 +00001759 {
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001760 ReleaseCapture(); /* A disabled window can't capture the mouse */
Noel Borthwickb4278561999-02-05 10:37:53 +00001761 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00001762 SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001763 retvalue = FALSE;
1764 goto end;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001765 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001766 retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);
1767end:
1768 WIN_ReleaseWndPtr(wndPtr);
1769 return retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001770}
1771
1772
1773/***********************************************************************
Alexandre Julliard01d63461997-01-20 19:43:45 +00001774 * IsWindowEnabled16 (USER.35)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001775 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001776BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001777{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001778 return IsWindowEnabled(hWnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00001779}
1780
1781
1782/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001783 * IsWindowEnabled (USER32.349)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001784 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001785BOOL WINAPI IsWindowEnabled(HWND hWnd)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001786{
1787 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001788 BOOL retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001789
1790 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001791 retvalue = !(wndPtr->dwStyle & WS_DISABLED);
1792 WIN_ReleaseWndPtr(wndPtr);
1793 return retvalue;
1794
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001795}
1796
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001797
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001798/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001799 * IsWindowUnicode (USER32.350)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001800 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001801BOOL WINAPI IsWindowUnicode( HWND hwnd )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001802{
1803 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001804 BOOL retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001805
1806 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001807 retvalue = (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1808 WIN_ReleaseWndPtr(wndPtr);
1809 return retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001810}
1811
1812
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001813/**********************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00001814 * GetWindowWord16 (USER.133)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001815 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001816WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
Alexandre Julliard21979011997-03-05 08:22:35 +00001817{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001818 return GetWindowWord( hwnd, offset );
Alexandre Julliard21979011997-03-05 08:22:35 +00001819}
1820
1821
1822/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001823 * GetWindowWord (USER32.314)
Alexandre Julliard21979011997-03-05 08:22:35 +00001824 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001825WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001826{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001827 WORD retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001828 WND * wndPtr = WIN_FindWndPtr( hwnd );
1829 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001830 if (offset >= 0)
1831 {
1832 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1833 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001834 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001835 retvalue = 0;
1836 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001837 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001838 retvalue = *(WORD *)(((char *)wndPtr->wExtra) + offset);
1839 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001840 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001841 switch(offset)
1842 {
Alexandre Julliard77b99181997-09-14 17:17:23 +00001843 case GWW_ID:
1844 if (HIWORD(wndPtr->wIDmenu))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001845 WARN("GWW_ID: discards high bits of 0x%08x!\n",
Alexandre Julliarda845b881998-06-01 10:44:35 +00001846 wndPtr->wIDmenu);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001847 retvalue = (WORD)wndPtr->wIDmenu;
1848 goto end;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001849 case GWW_HWNDPARENT:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001850 retvalue = GetParent(hwnd);
1851 goto end;
Alexandre Julliard77b99181997-09-14 17:17:23 +00001852 case GWW_HINSTANCE:
1853 if (HIWORD(wndPtr->hInstance))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001854 WARN("GWW_HINSTANCE: discards high bits of 0x%08x!\n",
Alexandre Julliarda845b881998-06-01 10:44:35 +00001855 wndPtr->hInstance);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001856 retvalue = (WORD)wndPtr->hInstance;
1857 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001858 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001859 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001860 retvalue = 0;
1861 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001862 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001863end:
1864 WIN_ReleaseWndPtr(wndPtr);
1865 return retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001866}
1867
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00001868/**********************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00001869 * SetWindowWord16 (USER.134)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001870 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001871WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
Alexandre Julliard21979011997-03-05 08:22:35 +00001872{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001873 return SetWindowWord( hwnd, offset, newval );
Alexandre Julliard21979011997-03-05 08:22:35 +00001874}
1875
1876
1877/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001878 * SetWindowWord (USER32.524)
Alexandre Julliard21979011997-03-05 08:22:35 +00001879 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001880WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001881{
1882 WORD *ptr, retval;
1883 WND * wndPtr = WIN_FindWndPtr( hwnd );
1884 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001885 if (offset >= 0)
1886 {
1887 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1888 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001889 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001890 retval = 0;
1891 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001892 }
1893 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1894 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001895 else switch(offset)
1896 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001897 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1898 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001899 case GWW_HWNDPARENT: retval = SetParent( hwnd, newval );
1900 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001901 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001902 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001903 retval = 0;
1904 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001905 }
1906 retval = *ptr;
1907 *ptr = newval;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001908end:
1909 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001910 return retval;
1911}
1912
1913
1914/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001915 * WIN_GetWindowLong
1916 *
1917 * Helper function for GetWindowLong().
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001918 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001919static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001920{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001921 LONG retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001922 WND * wndPtr = WIN_FindWndPtr( hwnd );
1923 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001924 if (offset >= 0)
1925 {
1926 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1927 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001928 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001929 retvalue = 0;
1930 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001931 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001932 retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
Alexandre Julliard3051b641996-07-05 17:14:13 +00001933 /* Special case for dialog window procedure */
1934 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001935 {
1936 retvalue = (LONG)WINPROC_GetProc( (HWINDOWPROC)retvalue, type );
1937 goto end;
1938 }
1939 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001940 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001941 switch(offset)
1942 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001943 case GWL_USERDATA: retvalue = wndPtr->userdata;
1944 goto end;
1945 case GWL_STYLE: retvalue = wndPtr->dwStyle;
1946 goto end;
1947 case GWL_EXSTYLE: retvalue = wndPtr->dwExStyle;
1948 goto end;
1949 case GWL_ID: retvalue = (LONG)wndPtr->wIDmenu;
1950 goto end;
1951 case GWL_WNDPROC: retvalue = (LONG)WINPROC_GetProc( wndPtr->winproc,
Alexandre Julliard3051b641996-07-05 17:14:13 +00001952 type );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001953 goto end;
1954 case GWL_HWNDPARENT: retvalue = GetParent(hwnd);
1955 goto end;
1956 case GWL_HINSTANCE: retvalue = wndPtr->hInstance;
1957 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001958 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001959 WARN("Unknown offset %d\n", offset );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001960 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001961 retvalue = 0;
1962end:
1963 WIN_ReleaseWndPtr(wndPtr);
1964 return retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001965}
1966
1967
1968/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001969 * WIN_SetWindowLong
1970 *
1971 * Helper function for SetWindowLong().
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001972 *
1973 * 0 is the failure code. However, in the case of failure SetLastError
1974 * must be set to distinguish between a 0 return value and a failure.
1975 *
1976 * FIXME: The error values for SetLastError may not be right. Can
1977 * someone check with the real thing?
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001978 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001979static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
Alexandre Julliard3051b641996-07-05 17:14:13 +00001980 WINDOWPROCTYPE type )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001981{
1982 LONG *ptr, retval;
1983 WND * wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001984 STYLESTRUCT style;
1985
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001986 TRACE("%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001987
1988 if (!wndPtr)
1989 {
1990 /* Is this the right error? */
1991 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1992 return 0;
1993 }
1994
Alexandre Julliard3051b641996-07-05 17:14:13 +00001995 if (offset >= 0)
1996 {
1997 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1998 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001999 WARN("Invalid offset %d\n", offset );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002000
2001 /* Is this the right error? */
2002 SetLastError( ERROR_OUTOFMEMORY );
2003
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002004 retval = 0;
2005 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002006 }
2007 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
2008 /* Special case for dialog window procedure */
2009 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
2010 {
2011 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002012 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
2013 type, WIN_PROC_WINDOW );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002014 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002015 }
2016 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002017 else switch(offset)
2018 {
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002019 case GWL_ID:
2020 ptr = (DWORD*)&wndPtr->wIDmenu;
2021 break;
2022 case GWL_HINSTANCE:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002023 retval = SetWindowWord( hwnd, offset, newval );
2024 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002025 case GWL_WNDPROC:
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002026 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
2027 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002028 type, WIN_PROC_WINDOW );
Andreas Mohr1c20b392000-02-20 19:17:35 +00002029 goto end;
Alexandre Julliardca22b331996-07-12 19:02:39 +00002030 case GWL_STYLE:
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002031 style.styleOld = wndPtr->dwStyle;
Gerard Patel72b93d42000-07-15 19:42:52 +00002032 newval &= ~(WS_CHILD); /* this bit can't be changed this way */
2033 style.styleNew = newval | (style.styleOld & (WS_CHILD));
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002034
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002035 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002036 SendMessageA(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002037 wndPtr->dwStyle = style.styleNew;
2038 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002039 SendMessageA(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002040 retval = style.styleOld;
2041 goto end;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002042
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002043 case GWL_USERDATA:
2044 ptr = &wndPtr->userdata;
2045 break;
2046 case GWL_EXSTYLE:
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002047 style.styleOld = wndPtr->dwExStyle;
2048 style.styleNew = newval;
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002049 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002050 SendMessageA(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002051 wndPtr->dwExStyle = newval;
2052 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002053 SendMessageA(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002054 retval = style.styleOld;
2055 goto end;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002056
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002057 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002058 WARN("Invalid offset %d\n", offset );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002059
2060 /* Don't think this is right error but it should do */
2061 SetLastError( ERROR_OUTOFMEMORY );
2062
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002063 retval = 0;
2064 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002065 }
2066 retval = *ptr;
2067 *ptr = newval;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002068end:
2069 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002070 return retval;
2071}
2072
2073
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002074/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002075 * GetWindowLong16 (USER.135)
2076 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002077LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002078{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002079 return WIN_GetWindowLong( (HWND)hwnd, offset, WIN_PROC_16 );
Alexandre Julliard3051b641996-07-05 17:14:13 +00002080}
2081
2082
2083/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002084 * GetWindowLongA (USER32.305)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002085 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002086LONG WINAPI GetWindowLongA( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002087{
2088 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
2089}
2090
2091
2092/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002093 * GetWindowLongW (USER32.306)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002094 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002095LONG WINAPI GetWindowLongW( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002096{
2097 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
2098}
2099
2100
2101/**********************************************************************
2102 * SetWindowLong16 (USER.136)
2103 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002104LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002105{
2106 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
2107}
2108
2109
2110/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002111 * SetWindowLongA (USER32.517)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002112 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002113LONG WINAPI SetWindowLongA( HWND hwnd, INT offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002114{
2115 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
2116}
2117
2118
2119/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002120 * SetWindowLongW (USER32.518) Set window attribute
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002121 *
2122 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
2123 * value in a window's extra memory.
2124 *
2125 * The _hwnd_ parameter specifies the window. is the handle to a
2126 * window that has extra memory. The _newval_ parameter contains the
2127 * new attribute or extra memory value. If positive, the _offset_
2128 * parameter is the byte-addressed location in the window's extra
2129 * memory to set. If negative, _offset_ specifies the window
2130 * attribute to set, and should be one of the following values:
2131 *
2132 * GWL_EXSTYLE The window's extended window style
2133 *
2134 * GWL_STYLE The window's window style.
2135 *
2136 * GWL_WNDPROC Pointer to the window's window procedure.
2137 *
2138 * GWL_HINSTANCE The window's pplication instance handle.
2139 *
2140 * GWL_ID The window's identifier.
2141 *
2142 * GWL_USERDATA The window's user-specified data.
2143 *
2144 * If the window is a dialog box, the _offset_ parameter can be one of
2145 * the following values:
2146 *
2147 * DWL_DLGPROC The address of the window's dialog box procedure.
2148 *
2149 * DWL_MSGRESULT The return value of a message
2150 * that the dialog box procedure processed.
2151 *
2152 * DWL_USER Application specific information.
2153 *
2154 * RETURNS
2155 *
2156 * If successful, returns the previous value located at _offset_. Otherwise,
2157 * returns 0.
2158 *
2159 * NOTES
2160 *
2161 * Extra memory for a window class is specified by a nonzero cbWndExtra
2162 * parameter of the WNDCLASS structure passed to RegisterClass() at the
2163 * time of class creation.
2164 *
2165 * Using GWL_WNDPROC to set a new window procedure effectively creates
2166 * a window subclass. Use CallWindowProc() in the new windows procedure
2167 * to pass messages to the superclass's window procedure.
2168 *
2169 * The user data is reserved for use by the application which created
2170 * the window.
2171 *
2172 * Do not use GWL_STYLE to change the window's WS_DISABLE style;
2173 * instead, call the EnableWindow() function to change the window's
2174 * disabled state.
2175 *
2176 * Do not use GWL_HWNDPARENT to reset the window's parent, use
2177 * SetParent() instead.
2178 *
Alexandre Julliard638f1691999-01-17 16:32:32 +00002179 * Win95:
2180 * When offset is GWL_STYLE and the calling app's ver is 4.0,
2181 * it sends WM_STYLECHANGING before changing the settings
2182 * and WM_STYLECHANGED afterwards.
2183 * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
2184 *
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002185 * BUGS
2186 *
Alexandre Julliard638f1691999-01-17 16:32:32 +00002187 * GWL_STYLE does not dispatch WM_STYLE... messages.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002188 *
2189 * CONFORMANCE
2190 *
2191 * ECMA-234, Win32
2192 *
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002193 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002194LONG WINAPI SetWindowLongW(
2195 HWND hwnd, /* window to alter */
2196 INT offset, /* offset, in bytes, of location to alter */
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002197 LONG newval /* new value of location */
2198) {
Alexandre Julliard3051b641996-07-05 17:14:13 +00002199 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002200}
2201
2202
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002203/*******************************************************************
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002204 * GetWindowText16 (USER.36)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002205 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002206INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002207{
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002208 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
Alexandre Julliard0e607781993-11-03 19:23:37 +00002209}
2210
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002211
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002212/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002213 * GetWindowTextA (USER32.309)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002214 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002215INT WINAPI GetWindowTextA( HWND hwnd, LPSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002216{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002217 return (INT)SendMessageA( hwnd, WM_GETTEXT, nMaxCount,
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002218 (LPARAM)lpString );
2219}
2220
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002221/*******************************************************************
2222 * InternalGetWindowText (USER32.326)
2223 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002224INT WINAPI InternalGetWindowText(HWND hwnd,LPWSTR lpString,INT nMaxCount )
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002225{
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002226 FIXME("(0x%08x,%p,0x%x),stub!\n",hwnd,lpString,nMaxCount);
Alexandre Julliarda3960291999-02-26 11:11:13 +00002227 return GetWindowTextW(hwnd,lpString,nMaxCount);
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002228}
2229
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002230
2231/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002232 * GetWindowTextW (USER32.312)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002233 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002234INT WINAPI GetWindowTextW( HWND hwnd, LPWSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002235{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002236 return (INT)SendMessageW( hwnd, WM_GETTEXT, nMaxCount,
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002237 (LPARAM)lpString );
2238}
2239
2240
2241/*******************************************************************
2242 * SetWindowText16 (USER.37)
2243 */
Paul Quinn1beaae51998-12-15 15:38:36 +00002244BOOL16 WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002245{
Paul Quinn1beaae51998-12-15 15:38:36 +00002246 return (BOOL16)SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002247}
2248
2249
2250/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002251 * SetWindowTextA (USER32.521)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002252 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002253BOOL WINAPI SetWindowTextA( HWND hwnd, LPCSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002254{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002255 return (BOOL)SendMessageA( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002256}
2257
2258
2259/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002260 * SetWindowTextW (USER32.523)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002261 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002262BOOL WINAPI SetWindowTextW( HWND hwnd, LPCWSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002263{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002264 return (BOOL)SendMessageW( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002265}
2266
2267
Alexandre Julliard0e607781993-11-03 19:23:37 +00002268/*******************************************************************
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002269 * GetWindowTextLength16 (USER.38)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002270 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002271INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002272{
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002273 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002274}
2275
2276
Alexandre Julliard0e607781993-11-03 19:23:37 +00002277/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002278 * GetWindowTextLengthA (USER32.310)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002279 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002280INT WINAPI GetWindowTextLengthA( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002281{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002282 return SendMessageA( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002283}
2284
2285/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002286 * GetWindowTextLengthW (USER32.311)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002287 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002288INT WINAPI GetWindowTextLengthW( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002289{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002290 return SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002291}
2292
Alexandre Julliard21979011997-03-05 08:22:35 +00002293
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002294/*******************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00002295 * IsWindow16 (USER.47)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002296 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002297BOOL16 WINAPI IsWindow16( HWND16 hwnd )
Alexandre Julliard21979011997-03-05 08:22:35 +00002298{
Alexandre Julliard4220b291999-07-11 17:20:01 +00002299 CURRENT_STACK16->es = USER_HeapSel;
Alexandre Julliarda3960291999-02-26 11:11:13 +00002300 return IsWindow( hwnd );
Alexandre Julliard21979011997-03-05 08:22:35 +00002301}
2302
2303
2304/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002305 * IsWindow (USER32.348)
Alexandre Julliard21979011997-03-05 08:22:35 +00002306 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002307BOOL WINAPI IsWindow( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002308{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002309 WND * wndPtr;
2310 BOOL retvalue;
2311
2312 if(!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
2313 retvalue = (wndPtr->dwMagic == WND_MAGIC);
2314 WIN_ReleaseWndPtr(wndPtr);
2315 return retvalue;
2316
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002317}
2318
2319
2320/*****************************************************************
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002321 * GetParent16 (USER.46)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002322 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002323HWND16 WINAPI GetParent16( HWND16 hwnd )
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002324{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002325 return (HWND16)GetParent( hwnd );
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002326}
2327
2328
2329/*****************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002330 * GetParent (USER32.278)
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002331 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002332HWND WINAPI GetParent( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002333{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002334 WND *wndPtr;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002335 HWND retvalue = 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002336
2337 if(!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
2338 if ((!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD))))
Andreas Mohr1c20b392000-02-20 19:17:35 +00002339 goto end;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002340
Andreas Mohr1c20b392000-02-20 19:17:35 +00002341 WIN_UpdateWndPtr(&wndPtr,((wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner));
2342 if (wndPtr)
2343 retvalue = wndPtr->hwndSelf;
2344
2345end:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002346 WIN_ReleaseWndPtr(wndPtr);
2347 return retvalue;
2348
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002349}
2350
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002351/*****************************************************************
2352 * WIN_GetTopParent
2353 *
2354 * Get the top-level parent for a child window.
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002355 * returns a locked pointer
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002356 */
2357WND* WIN_GetTopParentPtr( WND* pWnd )
2358{
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002359 WND *tmpWnd = WIN_LockWndPtr(pWnd);
2360
2361 while( tmpWnd && (tmpWnd->dwStyle & WS_CHILD))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002362 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002363 WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002364 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002365 return tmpWnd;
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002366}
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002367
2368/*****************************************************************
2369 * WIN_GetTopParent
2370 *
2371 * Get the top-level parent for a child window.
2372 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002373HWND WIN_GetTopParent( HWND hwnd )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002374{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002375 HWND retvalue;
2376 WND *tmpPtr = WIN_FindWndPtr(hwnd);
2377 WND *wndPtr = WIN_GetTopParentPtr (tmpPtr );
2378
2379 retvalue = wndPtr ? wndPtr->hwndSelf : 0;
2380 WIN_ReleaseWndPtr(tmpPtr);
2381 WIN_ReleaseWndPtr(wndPtr);
2382 return retvalue;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002383}
2384
2385
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002386/*****************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002387 * SetParent16 (USER.233)
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002388 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002389HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002390{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002391 return SetParent( hwndChild, hwndNewParent );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002392}
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002393
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002394
2395/*****************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002396 * SetParent (USER32.495)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002397 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002398HWND WINAPI SetParent( HWND hwndChild, HWND hwndNewParent )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002399{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002400 WND *wndPtr;
2401 DWORD dwStyle;
2402 WND *pWndNewParent;
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002403 WND *pWndOldParent;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002404 HWND retvalue;
2405
2406
2407 if(!(wndPtr = WIN_FindWndPtr(hwndChild))) return 0;
2408
2409 dwStyle = wndPtr->dwStyle;
2410
2411 pWndNewParent = hwndNewParent ? WIN_FindWndPtr(hwndNewParent)
2412 : WIN_LockWndPtr(pWndDesktop);
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002413
2414 /* Windows hides the window first, then shows it again
2415 * including the WM_SHOWWINDOW messages and all */
2416 if (dwStyle & WS_VISIBLE)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002417 ShowWindow( hwndChild, SW_HIDE );
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002418
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002419 pWndOldParent = WIN_LockWndPtr((*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent));
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002420
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002421 /* SetParent additionally needs to make hwndChild the topmost window
Noel Borthwick463eb291999-01-20 13:50:13 +00002422 in the x-order and send the expected WM_WINDOWPOSCHANGING and
2423 WM_WINDOWPOSCHANGED notification messages.
2424 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002425 SetWindowPos( hwndChild, HWND_TOPMOST, 0, 0, 0, 0,
Gerard Patel78f52b52000-05-31 19:23:20 +00002426 SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002427 /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
2428 * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
2429
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002430 retvalue = pWndOldParent?pWndOldParent->hwndSelf:0;
2431
2432 WIN_ReleaseWndPtr(pWndOldParent);
2433 WIN_ReleaseWndPtr(pWndNewParent);
2434 WIN_ReleaseWndPtr(wndPtr);
2435
2436 return retvalue;
2437
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002438}
2439
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002440/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002441 * IsChild16 (USER.48)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002442 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002443BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002444{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002445 return IsChild(parent,child);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002446}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002447
2448
Alexandre Julliard01d63461997-01-20 19:43:45 +00002449/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002450 * IsChild (USER32.339)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002451 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002452BOOL WINAPI IsChild( HWND parent, HWND child )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002453{
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002454 WND * wndPtr = WIN_FindWndPtr( child );
2455 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
Alexandre Julliard0e607781993-11-03 19:23:37 +00002456 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002457 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
2458 if (wndPtr->hwndSelf == parent)
Andreas Mohr1c20b392000-02-20 19:17:35 +00002459 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002460 WIN_ReleaseWndPtr(wndPtr);
2461 return TRUE;
2462 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002463 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002464 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard0e607781993-11-03 19:23:37 +00002465 return FALSE;
2466}
2467
2468
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002469/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002470 * IsWindowVisible16 (USER.49)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002471 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002472BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002473{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002474 return IsWindowVisible(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002475}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002476
2477
Alexandre Julliard01d63461997-01-20 19:43:45 +00002478/***********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002479 * IsWindowVisible (USER32.351)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002480 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002481BOOL WINAPI IsWindowVisible( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002482{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002483 BOOL retval;
Alexandre Julliardded30381995-07-06 17:18:27 +00002484 WND *wndPtr = WIN_FindWndPtr( hwnd );
2485 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
2486 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002487 if (!(wndPtr->dwStyle & WS_VISIBLE))
2488 {
2489 WIN_ReleaseWndPtr(wndPtr);
2490 return FALSE;
2491 }
2492 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
Alexandre Julliardded30381995-07-06 17:18:27 +00002493 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002494 retval = (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
2495 WIN_ReleaseWndPtr(wndPtr);
2496 return retval;
2497
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002498}
2499
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002500
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002501/***********************************************************************
2502 * WIN_IsWindowDrawable
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002503 *
2504 * hwnd is drawable when it is visible, all parents are not
2505 * minimized, and it is itself not minimized unless we are
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002506 * trying to draw its default class icon.
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002507 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002508BOOL WIN_IsWindowDrawable( WND* wnd, BOOL icon )
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002509{
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002510 if( (wnd->dwStyle & WS_MINIMIZE &&
2511 icon && wnd->class->hIcon) ||
2512 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
2513 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
2514 if( wnd->dwStyle & WS_MINIMIZE ||
2515 !(wnd->dwStyle & WS_VISIBLE) ) break;
2516 return (wnd == NULL);
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002517}
2518
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002519
Alexandre Julliard0e607781993-11-03 19:23:37 +00002520/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002521 * GetTopWindow16 (USER.229)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002522 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002523HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002524{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002525 return GetTopWindow(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002526}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002527
2528
Alexandre Julliard01d63461997-01-20 19:43:45 +00002529/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002530 * GetTopWindow (USER.229)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002531 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002532HWND WINAPI GetTopWindow( HWND hwnd )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002533{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002534 HWND retval = 0;
2535 WND * wndPtr = (hwnd) ?
2536 WIN_FindWndPtr( hwnd ) : WIN_GetDesktop();
Francis Beaudetb7e8e801999-05-22 10:46:30 +00002537
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002538 if (wndPtr && wndPtr->child)
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002539 retval = wndPtr->child->hwndSelf;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002540
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002541 WIN_ReleaseWndPtr(wndPtr);
2542 return retval;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002543}
2544
2545
2546/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002547 * GetWindow16 (USER.262)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002548 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002549HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002550{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002551 return GetWindow( hwnd,rel );
Alexandre Julliard01d63461997-01-20 19:43:45 +00002552}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002553
2554
Alexandre Julliard01d63461997-01-20 19:43:45 +00002555/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002556 * GetWindow (USER32.302)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002557 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002558HWND WINAPI GetWindow( HWND hwnd, WORD rel )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002559{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002560 HWND retval;
2561
Alexandre Julliard0e607781993-11-03 19:23:37 +00002562 WND * wndPtr = WIN_FindWndPtr( hwnd );
2563 if (!wndPtr) return 0;
2564 switch(rel)
2565 {
2566 case GW_HWNDFIRST:
Andreas Mohr1c20b392000-02-20 19:17:35 +00002567 retval = wndPtr->parent ? wndPtr->parent->child->hwndSelf : 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002568 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002569
2570 case GW_HWNDLAST:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002571 if (!wndPtr->parent)
2572 {
2573 retval = 0; /* Desktop window */
2574 goto end;
2575 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002576 while (wndPtr->next)
2577 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002578 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002579 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002580 retval = wndPtr->hwndSelf;
2581 goto end;
2582
2583 case GW_HWNDNEXT:
Andreas Mohr1c20b392000-02-20 19:17:35 +00002584 retval = wndPtr->next ? wndPtr->next->hwndSelf : 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002585 goto end;
2586
2587 case GW_HWNDPREV:
2588 if (!wndPtr->parent)
2589 {
2590 retval = 0; /* Desktop window */
2591 goto end;
2592 }
2593 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent->child); /* First sibling */
2594 if (wndPtr->hwndSelf == hwnd)
2595 {
2596 retval = 0; /* First in list */
2597 goto end;
2598 }
2599 while (wndPtr->next)
2600 {
2601 if (wndPtr->next->hwndSelf == hwnd)
Andreas Mohr1c20b392000-02-20 19:17:35 +00002602 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002603 retval = wndPtr->hwndSelf;
2604 goto end;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002605 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002606 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
2607 }
2608 retval = 0;
2609 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002610
2611 case GW_OWNER:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002612 retval = wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
2613 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002614
2615 case GW_CHILD:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002616 retval = wndPtr->child ? wndPtr->child->hwndSelf : 0;
2617 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002618 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002619 retval = 0;
2620end:
2621 WIN_ReleaseWndPtr(wndPtr);
2622 return retval;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002623}
2624
2625
2626/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002627 * GetNextWindow16 (USER.230)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002628 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002629HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002630{
2631 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
Alexandre Julliard01d63461997-01-20 19:43:45 +00002632 return GetWindow16( hwnd, flag );
Alexandre Julliard0e607781993-11-03 19:23:37 +00002633}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002634
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002635/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002636 * ShowOwnedPopups16 (USER.265)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002637 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002638void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002639{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002640 ShowOwnedPopups( owner, fShow );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002641}
2642
2643
2644/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002645 * ShowOwnedPopups (USER32.531)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002646 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002647BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL fShow )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002648{
Noomen Hamzaa018d851999-09-28 16:26:09 +00002649 UINT totalChild=0, count=0;
2650
2651 WND **pWnd = WIN_BuildWinArray(WIN_GetDesktop(), 0, &totalChild);
2652
2653 if (!pWnd) return TRUE;
2654
2655 for (; count < totalChild; count++)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002656 {
Noomen Hamzaa018d851999-09-28 16:26:09 +00002657 if (pWnd[count]->owner && (pWnd[count]->owner->hwndSelf == owner) && (pWnd[count]->dwStyle & WS_POPUP))
Noomen Hamzaff727762000-02-18 19:11:04 +00002658 {
2659 if (fShow)
2660 {
2661 if (pWnd[count]->flags & WIN_NEEDS_SHOW_OWNEDPOPUP)
2662 {
2663 SendMessageA(pWnd[count]->hwndSelf, WM_SHOWWINDOW, SW_SHOW, IsIconic(owner) ? SW_PARENTOPENING : SW_PARENTCLOSING);
2664 pWnd[count]->flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
2665 }
2666 }
2667 else
2668 {
2669 if (IsWindowVisible(pWnd[count]->hwndSelf))
2670 {
2671 SendMessageA(pWnd[count]->hwndSelf, WM_SHOWWINDOW, SW_HIDE, IsIconic(owner) ? SW_PARENTOPENING : SW_PARENTCLOSING);
2672 pWnd[count]->flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
2673 }
2674 }
2675 }
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002676 }
Noomen Hamzaa018d851999-09-28 16:26:09 +00002677
2678 WIN_ReleaseDesktop();
2679 WIN_ReleaseWinArray(pWnd);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002680 return TRUE;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002681}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002682
2683
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002684/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002685 * GetLastActivePopup16 (USER.287)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002686 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002687HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002688{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002689 return GetLastActivePopup( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002690}
2691
2692/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002693 * GetLastActivePopup (USER32.256)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002694 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002695HWND WINAPI GetLastActivePopup( HWND hwnd )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002696{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002697 HWND retval;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002698 WND *wndPtr =WIN_FindWndPtr(hwnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002699 if (!wndPtr) return hwnd;
2700 retval = wndPtr->hwndLastActive;
2701 WIN_ReleaseWndPtr(wndPtr);
2702 return retval;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002703}
2704
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002705
2706/*******************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002707 * WIN_BuildWinArray
2708 *
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002709 * Build an array of pointers to the children of a given window.
Alexandre Julliard90476d62000-02-16 22:47:24 +00002710 * The array must be freed with WIN_ReleaseWinArray. Return NULL
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002711 * when no windows are found.
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002712 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002713WND **WIN_BuildWinArray( WND *wndPtr, UINT bwaFlags, UINT* pTotal )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002714{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002715 /* Future: this function will lock all windows associated with this array */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002716
Alexandre Julliard3051b641996-07-05 17:14:13 +00002717 WND **list, **ppWnd;
2718 WND *pWnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002719 UINT count = 0, skipOwned, skipHidden;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002720 DWORD skipFlags;
2721
2722 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2723 skipOwned = bwaFlags & BWA_SKIPOWNED;
2724 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2725 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002726
2727 /* First count the windows */
2728
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002729 if (!wndPtr)
2730 wndPtr = WIN_GetDesktop();
2731
2732 pWnd = WIN_LockWndPtr(wndPtr->child);
2733 while (pWnd)
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002734 {
Alex Korobka44a1b591999-04-01 12:03:52 +00002735 if( !(pWnd->dwStyle & skipFlags) && !(skipOwned && pWnd->owner) &&
2736 (!skipHidden || (pWnd->dwStyle & WS_VISIBLE)) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002737 count++;
Alex Korobka44a1b591999-04-01 12:03:52 +00002738 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002739 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002740
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002741 if( count )
2742 {
2743 /* Now build the list of all windows */
Alexandre Julliard3051b641996-07-05 17:14:13 +00002744
Alexandre Julliard90476d62000-02-16 22:47:24 +00002745 if ((list = (WND **)HeapAlloc( GetProcessHeap(), 0, sizeof(WND *) * (count + 1))))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002746 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002747 for (pWnd = WIN_LockWndPtr(wndPtr->child), ppWnd = list, count = 0; pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002748 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002749 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) );
2750 else if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002751 {
2752 *ppWnd++ = pWnd;
2753 count++;
2754 }
2755 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002756 WIN_ReleaseWndPtr(pWnd);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002757 *ppWnd = NULL;
2758 }
2759 else count = 0;
2760 } else list = NULL;
2761
2762 if( pTotal ) *pTotal = count;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002763 return list;
2764}
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002765/*******************************************************************
2766 * WIN_ReleaseWinArray
2767 */
2768void WIN_ReleaseWinArray(WND **wndArray)
2769{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002770 /* Future: this function will also unlock all windows associated with wndArray */
Alexandre Julliard90476d62000-02-16 22:47:24 +00002771 HeapFree( GetProcessHeap(), 0, wndArray );
Alexandre Julliard3051b641996-07-05 17:14:13 +00002772
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002773}
Alexandre Julliard3051b641996-07-05 17:14:13 +00002774
2775/*******************************************************************
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002776 * EnumWindows (USER32.193)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002777 */
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002778BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002779{
2780 WND **list, **ppWnd;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002781
Alexandre Julliard594997c1995-04-30 10:05:20 +00002782 /* We have to build a list of all windows first, to avoid */
Andreas Mohr1c20b392000-02-20 19:17:35 +00002783 /* unpleasant side-effects, for instance if the callback */
2784 /* function changes the Z-order of the windows. */
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002785
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002786 if (!(list = WIN_BuildWinArray(WIN_GetDesktop(), 0, NULL )))
2787 {
2788 WIN_ReleaseDesktop();
2789 return FALSE;
2790 }
Alexandre Julliard594997c1995-04-30 10:05:20 +00002791
Alexandre Julliard3051b641996-07-05 17:14:13 +00002792 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002793
Alexandre Julliard3051b641996-07-05 17:14:13 +00002794 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002795 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002796 LRESULT lpEnumFuncRetval;
2797 int iWndsLocks = 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002798 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002799 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Francois Boisvertd96bc151999-04-02 10:34:43 +00002800
2801 /* To avoid any deadlocks, all the locks on the windows
2802 structures must be suspended before the control
2803 is passed to the application */
2804 iWndsLocks = WIN_SuspendWndsLock();
2805 lpEnumFuncRetval = lpEnumFunc( (*ppWnd)->hwndSelf, lParam);
2806 WIN_RestoreWndsLock(iWndsLocks);
2807
2808 if (!lpEnumFuncRetval) break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002809 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002810 WIN_ReleaseWinArray(list);
2811 WIN_ReleaseDesktop();
Alexandre Julliard3051b641996-07-05 17:14:13 +00002812 return TRUE;
2813}
2814
2815
Alexandre Julliard594997c1995-04-30 10:05:20 +00002816/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002817 * EnumTaskWindows16 (USER.225)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002818 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002819BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2820 LPARAM lParam )
Alexandre Julliard594997c1995-04-30 10:05:20 +00002821{
Alexandre Julliard3051b641996-07-05 17:14:13 +00002822 WND **list, **ppWnd;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002823
2824 /* This function is the same as EnumWindows(), */
Per Ångströma47bc3a1998-11-14 17:00:37 +00002825 /* except for an added check on the window's task. */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002826
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002827 if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
2828 {
2829 WIN_ReleaseDesktop();
2830 return FALSE;
2831 }
Alexandre Julliard594997c1995-04-30 10:05:20 +00002832
Alexandre Julliard3051b641996-07-05 17:14:13 +00002833 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002834
Alexandre Julliard3051b641996-07-05 17:14:13 +00002835 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002836 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002837 LRESULT funcRetval;
2838 int iWndsLocks = 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002839 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002840 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Per Ångströma47bc3a1998-11-14 17:00:37 +00002841 if (QUEUE_GetQueueTask((*ppWnd)->hmemTaskQ) != hTask) continue;
Francois Boisvertd96bc151999-04-02 10:34:43 +00002842
2843 /* To avoid any deadlocks, all the locks on the windows
2844 structures must be suspended before the control
2845 is passed to the application */
2846 iWndsLocks = WIN_SuspendWndsLock();
2847 funcRetval = func( (*ppWnd)->hwndSelf, lParam );
2848 WIN_RestoreWndsLock(iWndsLocks);
2849
2850 if (!funcRetval) break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002851 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002852 WIN_ReleaseWinArray(list);
2853 WIN_ReleaseDesktop();
Alexandre Julliard594997c1995-04-30 10:05:20 +00002854 return TRUE;
2855}
2856
2857
Alexandre Julliard3051b641996-07-05 17:14:13 +00002858/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002859 * EnumThreadWindows (USER32.190)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002860 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002861BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002862{
Alexandre Julliard0a860a01999-06-22 11:43:42 +00002863 TEB *teb = THREAD_IdToTEB(id);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002864
Alexandre Julliard0a860a01999-06-22 11:43:42 +00002865 return (BOOL16)EnumTaskWindows16(teb->htask16, (WNDENUMPROC16)func, lParam);
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002866}
2867
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002868
Alexandre Julliard3051b641996-07-05 17:14:13 +00002869/**********************************************************************
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002870 * WIN_EnumChildWindows
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002871 *
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002872 * Helper function for EnumChildWindows().
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002873 */
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002874static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002875{
Alexandre Julliard3051b641996-07-05 17:14:13 +00002876 WND **childList;
2877 BOOL16 ret = FALSE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002878
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002879 for ( ; *ppWnd; ppWnd++)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002880 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002881 int iWndsLocks = 0;
2882
Alexandre Julliard3051b641996-07-05 17:14:13 +00002883 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002884 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002885 /* Build children list first */
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002886 childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
Francois Boisvertd96bc151999-04-02 10:34:43 +00002887
2888 /* To avoid any deadlocks, all the locks on the windows
2889 structures must be suspended before the control
2890 is passed to the application */
2891 iWndsLocks = WIN_SuspendWndsLock();
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002892 ret = func( (*ppWnd)->hwndSelf, lParam );
Francois Boisvertd96bc151999-04-02 10:34:43 +00002893 WIN_RestoreWndsLock(iWndsLocks);
2894
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002895 if (childList)
2896 {
2897 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002898 WIN_ReleaseWinArray(childList);
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002899 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002900 if (!ret) return FALSE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002901 }
2902 return TRUE;
2903}
2904
2905
2906/**********************************************************************
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002907 * EnumChildWindows (USER32.178)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002908 */
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002909BOOL WINAPI EnumChildWindows( HWND parent, WNDENUMPROC func,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002910 LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002911{
2912 WND **list, *pParent;
2913
2914 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002915 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL )))
2916 {
2917 WIN_ReleaseWndPtr(pParent);
2918 return FALSE;
2919 }
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002920 WIN_EnumChildWindows( list, func, lParam );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002921 WIN_ReleaseWinArray(list);
2922 WIN_ReleaseWndPtr(pParent);
Alexandre Julliard3051b641996-07-05 17:14:13 +00002923 return TRUE;
2924}
2925
2926
Alexandre Julliard58199531994-04-21 01:20:00 +00002927/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002928 * AnyPopup16 (USER.52)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002929 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002930BOOL16 WINAPI AnyPopup16(void)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002931{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002932 return AnyPopup();
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002933}
2934
2935
2936/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002937 * AnyPopup (USER32.4)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002938 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002939BOOL WINAPI AnyPopup(void)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002940{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002941 WND *wndPtr = WIN_LockWndPtr(pWndDesktop->child);
2942 BOOL retvalue;
2943
2944 while (wndPtr)
2945 {
2946 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE))
2947 {
2948 retvalue = TRUE;
2949 goto end;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002950 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002951 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
2952 }
2953 retvalue = FALSE;
2954end:
2955 WIN_ReleaseWndPtr(wndPtr);
2956 return retvalue;
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002957}
2958
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002959
Alexandre Julliard73450d61994-05-18 18:29:32 +00002960/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002961 * FlashWindow16 (USER.105)
Alexandre Julliard73450d61994-05-18 18:29:32 +00002962 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002963BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002964{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002965 return FlashWindow( hWnd, bInvert );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002966}
2967
2968
2969/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002970 * FlashWindow (USER32.202)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002971 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002972BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert )
Alexandre Julliard73450d61994-05-18 18:29:32 +00002973{
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002974 WND *wndPtr = WIN_FindWndPtr(hWnd);
2975
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002976 TRACE("%04x\n", hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002977
2978 if (!wndPtr) return FALSE;
2979
2980 if (wndPtr->dwStyle & WS_MINIMIZE)
2981 {
2982 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2983 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002984 HDC hDC = GetDC(hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002985
Alexandre Julliard530ee841996-10-23 16:59:13 +00002986 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002987 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2988
Alexandre Julliarda3960291999-02-26 11:11:13 +00002989 ReleaseDC( hWnd, hDC );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002990 wndPtr->flags |= WIN_NCACTIVATED;
2991 }
2992 else
2993 {
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002994 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2995 RDW_UPDATENOW | RDW_FRAME, 0 );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002996 wndPtr->flags &= ~WIN_NCACTIVATED;
2997 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002998 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002999 return TRUE;
3000 }
3001 else
3002 {
Alexandre Julliard530ee841996-10-23 16:59:13 +00003003 WPARAM16 wparam;
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003004 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
Alexandre Julliarda3960291999-02-26 11:11:13 +00003005 else wparam = (hWnd == GetActiveWindow());
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003006
Alexandre Julliard2d93d001996-05-21 15:01:41 +00003007 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003008 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003009 return wparam;
3010 }
Alexandre Julliard73450d61994-05-18 18:29:32 +00003011}
3012
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003013
3014/*******************************************************************
Alexandre Julliard18f92e71996-07-17 20:02:21 +00003015 * SetSysModalWindow16 (USER.188)
Alexandre Julliard58199531994-04-21 01:20:00 +00003016 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003017HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
Alexandre Julliard58199531994-04-21 01:20:00 +00003018{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003019 HWND hWndOldModal = hwndSysModal;
Alexandre Julliardd4719651995-12-12 18:49:11 +00003020 hwndSysModal = hWnd;
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00003021 FIXME("EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
Alexandre Julliardd4719651995-12-12 18:49:11 +00003022 return hWndOldModal;
Alexandre Julliard58199531994-04-21 01:20:00 +00003023}
3024
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003025
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003026/*******************************************************************
Alexandre Julliard18f92e71996-07-17 20:02:21 +00003027 * GetSysModalWindow16 (USER.52)
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003028 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003029HWND16 WINAPI GetSysModalWindow16(void)
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003030{
Alexandre Julliardd4719651995-12-12 18:49:11 +00003031 return hwndSysModal;
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003032}
Alexandre Julliardade697e1995-11-26 13:59:11 +00003033
Alexandre Julliard18f92e71996-07-17 20:02:21 +00003034
Alexandre Julliardade697e1995-11-26 13:59:11 +00003035/*******************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003036 * GetWindowContextHelpId (USER32.303)
3037 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003038DWORD WINAPI GetWindowContextHelpId( HWND hwnd )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003039{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003040 DWORD retval;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003041 WND *wnd = WIN_FindWndPtr( hwnd );
3042 if (!wnd) return 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003043 retval = wnd->helpContext;
3044 WIN_ReleaseWndPtr(wnd);
3045 return retval;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003046}
3047
3048
3049/*******************************************************************
3050 * SetWindowContextHelpId (USER32.515)
3051 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003052BOOL WINAPI SetWindowContextHelpId( HWND hwnd, DWORD id )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003053{
3054 WND *wnd = WIN_FindWndPtr( hwnd );
3055 if (!wnd) return FALSE;
3056 wnd->helpContext = id;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003057 WIN_ReleaseWndPtr(wnd);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003058 return TRUE;
3059}
3060
3061
3062/*******************************************************************
Alexandre Julliardade697e1995-11-26 13:59:11 +00003063 * DRAG_QueryUpdate
3064 *
3065 * recursively find a child that contains spDragInfo->pt point
3066 * and send WM_QUERYDROPOBJECT
3067 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003068BOOL16 DRAG_QueryUpdate( HWND hQueryWnd, SEGPTR spDragInfo, BOOL bNoSend )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003069{
Andreas Mohr1c20b392000-02-20 19:17:35 +00003070 BOOL16 wParam, bResult = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003071 POINT pt;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003072 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
3073 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003074 RECT tempRect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003075
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003076 if( !ptrQueryWnd || !ptrDragInfo )
Andreas Mohr1c20b392000-02-20 19:17:35 +00003077 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003078
Alexandre Julliardd37eb361997-07-20 16:23:21 +00003079 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003080
Alexandre Julliarda3960291999-02-26 11:11:13 +00003081 GetWindowRect(hQueryWnd,&tempRect);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003082
Alexandre Julliarda3960291999-02-26 11:11:13 +00003083 if( !PtInRect(&tempRect,pt) ||
Alexandre Julliardade697e1995-11-26 13:59:11 +00003084 (ptrQueryWnd->dwStyle & WS_DISABLED) )
Andreas Mohr1c20b392000-02-20 19:17:35 +00003085 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003086
3087 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
3088 {
3089 tempRect = ptrQueryWnd->rectClient;
3090 if(ptrQueryWnd->dwStyle & WS_CHILD)
Alexandre Julliarda3960291999-02-26 11:11:13 +00003091 MapWindowPoints( ptrQueryWnd->parent->hwndSelf, 0,
3092 (LPPOINT)&tempRect, 2 );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003093
Alexandre Julliarda3960291999-02-26 11:11:13 +00003094 if (PtInRect( &tempRect, pt))
Alexandre Julliardade697e1995-11-26 13:59:11 +00003095 {
3096 wParam = 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003097
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003098 for (ptrWnd = WIN_LockWndPtr(ptrQueryWnd->child); ptrWnd ;WIN_UpdateWndPtr(&ptrWnd,ptrWnd->next))
3099 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003100 if( ptrWnd->dwStyle & WS_VISIBLE )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003101 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003102 GetWindowRect( ptrWnd->hwndSelf, &tempRect );
3103 if (PtInRect( &tempRect, pt )) break;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003104 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003105 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003106
3107 if(ptrWnd)
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003108 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +00003109 TRACE_(msg)("hwnd = %04x, %d %d - %d %d\n",
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003110 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
3111 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
3112 if( !(ptrWnd->dwStyle & WS_DISABLED) )
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003113 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003114
3115 WIN_ReleaseWndPtr(ptrWnd);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003116 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003117
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003118 if(bResult)
Andreas Mohr1c20b392000-02-20 19:17:35 +00003119 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003120 }
3121 else wParam = 1;
3122 }
3123 else wParam = 1;
3124
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00003125 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003126
3127 ptrDragInfo->hScope = hQueryWnd;
3128
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003129 bResult = ( bNoSend )
3130 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
3131 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
Alexandre Julliard530ee841996-10-23 16:59:13 +00003132 (WPARAM16)wParam ,(LPARAM) spDragInfo );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003133 if( !bResult )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00003134 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003135
Andreas Mohr1c20b392000-02-20 19:17:35 +00003136end:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003137 WIN_ReleaseWndPtr(ptrQueryWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003138 return bResult;
3139}
3140
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003141
Alexandre Julliardade697e1995-11-26 13:59:11 +00003142/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003143 * DragDetect (USER.465)
Alexandre Julliardade697e1995-11-26 13:59:11 +00003144 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003145BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003146{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003147 POINT pt32;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003148 CONV_POINT16TO32( &pt, &pt32 );
Alexandre Julliarda3960291999-02-26 11:11:13 +00003149 return DragDetect( hWnd, pt32 );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003150}
3151
3152/*******************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003153 * DragDetect (USER32.151)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003154 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003155BOOL WINAPI DragDetect( HWND hWnd, POINT pt )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003156{
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003157 MSG16 msg;
3158 RECT16 rect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003159
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003160 rect.left = pt.x - wDragWidth;
3161 rect.right = pt.x + wDragWidth;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003162
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003163 rect.top = pt.y - wDragHeight;
3164 rect.bottom = pt.y + wDragHeight;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003165
Alexandre Julliarda3960291999-02-26 11:11:13 +00003166 SetCapture(hWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003167
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003168 while(1)
3169 {
3170 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
3171 {
3172 if( msg.message == WM_LBUTTONUP )
3173 {
3174 ReleaseCapture();
3175 return 0;
3176 }
3177 if( msg.message == WM_MOUSEMOVE )
3178 {
3179 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003180 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003181 ReleaseCapture();
3182 return 1;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003183 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003184 }
3185 }
3186 WaitMessage();
3187 }
3188 return 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003189}
3190
3191/******************************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00003192 * DragObject16 (USER.464)
Alexandre Julliardade697e1995-11-26 13:59:11 +00003193 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003194DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
3195 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003196{
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003197 MSG16 msg;
3198 LPDRAGINFO lpDragInfo;
3199 SEGPTR spDragInfo;
3200 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
3201 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
3202 WND *wndPtr = WIN_FindWndPtr(hWnd);
3203 HCURSOR16 hCurrentCursor = 0;
3204 HWND16 hCurrentWnd = 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003205
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003206 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
3207 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003208
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003209 if( !lpDragInfo || !spDragInfo )
3210 {
3211 WIN_ReleaseWndPtr(wndPtr);
3212 return 0L;
3213 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003214
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003215 hBummer = LoadCursor16(0, IDC_BUMMER16);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003216
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003217 if( !hBummer || !wndPtr )
3218 {
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00003219 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003220 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003221 return 0L;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003222 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003223
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003224 if(hCursor)
3225 {
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003226 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003227 {
3228 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003229 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003230 return 0L;
3231 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003232
3233 if( hDragCursor == hCursor ) hDragCursor = 0;
3234 else hCursor = hDragCursor;
3235
Alexandre Julliarda3960291999-02-26 11:11:13 +00003236 hOldCursor = SetCursor(hDragCursor);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003237 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003238
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003239 lpDragInfo->hWnd = hWnd;
3240 lpDragInfo->hScope = 0;
3241 lpDragInfo->wFlags = wObj;
3242 lpDragInfo->hList = szList; /* near pointer! */
3243 lpDragInfo->hOfStruct = hOfStruct;
3244 lpDragInfo->l = 0L;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003245
Alexandre Julliarda3960291999-02-26 11:11:13 +00003246 SetCapture(hWnd);
3247 ShowCursor( TRUE );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003248
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003249 do
3250 {
3251 do{ WaitMessage(); }
3252 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003253
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003254 *(lpDragInfo+1) = *lpDragInfo;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003255
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003256 lpDragInfo->pt = msg.pt;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003257
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003258 /* update DRAGINFO struct */
Alexandre Julliard06c275a1999-05-02 14:32:27 +00003259 TRACE_(msg)("lpDI->hScope = %04x\n",lpDragInfo->hScope);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003260
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003261 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
3262 hCurrentCursor = hCursor;
3263 else
Alexandre Julliardade697e1995-11-26 13:59:11 +00003264 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003265 hCurrentCursor = hBummer;
3266 lpDragInfo->hScope = 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003267 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003268 if( hCurrentCursor )
Alexandre Julliarda3960291999-02-26 11:11:13 +00003269 SetCursor(hCurrentCursor);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003270
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003271 /* send WM_DRAGLOOP */
3272 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
3273 (LPARAM) spDragInfo );
3274 /* send WM_DRAGSELECT or WM_DRAGMOVE */
3275 if( hCurrentWnd != lpDragInfo->hScope )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003276 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003277 if( hCurrentWnd )
3278 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
Alexandre Julliardade697e1995-11-26 13:59:11 +00003279 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
3280 HIWORD(spDragInfo)) );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003281 hCurrentWnd = lpDragInfo->hScope;
3282 if( hCurrentWnd )
3283 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003284 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003285 else
3286 if( hCurrentWnd )
3287 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
3288
3289 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
3290
3291 ReleaseCapture();
Alexandre Julliarda3960291999-02-26 11:11:13 +00003292 ShowCursor( FALSE );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003293
3294 if( hCursor )
3295 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003296 SetCursor( hOldCursor );
3297 if (hDragCursor) DestroyCursor( hDragCursor );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003298 }
3299
3300 if( hCurrentCursor != hBummer )
3301 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
3302 (WPARAM16)hWnd, (LPARAM)spDragInfo );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003303 else
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003304 msg.lParam = 0;
3305 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003306 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003307
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003308 return (DWORD)(msg.lParam);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003309}