blob: 938b48c62c9c9704bf65ac816fbd7270cae70372 [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 Julliard85ed45e1998-08-22 19:03:56 +000030#include "process.h"
Alexandre Julliard767e6f61998-08-09 12:47:43 +000031#include "winerror.h"
Rein Klazes5c6fc1b1998-11-01 14:50:06 +000032#include "mdi.h"
Patrik Stridvall8d8703c1999-02-04 14:05:38 +000033#include "local.h"
34#include "desktop.h"
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000035#include "syslevel.h"
Alexandre Julliard4220b291999-07-11 17:20:01 +000036#include "stackframe.h"
37#include "debugtools.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000038
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +000039DEFAULT_DEBUG_CHANNEL(win)
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000040DECLARE_DEBUG_CHANNEL(msg)
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000041
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000042/**********************************************************************/
43
44WND_DRIVER *WND_Driver = NULL;
Patrik Stridvalle35d6361998-12-07 09:13:40 +000045
Alexandre Julliard59730ae1996-03-24 16:20:51 +000046/* Desktop window */
47static WND *pWndDesktop = NULL;
48
Alexandre Julliarda3960291999-02-26 11:11:13 +000049static HWND hwndSysModal = 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +000050
Alexandre Julliardd4719651995-12-12 18:49:11 +000051static WORD wDragWidth = 4;
52static WORD wDragHeight= 3;
Alexandre Julliardade697e1995-11-26 13:59:11 +000053
Francois Boisvert93e3f901999-02-25 17:32:31 +000054/* thread safeness */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000055static SYSLEVEL WIN_SysLevel;
Francois Boisvert93e3f901999-02-25 17:32:31 +000056
57/***********************************************************************
Ulrich Weigandef61c0b1999-05-08 09:45:50 +000058 * WIN_Init
59 */
60void WIN_Init( void )
61{
62 /* Initialisation of the critical section for thread safeness */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000063 _CreateSysLevel( &WIN_SysLevel, 2 );
Ulrich Weigandef61c0b1999-05-08 09:45:50 +000064}
65
66/***********************************************************************
Francois Boisvert93e3f901999-02-25 17:32:31 +000067 * WIN_LockWnds
68 *
69 * Locks access to all WND structures for thread safeness
70 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000071void WIN_LockWnds( void )
Francois Boisvert93e3f901999-02-25 17:32:31 +000072{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000073 _EnterSysLevel( &WIN_SysLevel );
Francois Boisvert93e3f901999-02-25 17:32:31 +000074}
75
76/***********************************************************************
77 * WIN_UnlockWnds
78 *
79 * Unlocks access to all WND structures
80 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000081void WIN_UnlockWnds( void )
Ove Kaavenbcb4bb61999-05-12 10:07:02 +000082{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000083 _LeaveSysLevel( &WIN_SysLevel );
Francois Boisvert93e3f901999-02-25 17:32:31 +000084}
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000085
Francois Boisvert93e3f901999-02-25 17:32:31 +000086/***********************************************************************
87 * WIN_SuspendWndsLock
88 *
89 * Suspend the lock on WND structures.
90 * Returns the number of locks suspended
91 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000092int WIN_SuspendWndsLock( void )
Francois Boisvert93e3f901999-02-25 17:32:31 +000093{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000094 int isuspendedLocks = _ConfirmSysLevel( &WIN_SysLevel );
95 int count = isuspendedLocks;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +000096
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000097 while ( count-- > 0 )
98 _LeaveSysLevel( &WIN_SysLevel );
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +000099
Francois Boisvert93e3f901999-02-25 17:32:31 +0000100 return isuspendedLocks;
Francois Boisvert93e3f901999-02-25 17:32:31 +0000101}
102
103/***********************************************************************
104 * WIN_RestoreWndsLock
105 *
106 * Restore the suspended locks on WND structures
107 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +0000108void WIN_RestoreWndsLock( int ipreviousLocks )
Francois Boisvert93e3f901999-02-25 17:32:31 +0000109{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +0000110 while ( ipreviousLocks-- > 0 )
111 _EnterSysLevel( &WIN_SysLevel );
Francois Boisvert93e3f901999-02-25 17:32:31 +0000112}
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000113
Alexandre Julliard401710d1993-09-04 10:09:32 +0000114/***********************************************************************
115 * WIN_FindWndPtr
116 *
117 * Return a pointer to the WND structure corresponding to a HWND.
Alexandre Julliard401710d1993-09-04 10:09:32 +0000118 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000119WND * WIN_FindWndPtr( HWND hwnd )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000120{
121 WND * ptr;
122
Francois Boisvert93e3f901999-02-25 17:32:31 +0000123 if (!hwnd || HIWORD(hwnd)) goto error2;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000124 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000125 /* Lock all WND structures for thread safeness*/
126 WIN_LockWnds();
127 /*and increment destruction monitoring*/
Francois Boisvert93e3f901999-02-25 17:32:31 +0000128 ptr->irefCount++;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000129
Eric Pouechb9544f11999-02-14 14:09:42 +0000130 if (ptr->dwMagic != WND_MAGIC) goto error;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000131 if (ptr->hwndSelf != hwnd)
132 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000133 ERR("Can't happen: hwnd %04x self pointer is %04x\n",hwnd, ptr->hwndSelf );
Eric Pouechb9544f11999-02-14 14:09:42 +0000134 goto error;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000135 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000136 /* returns a locked pointer */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000137 return ptr;
Eric Pouechb9544f11999-02-14 14:09:42 +0000138 error:
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000139 /* Unlock all WND structures for thread safeness*/
140 WIN_UnlockWnds();
141 /* and decrement destruction monitoring value */
Francois Boisvert93e3f901999-02-25 17:32:31 +0000142 ptr->irefCount--;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000143
Francois Boisvert93e3f901999-02-25 17:32:31 +0000144error2:
Juergen Schmied1e0bc841999-02-28 11:08:13 +0000145 if ( hwnd!=0 )
146 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
Eric Pouechb9544f11999-02-14 14:09:42 +0000147 return NULL;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000148}
149
Francois Boisvert93e3f901999-02-25 17:32:31 +0000150/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000151 * WIN_LockWndPtr
152 *
153 * Use in case the wnd ptr is not initialized with WIN_FindWndPtr
154 * but by initWndPtr;
155 * Returns the locked initialisation pointer
156 */
157WND *WIN_LockWndPtr(WND *initWndPtr)
158{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000159 if(!initWndPtr) return 0;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000160
161 /* Lock all WND structures for thread safeness*/
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000162 WIN_LockWnds();
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000163 /*and increment destruction monitoring*/
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000164 initWndPtr->irefCount++;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000165
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000166 return initWndPtr;
167
168}
169
170/***********************************************************************
Francois Boisvert93e3f901999-02-25 17:32:31 +0000171 * WIN_ReleaseWndPtr
172 *
173 * Release the pointer to the WND structure.
174 */
175void WIN_ReleaseWndPtr(WND *wndPtr)
176{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000177 if(!wndPtr) return;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000178
179 /*Decrement destruction monitoring value*/
Francois Boisvert93e3f901999-02-25 17:32:31 +0000180 wndPtr->irefCount--;
Francois Boisvert86e2e111999-04-03 11:13:33 +0000181 /* Check if it's time to release the memory*/
182 if(wndPtr->irefCount == 0 && !wndPtr->dwMagic)
Francois Boisvert93e3f901999-02-25 17:32:31 +0000183 {
Francois Boisvert86e2e111999-04-03 11:13:33 +0000184 /* Release memory */
185 USER_HEAP_FREE( wndPtr->hwndSelf);
Francis Beaudet48126471999-05-22 19:21:01 +0000186 wndPtr->hwndSelf = 0;
Francois Boisvert93e3f901999-02-25 17:32:31 +0000187 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000188 else if(wndPtr->irefCount < 0)
189 {
190 /* This else if is useful to monitor the WIN_ReleaseWndPtr function */
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000191 ERR("forgot a Lock on %p somewhere\n",wndPtr);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000192 }
193 /*unlock all WND structures for thread safeness*/
Francois Boisvert93e3f901999-02-25 17:32:31 +0000194 WIN_UnlockWnds();
Francois Boisvert93e3f901999-02-25 17:32:31 +0000195}
196
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000197/***********************************************************************
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000198 * WIN_UpdateWndPtr
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000199 *
200 * Updates the value of oldPtr to newPtr.
201 */
202void WIN_UpdateWndPtr(WND **oldPtr, WND *newPtr)
203{
204 WND *tmpWnd = NULL;
205
206 tmpWnd = WIN_LockWndPtr(newPtr);
207 WIN_ReleaseWndPtr(*oldPtr);
208 *oldPtr = tmpWnd;
209
210}
Alexandre Julliard401710d1993-09-04 10:09:32 +0000211
212/***********************************************************************
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000213 * WIN_DumpWindow
214 *
215 * Dump the content of a window structure to stderr.
216 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000217void WIN_DumpWindow( HWND hwnd )
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000218{
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000219 WND *ptr;
220 char className[80];
221 int i;
222
223 if (!(ptr = WIN_FindWndPtr( hwnd )))
224 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000225 WARN("%04x is not a window handle\n", hwnd );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000226 return;
227 }
228
Alexandre Julliarda3960291999-02-26 11:11:13 +0000229 if (!GetClassNameA( hwnd, className, sizeof(className ) ))
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000230 strcpy( className, "#NULL#" );
231
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000232 TRACE("Window %04x (%p):\n", hwnd, ptr );
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000233 DPRINTF( "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000234 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000235 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000236 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000237 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000238 ptr->next, ptr->child, ptr->parent, ptr->owner,
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000239 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000240 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000241 ptr->dwStyle, ptr->dwExStyle, (UINT)ptr->winproc,
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000242 ptr->text ? ptr->text : "",
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000243 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
244 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000245 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000246 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000247
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000248 if (ptr->class->cbWndExtra)
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000249 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000250 DPRINTF( "extra bytes:" );
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000251 for (i = 0; i < ptr->class->cbWndExtra; i++)
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000252 DPRINTF( " %02x", *((BYTE*)ptr->wExtra+i) );
253 DPRINTF( "\n" );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000254 }
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000255 DPRINTF( "\n" );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000256 WIN_ReleaseWndPtr(ptr);
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000257}
258
259
260/***********************************************************************
261 * WIN_WalkWindows
262 *
263 * Walk the windows tree and print each window on stderr.
264 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000265void WIN_WalkWindows( HWND hwnd, int indent )
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000266{
267 WND *ptr;
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000268 char className[80];
269
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000270 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : WIN_GetDesktop();
271
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000272 if (!ptr)
273 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000274 WARN("Invalid window handle %04x\n", hwnd );
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000275 return;
276 }
277
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000278 if (!indent) /* first time around */
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000279 DPRINTF( "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
Rein Klazesd62c62b1998-10-11 14:05:34 +0000280 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc"
281 " Text");
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000282
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000283 while (ptr)
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000284 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000285 DPRINTF( "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000286
Alexandre Julliardb849d792000-02-13 13:56:13 +0000287 GlobalGetAtomNameA(ptr->class->atomName,className,sizeof(className));
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000288
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000289 DPRINTF( "%08lx %-6.4x %-17.17s %08x %08x %.14s\n",
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000290 (DWORD)ptr, ptr->hmemTaskQ, className,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000291 (UINT)ptr->dwStyle, (UINT)ptr->winproc,
Rein Klazesd62c62b1998-10-11 14:05:34 +0000292 ptr->text?ptr->text:"<null>");
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000293
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000294 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000295 WIN_UpdateWndPtr(&ptr,ptr->next);
296
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000297 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000298
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000299}
300
Alexandre Julliardaca05781994-10-17 18:12:41 +0000301/***********************************************************************
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000302 * WIN_UnlinkWindow
303 *
304 * Remove a window from the siblings linked list.
305 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000306BOOL WIN_UnlinkWindow( HWND hwnd )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000307{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000308 WND *wndPtr, **ppWnd;
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000309 BOOL ret = FALSE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000310
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000311 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
312 else if(!wndPtr->parent)
313 {
314 WIN_ReleaseWndPtr(wndPtr);
315 return FALSE;
316 }
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000317
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000318 ppWnd = &wndPtr->parent->child;
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000319 while (*ppWnd && *ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
320 if (*ppWnd)
321 {
322 *ppWnd = wndPtr->next;
323 ret = TRUE;
324 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000325 WIN_ReleaseWndPtr(wndPtr);
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000326 return ret;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000327}
328
329
330/***********************************************************************
331 * WIN_LinkWindow
332 *
333 * Insert a window into the siblings linked list.
334 * The window is inserted after the specified window, which can also
335 * be specified as HWND_TOP or HWND_BOTTOM.
336 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000337BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000338{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000339 WND *wndPtr, **ppWnd;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000340
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000341 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
342 else if(!wndPtr->parent)
343 {
344 WIN_ReleaseWndPtr(wndPtr);
345 return FALSE;
346 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000347 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
348 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000349 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000350 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000351 while (*ppWnd) ppWnd = &(*ppWnd)->next;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000352 }
353 else /* Normal case */
354 {
355 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000356 if (!afterPtr)
357 {
358 WIN_ReleaseWndPtr(wndPtr);
359 return FALSE;
360 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000361 ppWnd = &afterPtr->next;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000362 WIN_ReleaseWndPtr(afterPtr);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000363 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000364 wndPtr->next = *ppWnd;
365 *ppWnd = wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000366 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000367 return TRUE;
368}
369
370
371/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000372 * WIN_FindWinToRepaint
373 *
374 * Find a window that needs repaint.
375 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000376HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE16 hQueue )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000377{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000378 HWND hwndRet;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000379 WND *pWnd;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000380
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000381 /* Note: the desktop window never gets WM_PAINT messages
382 * The real reason why is because Windows DesktopWndProc
383 * does ValidateRgn inside WM_ERASEBKGND handler.
384 */
385
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000386 pWnd = hwnd ? WIN_FindWndPtr(hwnd) : WIN_LockWndPtr(pWndDesktop->child);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000387
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000388 for ( ; pWnd ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard401710d1993-09-04 10:09:32 +0000389 {
Alexandre Julliarde658d821997-11-30 17:45:40 +0000390 if (!(pWnd->dwStyle & WS_VISIBLE))
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000391 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000392 TRACE("skipping window %04x\n",
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000393 pWnd->hwndSelf );
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000394 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000395 else if ((pWnd->hmemTaskQ == hQueue) &&
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000396 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)))
397 break;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000398
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000399 else if (pWnd->child )
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000400 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000401 {
402 WIN_ReleaseWndPtr(pWnd);
403 return hwndRet;
404 }
405
Alexandre Julliard401710d1993-09-04 10:09:32 +0000406 }
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000407
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000408 if(!pWnd)
409 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000410 return 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000411 }
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000412
413 hwndRet = pWnd->hwndSelf;
414
415 /* look among siblings if we got a transparent window */
416 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
417 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
418 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000419 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000420 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000421 if (pWnd)
422 {
423 hwndRet = pWnd->hwndSelf;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000424 WIN_ReleaseWndPtr(pWnd);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000425 }
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000426 TRACE("found %04x\n",hwndRet);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000427 return hwndRet;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000428}
429
430
431/***********************************************************************
Alexandre Julliardaca05781994-10-17 18:12:41 +0000432 * WIN_DestroyWindow
433 *
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000434 * Destroy storage associated to a window. "Internals" p.358
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000435 * returns a locked wndPtr->next
Alexandre Julliardaca05781994-10-17 18:12:41 +0000436 */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000437static WND* WIN_DestroyWindow( WND* wndPtr )
Alexandre Julliardaca05781994-10-17 18:12:41 +0000438{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000439 HWND hwnd = wndPtr->hwndSelf;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000440 WND *pWnd;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000441
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000442 TRACE("%04x\n", wndPtr->hwndSelf );
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000443
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000444 /* free child windows */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000445 WIN_LockWndPtr(wndPtr->child);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000446 while ((pWnd = wndPtr->child))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000447 {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000448 wndPtr->child = WIN_DestroyWindow( pWnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000449 WIN_ReleaseWndPtr(pWnd);
450 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000451
Francis Beaudet7c2f0fe1999-03-21 08:50:41 +0000452 /*
453 * Clear the update region to make sure no WM_PAINT messages will be
454 * generated for this window while processing the WM_NCDESTROY.
455 */
456 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
457 {
458 if (wndPtr->hrgnUpdate > 1)
459 DeleteObject( wndPtr->hrgnUpdate );
460
461 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
462
463 wndPtr->hrgnUpdate = 0;
464 }
465
466 /*
467 * Send the WM_NCDESTROY to the window being destroyed.
468 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000469 SendMessageA( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000470
471 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
472
Noel Borthwickb4278561999-02-05 10:37:53 +0000473 WINPOS_CheckInternalPos( wndPtr );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000474 if( hwnd == GetCapture()) ReleaseCapture();
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000475
476 /* free resources associated with the window */
477
478 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000479 PROPERTY_RemoveWindowProps( wndPtr );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000480
Alexandre Julliardaca05781994-10-17 18:12:41 +0000481 wndPtr->dwMagic = 0; /* Mark it as invalid */
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000482
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000483 /* toss stale messages from the queue */
484
485 if( wndPtr->hmemTaskQ )
Alexandre Julliardaca05781994-10-17 18:12:41 +0000486 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000487 BOOL bPostQuit = FALSE;
488 WPARAM wQuitParam = 0;
Stephane Lussier1c4786f1999-01-28 10:54:11 +0000489 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) QUEUE_Lock(wndPtr->hmemTaskQ);
Stephane Lussiera4c84451999-01-26 09:30:05 +0000490 QMSG *qmsg;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000491
Stephane Lussiera4c84451999-01-26 09:30:05 +0000492 while( (qmsg = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != 0 )
Alexandre Julliard491502b1997-11-01 19:08:16 +0000493 {
Stephane Lussiera4c84451999-01-26 09:30:05 +0000494 if( qmsg->msg.message == WM_QUIT )
Alexandre Julliard491502b1997-11-01 19:08:16 +0000495 {
496 bPostQuit = TRUE;
Stephane Lussiera4c84451999-01-26 09:30:05 +0000497 wQuitParam = qmsg->msg.wParam;
Alexandre Julliard491502b1997-11-01 19:08:16 +0000498 }
Stephane Lussiera4c84451999-01-26 09:30:05 +0000499 QUEUE_RemoveMsg(msgQ, qmsg);
Alexandre Julliard491502b1997-11-01 19:08:16 +0000500 }
Stephane Lussier1c4786f1999-01-28 10:54:11 +0000501
502 QUEUE_Unlock(msgQ);
503
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +0000504 /* repost WM_QUIT to make sure this app exits its message loop */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000505 if( bPostQuit ) PostQuitMessage(wQuitParam);
Alexandre Julliard491502b1997-11-01 19:08:16 +0000506 wndPtr->hmemTaskQ = 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000507 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000508
509 if (!(wndPtr->dwStyle & WS_CHILD))
Alexandre Julliarda3960291999-02-26 11:11:13 +0000510 if (wndPtr->wIDmenu) DestroyMenu( (HMENU)wndPtr->wIDmenu );
511 if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
Patrik Stridvalle35d6361998-12-07 09:13:40 +0000512 wndPtr->pDriver->pDestroyWindow( wndPtr );
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000513 DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000514 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000515 wndPtr->class->cWindows--;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000516 wndPtr->class = NULL;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000517
518 WIN_UpdateWndPtr(&pWnd,wndPtr->next);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000519
Patrik Stridvall151170c1998-12-26 12:00:43 +0000520 wndPtr->pDriver->pFinalize(wndPtr);
Francois Boisvert86e2e111999-04-03 11:13:33 +0000521
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000522 return pWnd;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000523}
524
Alexandre Julliardaca05781994-10-17 18:12:41 +0000525/***********************************************************************
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000526 * WIN_ResetQueueWindows
Alexandre Julliard77b99181997-09-14 17:17:23 +0000527 *
528 * Reset the queue of all the children of a given window.
529 * Return TRUE if something was done.
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000530 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000531BOOL WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000532{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000533 BOOL ret = FALSE;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000534
Alexandre Julliard77b99181997-09-14 17:17:23 +0000535 if (hNew) /* Set a new queue */
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000536 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000537 for (wnd = WIN_LockWndPtr(wnd->child); (wnd);WIN_UpdateWndPtr(&wnd,wnd->next))
Alexandre Julliard77b99181997-09-14 17:17:23 +0000538 {
539 if (wnd->hmemTaskQ == hQueue)
540 {
541 wnd->hmemTaskQ = hNew;
542 ret = TRUE;
543 }
544 if (wnd->child)
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000545 {
Ulrich Weigand7af95ae1998-12-07 10:24:42 +0000546 ret |= WIN_ResetQueueWindows( wnd, hQueue, hNew );
Alexandre Julliard77b99181997-09-14 17:17:23 +0000547 }
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000548 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000549 }
Alexandre Julliard77b99181997-09-14 17:17:23 +0000550 else /* Queue is being destroyed */
551 {
552 while (wnd->child)
553 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000554 WND *tmp = WIN_LockWndPtr(wnd->child);
555 WND *tmp2;
Alexandre Julliard77b99181997-09-14 17:17:23 +0000556 ret = FALSE;
557 while (tmp)
558 {
559 if (tmp->hmemTaskQ == hQueue)
560 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000561 DestroyWindow( tmp->hwndSelf );
Alexandre Julliard77b99181997-09-14 17:17:23 +0000562 ret = TRUE;
563 break;
564 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000565 tmp2 = WIN_LockWndPtr(tmp->child);
566 if (tmp2 && WIN_ResetQueueWindows(tmp2,hQueue,0))
Alexandre Julliard77b99181997-09-14 17:17:23 +0000567 ret = TRUE;
568 else
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000569 {
570 WIN_UpdateWndPtr(&tmp,tmp->next);
571 }
572 WIN_ReleaseWndPtr(tmp2);
Alexandre Julliard77b99181997-09-14 17:17:23 +0000573 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000574 WIN_ReleaseWndPtr(tmp);
Alexandre Julliard77b99181997-09-14 17:17:23 +0000575 if (!ret) break;
576 }
577 }
578 return ret;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000579}
580
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000581/***********************************************************************
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000582 * WIN_CreateDesktopWindow
583 *
584 * Create the desktop window.
585 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000586BOOL WIN_CreateDesktopWindow(void)
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000587{
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000588 CLASS *class;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000589 HWND hwndDesktop;
Patrik Stridvall8d8703c1999-02-04 14:05:38 +0000590 DESKTOP *pDesktop;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000591
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000592 TRACE("Creating desktop window\n");
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000593
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000594
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000595 if (!ICONTITLE_Init() ||
596 !WINPOS_CreateInternalPosAtom() ||
597 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000598 return FALSE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000599
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000600 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000601 if (!hwndDesktop) return FALSE;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000602 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000603
Patrik Stridvall8d8703c1999-02-04 14:05:38 +0000604 pDesktop = (DESKTOP *) pWndDesktop->wExtra;
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +0000605 pDesktop->pDriver = DESKTOP_Driver;
606 pWndDesktop->pDriver = WND_Driver;
Patrik Stridvall8d8703c1999-02-04 14:05:38 +0000607
608 pDesktop->pDriver->pInitialize(pDesktop);
Patrik Stridvall151170c1998-12-26 12:00:43 +0000609 pWndDesktop->pDriver->pInitialize(pWndDesktop);
610
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000611 pWndDesktop->next = NULL;
612 pWndDesktop->child = NULL;
613 pWndDesktop->parent = NULL;
614 pWndDesktop->owner = NULL;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000615 pWndDesktop->class = class;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000616 pWndDesktop->dwMagic = WND_MAGIC;
617 pWndDesktop->hwndSelf = hwndDesktop;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000618 pWndDesktop->hInstance = 0;
619 pWndDesktop->rectWindow.left = 0;
620 pWndDesktop->rectWindow.top = 0;
Marcus Meissnerddca3151999-05-22 11:33:23 +0000621 pWndDesktop->rectWindow.right = GetSystemMetrics(SM_CXSCREEN);
622 pWndDesktop->rectWindow.bottom = GetSystemMetrics(SM_CYSCREEN);
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000623 pWndDesktop->rectClient = pWndDesktop->rectWindow;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000624 pWndDesktop->text = NULL;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000625 pWndDesktop->hmemTaskQ = GetFastQueue16();
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000626 pWndDesktop->hrgnUpdate = 0;
627 pWndDesktop->hwndLastActive = hwndDesktop;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000628 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
629 WS_CLIPSIBLINGS;
630 pWndDesktop->dwExStyle = 0;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000631 pWndDesktop->dce = NULL;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000632 pWndDesktop->pVScroll = NULL;
633 pWndDesktop->pHScroll = NULL;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000634 pWndDesktop->pProp = NULL;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000635 pWndDesktop->wIDmenu = 0;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000636 pWndDesktop->helpContext = 0;
Alex Korobka98447491999-05-08 17:57:09 +0000637 pWndDesktop->flags = Options.desktopGeometry ? WIN_NATIVE : 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000638 pWndDesktop->hSysMenu = 0;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000639 pWndDesktop->userdata = 0;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000640 pWndDesktop->winproc = (WNDPROC16)class->winproc;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000641 pWndDesktop->irefCount = 0;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000642
Patrik Stridvalle35d6361998-12-07 09:13:40 +0000643 /* FIXME: How do we know if it should be Unicode or not */
644 if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop, class, FALSE))
645 return FALSE;
646
Alexandre Julliarda3960291999-02-26 11:11:13 +0000647 SendMessageA( hwndDesktop, WM_NCCREATE, 0, 0 );
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000648 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000649 return TRUE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000650}
651
652
653/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000654 * WIN_CreateWindowEx
655 *
656 * Implementation of CreateWindowEx().
Alexandre Julliard401710d1993-09-04 10:09:32 +0000657 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000658static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
659 BOOL win32, BOOL unicode )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000660{
Slava Monicha27807d1999-06-05 11:46:35 +0000661 INT sw = SW_SHOW;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000662 CLASS *classPtr;
Alexandre Julliardd2e1c1a1996-03-09 16:12:43 +0000663 WND *wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000664 HWND retvalue;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000665 HWND16 hwnd, hwndLinkAfter;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000666 POINT maxSize, maxPos, minTrack, maxTrack;
667 LRESULT (CALLBACK *localSend32)(HWND, UINT, WPARAM, LPARAM);
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000668
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000669 TRACE("%s %s %08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000670 unicode ? debugres_w((LPWSTR)cs->lpszName) : debugres_a(cs->lpszName),
671 unicode ? debugres_w((LPWSTR)cs->lpszClass) : debugres_a(cs->lpszClass),
672 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
673 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000674
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000675 /* Find the parent window */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000676
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000677 if (cs->hwndParent)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000678 {
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000679 /* Make sure parent is valid */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000680 if (!IsWindow( cs->hwndParent ))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000681 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000682 WARN("Bad parent %04x\n", cs->hwndParent );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000683 return 0;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000684 }
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000685 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000686 WARN("No parent for child window\n" );
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000687 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000688 }
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000689
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000690 /* Find the window class */
Alexandre Julliard77b99181997-09-14 17:17:23 +0000691 if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
Alexandre Julliard808cb041995-08-17 17:11:36 +0000692 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +0000693 WARN("Bad class '%s'\n", cs->lpszClass );
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000694 return 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000695 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000696
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000697 /* Fix the coordinates */
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000698
Slava Monicha27807d1999-06-05 11:46:35 +0000699 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000700 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000701 PDB *pdb = PROCESS_Current();
Slava Monicha27807d1999-06-05 11:46:35 +0000702
703 /* Never believe Microsoft's documentation... CreateWindowEx doc says
704 * that if an overlapped window is created with WS_VISIBLE style bit
705 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
706 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
707 * reveals that
708 *
709 * 1) not only if checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
710 * 2) it does not ignore the y parameter as the docs claim; instead, it
711 * uses it as second parameter to ShowWindow() unless y is either
712 * CW_USEDEFAULT or CW_USEDEFAULT16.
713 *
714 * The fact that we didn't do 2) caused bogus windows pop up when wine
715 * was running apps that were using this obscure feature. Example -
716 * calc.exe that comes with Win98 (only Win98, it's different from
717 * the one that comes with Win95 and NT)
718 */
719 if (cs->y != CW_USEDEFAULT && cs->y != CW_USEDEFAULT16) sw = cs->y;
720
721 /* We have saved cs->y, now we can trash it */
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000722 if ( !(cs->style & (WS_CHILD | WS_POPUP))
723 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
724 {
725 cs->x = pdb->env_db->startup_info->dwX;
726 cs->y = pdb->env_db->startup_info->dwY;
727 }
728 else
729 {
730 cs->x = 0;
731 cs->y = 0;
732 }
733 }
Slava Monicha27807d1999-06-05 11:46:35 +0000734 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000735 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000736 PDB *pdb = PROCESS_Current();
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000737 if ( !(cs->style & (WS_CHILD | WS_POPUP))
738 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000739 {
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000740 cs->cx = pdb->env_db->startup_info->dwXSize;
741 cs->cy = pdb->env_db->startup_info->dwYSize;
742 }
743 else
744 {
745 cs->cx = 600; /* FIXME */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000746 cs->cy = 400;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000747 }
748 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000749
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000750 /* Create the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000751
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000752 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
753 - sizeof(wndPtr->wExtra) )))
754 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000755 TRACE("out of memory\n" );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000756 return 0;
757 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000758
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000759 /* Fill the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000760
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000761 wndPtr = WIN_LockWndPtr((WND *) USER_HEAP_LIN_ADDR( hwnd ));
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000762 wndPtr->next = NULL;
763 wndPtr->child = NULL;
764
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000765 if ((cs->style & WS_CHILD) && cs->hwndParent)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000766 {
767 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
768 wndPtr->owner = NULL;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000769 WIN_ReleaseWndPtr(wndPtr->parent);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000770 }
771 else
772 {
773 wndPtr->parent = pWndDesktop;
774 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
775 wndPtr->owner = NULL;
776 else
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000777 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000778 WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
779 wndPtr->owner = WIN_GetTopParentPtr(tmpWnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000780 WIN_ReleaseWndPtr(wndPtr->owner);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000781 WIN_ReleaseWndPtr(tmpWnd);
Slava Monicha27807d1999-06-05 11:46:35 +0000782 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000783 }
Slava Monicha27807d1999-06-05 11:46:35 +0000784
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000785
Patrik Stridvall151170c1998-12-26 12:00:43 +0000786 wndPtr->pDriver = wndPtr->parent->pDriver;
787 wndPtr->pDriver->pInitialize(wndPtr);
788
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000789 wndPtr->class = classPtr;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000790 wndPtr->winproc = classPtr->winproc;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000791 wndPtr->dwMagic = WND_MAGIC;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000792 wndPtr->hwndSelf = hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000793 wndPtr->hInstance = cs->hInstance;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000794 wndPtr->text = NULL;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000795 wndPtr->hmemTaskQ = GetFastQueue16();
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000796 wndPtr->hrgnUpdate = 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000797 wndPtr->hwndLastActive = hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000798 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
799 wndPtr->dwExStyle = cs->dwExStyle;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000800 wndPtr->wIDmenu = 0;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000801 wndPtr->helpContext = 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000802 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000803 wndPtr->pVScroll = NULL;
804 wndPtr->pHScroll = NULL;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000805 wndPtr->pProp = NULL;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000806 wndPtr->userdata = 0;
Alexandre Julliard7ff1c411997-05-25 13:58:18 +0000807 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
808 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000809 wndPtr->irefCount = 1;
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000810
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000811 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000812
813 /* Call the WH_CBT hook */
814
NF Stevens181fa7c1998-12-14 14:37:06 +0000815 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
816 ? HWND_BOTTOM : HWND_TOP;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000817
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000818 if (HOOK_IsHooked( WH_CBT ))
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000819 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000820 CBT_CREATEWNDA cbtc;
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000821 LRESULT ret;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000822
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000823 cbtc.lpcs = cs;
824 cbtc.hwndInsertAfter = hwndLinkAfter;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000825 ret = unicode ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc)
826 : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc);
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000827 if (ret)
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000828 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000829 TRACE("CBT-hook returned 0\n");
Patrik Stridvall151170c1998-12-26 12:00:43 +0000830 wndPtr->pDriver->pFinalize(wndPtr);
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000831 USER_HEAP_FREE( hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000832 retvalue = 0;
833 goto end;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000834 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000835 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000836
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000837 /* Increment class window counter */
Alexandre Julliard3051b641996-07-05 17:14:13 +0000838
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000839 classPtr->cWindows++;
Alexandre Julliard3051b641996-07-05 17:14:13 +0000840
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000841 /* Correct the window style */
842
Alex Korobka44a1b591999-04-01 12:03:52 +0000843 if (!(cs->style & WS_CHILD))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000844 {
Alex Korobka44a1b591999-04-01 12:03:52 +0000845 wndPtr->dwStyle |= WS_CLIPSIBLINGS;
846 if (!(cs->style & WS_POPUP))
847 {
848 wndPtr->dwStyle |= WS_CAPTION;
849 wndPtr->flags |= WIN_NEED_SIZE;
850 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000851 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000852
853 /* Get class or window DC if needed */
Alexandre Julliardaca05781994-10-17 18:12:41 +0000854
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000855 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
856 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
857 else wndPtr->dce = NULL;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000858
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000859 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
Alexandre Julliard988ca971994-06-21 16:15:21 +0000860
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000861 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000862 {
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000863 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000864 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
865 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000866 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
867 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000868 }
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000869
870 if(cs->style & WS_CHILD)
871 {
872 if(cs->cx < 0) cs->cx = 0;
873 if(cs->cy < 0) cs->cy = 0;
874 }
875 else
876 {
877 if (cs->cx <= 0) cs->cx = 1;
878 if (cs->cy <= 0) cs->cy = 1;
879 }
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000880
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000881 wndPtr->rectWindow.left = cs->x;
882 wndPtr->rectWindow.top = cs->y;
883 wndPtr->rectWindow.right = cs->x + cs->cx;
884 wndPtr->rectWindow.bottom = cs->y + cs->cy;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000885 wndPtr->rectClient = wndPtr->rectWindow;
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000886
Patrik Stridvalle35d6361998-12-07 09:13:40 +0000887 if(!wndPtr->pDriver->pCreateWindow(wndPtr, classPtr, cs, unicode))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000888 {
889 retvalue = FALSE;
890 goto end;
891 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000892
893 /* Set the window menu */
894
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000895 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000896 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000897 if (cs->hMenu) SetMenu(hwnd, cs->hMenu);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000898 else
899 {
900#if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
901 if (classPtr->menuNameA)
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000902 cs->hMenu = HIWORD(classPtr->menuNameA) ?
903 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
904 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000905#else
Alexandre Julliard77b99181997-09-14 17:17:23 +0000906 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
Alexandre Julliard54c27111998-03-29 19:44:57 +0000907 if (menuName)
908 {
Ulrich Weigand7df1fbb1998-11-01 18:01:53 +0000909 if (HIWORD(cs->hInstance))
Alexandre Julliarda3960291999-02-26 11:11:13 +0000910 cs->hMenu = LoadMenuA(cs->hInstance,PTR_SEG_TO_LIN(menuName));
Alexandre Julliard54c27111998-03-29 19:44:57 +0000911 else
Alexandre Julliard54c27111998-03-29 19:44:57 +0000912 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
913
Alexandre Julliarda3960291999-02-26 11:11:13 +0000914 if (cs->hMenu) SetMenu( hwnd, cs->hMenu );
Alexandre Julliard54c27111998-03-29 19:44:57 +0000915 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000916#endif
917 }
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000918 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000919 else wndPtr->wIDmenu = (UINT)cs->hMenu;
Alexandre Julliard490a27e1994-06-08 13:57:50 +0000920
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000921 /* Send the WM_CREATE message
922 * Perhaps we shouldn't allow width/height changes as well.
923 * See p327 in "Internals".
924 */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000925
Alexandre Julliardda0cfb31996-12-01 17:17:47 +0000926 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000927
Alexandre Julliarda3960291999-02-26 11:11:13 +0000928 localSend32 = unicode ? SendMessageW : SendMessageA;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000929 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000930 {
Rein Klazesbf1bc511998-10-31 12:09:32 +0000931 /* Insert the window in the linked list */
932
933 WIN_LinkWindow( hwnd, hwndLinkAfter );
934
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000935 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
936 NULL, NULL, 0, &wndPtr->rectClient );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000937 OffsetRect(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000938 maxPos.y - wndPtr->rectWindow.top);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000939 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
940 {
941 /* Send the size messages */
942
943 if (!(wndPtr->flags & WIN_NEED_SIZE))
944 {
945 /* send it anyway */
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000946 if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
947 ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000948 WARN("sending bogus WM_SIZE message 0x%08lx\n",
Alexandre Julliard46ea8b31998-05-03 19:01:20 +0000949 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
950 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
Alexandre Julliarda3960291999-02-26 11:11:13 +0000951 SendMessageA( hwnd, WM_SIZE, SIZE_RESTORED,
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000952 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
953 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
Alexandre Julliarda3960291999-02-26 11:11:13 +0000954 SendMessageA( hwnd, WM_MOVE, 0,
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000955 MAKELONG( wndPtr->rectClient.left,
956 wndPtr->rectClient.top ) );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000957 }
958
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000959 /* Show the window, maximizing or minimizing if needed */
960
Alexandre Julliard77b99181997-09-14 17:17:23 +0000961 if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000962 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000963 RECT16 newPos;
Alexandre Julliard77b99181997-09-14 17:17:23 +0000964 UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000965 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
Alexandre Julliard77b99181997-09-14 17:17:23 +0000966 WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000967 swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow())
NF Stevens181fa7c1998-12-14 14:37:06 +0000968 ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
969 : SWP_NOZORDER | SWP_FRAMECHANGED;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000970 SetWindowPos( hwnd, 0, newPos.left, newPos.top,
NF Stevens181fa7c1998-12-14 14:37:06 +0000971 newPos.right, newPos.bottom, swFlag );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000972 }
Alexandre Julliard77b99181997-09-14 17:17:23 +0000973
974 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
975 {
976 /* Notify the parent window only */
977
Alexandre Julliarda3960291999-02-26 11:11:13 +0000978 SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
Alexandre Julliard77b99181997-09-14 17:17:23 +0000979 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000980 if( !IsWindow(hwnd) )
981 {
982 retvalue = 0;
983 goto end;
984 }
Alexandre Julliard77b99181997-09-14 17:17:23 +0000985 }
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000986
Slava Monicha27807d1999-06-05 11:46:35 +0000987 if (cs->style & WS_VISIBLE) ShowWindow( hwnd, sw );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000988
989 /* Call WH_SHELL hook */
990
991 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
992 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
993
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000994 TRACE("created window %04x\n", hwnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000995 retvalue = hwnd;
996 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000997 }
Rein Klazesbf1bc511998-10-31 12:09:32 +0000998 WIN_UnlinkWindow( hwnd );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000999 }
Alexandre Julliard401710d1993-09-04 10:09:32 +00001000
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001001 /* Abort window creation */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001002
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001003 WARN("aborted by WM_xxCREATE!\n");
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001004 WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001005 retvalue = 0;
1006end:
1007 WIN_ReleaseWndPtr(wndPtr);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001008
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001009 return retvalue;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001010}
1011
1012
1013/***********************************************************************
1014 * CreateWindow16 (USER.41)
1015 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001016HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
1017 DWORD style, INT16 x, INT16 y, INT16 width,
1018 INT16 height, HWND16 parent, HMENU16 menu,
1019 HINSTANCE16 instance, LPVOID data )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001020{
1021 return CreateWindowEx16( 0, className, windowName, style,
1022 x, y, width, height, parent, menu, instance, data );
1023}
1024
1025
1026/***********************************************************************
1027 * CreateWindowEx16 (USER.452)
1028 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001029HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
1030 LPCSTR windowName, DWORD style, INT16 x,
1031 INT16 y, INT16 width, INT16 height,
1032 HWND16 parent, HMENU16 menu,
1033 HINSTANCE16 instance, LPVOID data )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001034{
1035 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001036 CREATESTRUCTA cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001037 char buffer[256];
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001038
1039 /* Find the class atom */
1040
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001041 if (HIWORD(className))
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001042 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001043 if (!(classAtom = GlobalFindAtomA( className )))
1044 {
1045 ERR( "bad class name %s\n", debugres_a(className) );
1046 return 0;
1047 }
1048 }
1049 else
1050 {
1051 classAtom = LOWORD(className);
1052 if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
1053 {
1054 ERR( "bad atom %x\n", classAtom);
1055 return 0;
1056 }
1057 className = buffer;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001058 }
1059
1060 /* Fix the coordinates */
1061
Alexandre Julliarda3960291999-02-26 11:11:13 +00001062 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)x;
1063 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)y;
1064 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)width;
1065 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)height;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001066
1067 /* Create the window */
1068
1069 cs.lpCreateParams = data;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001070 cs.hInstance = (HINSTANCE)instance;
1071 cs.hMenu = (HMENU)menu;
1072 cs.hwndParent = (HWND)parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001073 cs.style = style;
1074 cs.lpszName = windowName;
1075 cs.lpszClass = className;
1076 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001077
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001078 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001079}
1080
1081
1082/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001083 * CreateWindowEx32A (USER32.83)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001084 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001085HWND WINAPI CreateWindowExA( DWORD exStyle, LPCSTR className,
1086 LPCSTR windowName, DWORD style, INT x,
1087 INT y, INT width, INT height,
1088 HWND parent, HMENU menu,
1089 HINSTANCE instance, LPVOID data )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001090{
1091 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001092 CREATESTRUCTA cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001093 char buffer[256];
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001094
Rein Klazesd4a2cee1999-10-23 13:57:36 +00001095 if(!instance)
1096 instance=GetModuleHandleA(NULL);
1097
Rein Klazes5c6fc1b1998-11-01 14:50:06 +00001098 if(exStyle & WS_EX_MDICHILD)
Alexandre Julliarda3960291999-02-26 11:11:13 +00001099 return MDI_CreateMDIWindowA(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001100
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001101 /* Find the class atom */
1102
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001103 if (HIWORD(className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001104 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001105 if (!(classAtom = GlobalFindAtomA( className )))
1106 {
1107 ERR( "bad class name %s\n", debugres_a(className) );
1108 return 0;
1109 }
1110 }
1111 else
1112 {
1113 classAtom = LOWORD(className);
1114 if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
1115 {
1116 ERR( "bad atom %x\n", classAtom);
1117 return 0;
1118 }
1119 className = buffer;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001120 }
1121
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001122 /* Create the window */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001123
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001124 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001125 cs.hInstance = instance;
1126 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001127 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001128 cs.x = x;
1129 cs.y = y;
1130 cs.cx = width;
1131 cs.cy = height;
1132 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001133 cs.lpszName = windowName;
1134 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001135 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001136
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001137 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001138}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001139
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001140
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001141/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001142 * CreateWindowEx32W (USER32.84)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001143 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001144HWND WINAPI CreateWindowExW( DWORD exStyle, LPCWSTR className,
1145 LPCWSTR windowName, DWORD style, INT x,
1146 INT y, INT width, INT height,
1147 HWND parent, HMENU menu,
1148 HINSTANCE instance, LPVOID data )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001149{
1150 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001151 CREATESTRUCTW cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001152 WCHAR buffer[256];
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001153
Rein Klazesd4a2cee1999-10-23 13:57:36 +00001154 if(!instance)
1155 instance=GetModuleHandleA(NULL);
1156
Rein Klazes5c6fc1b1998-11-01 14:50:06 +00001157 if(exStyle & WS_EX_MDICHILD)
Alexandre Julliarda3960291999-02-26 11:11:13 +00001158 return MDI_CreateMDIWindowW(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
Rein Klazes5c6fc1b1998-11-01 14:50:06 +00001159
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001160 /* Find the class atom */
1161
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001162 if (HIWORD(className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001163 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001164 if (!(classAtom = GlobalFindAtomW( className )))
1165 {
1166 ERR( "bad class name %s\n", debugres_w(className) );
1167 return 0;
1168 }
1169 }
1170 else
1171 {
1172 classAtom = LOWORD(className);
1173 if (!GlobalGetAtomNameW( classAtom, buffer, sizeof(buffer)/sizeof(WCHAR) ))
1174 {
1175 ERR( "bad atom %x\n", classAtom);
1176 return 0;
1177 }
1178 className = buffer;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001179 }
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001180
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001181 /* Create the window */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001182
1183 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001184 cs.hInstance = instance;
1185 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001186 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001187 cs.x = x;
1188 cs.y = y;
1189 cs.cx = width;
1190 cs.cy = height;
1191 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001192 cs.lpszName = windowName;
1193 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001194 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001195
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001196 /* Note: we rely on the fact that CREATESTRUCT32A and */
1197 /* CREATESTRUCT32W have the same layout. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001198 return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, classAtom, TRUE, TRUE );
Alexandre Julliard401710d1993-09-04 10:09:32 +00001199}
1200
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001201
Alexandre Julliard401710d1993-09-04 10:09:32 +00001202/***********************************************************************
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001203 * WIN_CheckFocus
1204 */
1205static void WIN_CheckFocus( WND* pWnd )
1206{
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001207 if( GetFocus16() == pWnd->hwndSelf )
1208 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001209}
1210
1211/***********************************************************************
1212 * WIN_SendDestroyMsg
1213 */
1214static void WIN_SendDestroyMsg( WND* pWnd )
1215{
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001216 WIN_CheckFocus(pWnd);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001217
Alexandre Julliarda3960291999-02-26 11:11:13 +00001218 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret();
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +00001219 CLIPBOARD_Driver->pResetOwner( pWnd, TRUE );
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001220
1221 /*
1222 * Send the WM_DESTROY to the window.
1223 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001224 SendMessageA( pWnd->hwndSelf, WM_DESTROY, 0, 0);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001225
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001226 /*
1227 * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
1228 * make sure that the window still exists when we come back.
1229 */
1230 if (IsWindow(pWnd->hwndSelf))
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001231 {
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001232 HWND* pWndArray = NULL;
1233 WND* pChild = NULL;
1234 int nKidCount = 0;
1235
1236 /*
1237 * Now, if the window has kids, we have to send WM_DESTROY messages
1238 * recursively to it's kids. It seems that those calls can also
1239 * trigger re-entrant calls to DestroyWindow for the kids so we must
1240 * protect against corruption of the list of siblings. We first build
1241 * a list of HWNDs representing all the kids.
1242 */
1243 pChild = WIN_LockWndPtr(pWnd->child);
1244 while( pChild )
1245 {
1246 nKidCount++;
1247 WIN_UpdateWndPtr(&pChild,pChild->next);
1248 }
1249
1250 /*
1251 * If there are no kids, we're done.
1252 */
1253 if (nKidCount==0)
1254 return;
1255
1256 pWndArray = HeapAlloc(GetProcessHeap(), 0, nKidCount*sizeof(HWND));
1257
1258 /*
1259 * Sanity check
1260 */
1261 if (pWndArray==NULL)
1262 return;
1263
1264 /*
1265 * Now, enumerate all the kids in a list, since we wait to make the SendMessage
1266 * call, our linked list of siblings should be safe.
1267 */
1268 nKidCount = 0;
1269 pChild = WIN_LockWndPtr(pWnd->child);
1270 while( pChild )
1271 {
1272 pWndArray[nKidCount] = pChild->hwndSelf;
1273 nKidCount++;
1274 WIN_UpdateWndPtr(&pChild,pChild->next);
1275 }
1276
1277 /*
1278 * Now that we have a list, go through that list again and send the destroy
1279 * message to those windows. We are using the HWND to retrieve the
1280 * WND pointer so we are effectively checking that all the kid windows are
1281 * still valid before sending the message.
1282 */
1283 while (nKidCount>0)
1284 {
Pavel Roskinc5012071999-03-19 16:59:18 +00001285 pChild = WIN_FindWndPtr(pWndArray[--nKidCount]);
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001286
1287 if (pChild!=NULL)
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001288 {
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001289 WIN_SendDestroyMsg( pChild );
1290 WIN_ReleaseWndPtr(pChild);
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001291 }
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001292 }
1293
1294 /*
1295 * Cleanup
1296 */
1297 HeapFree(GetProcessHeap(), 0, pWndArray);
1298 WIN_CheckFocus(pWnd);
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001299 }
1300 else
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001301 WARN("\tdestroyed itself while in WM_DESTROY!\n");
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001302}
1303
1304
1305/***********************************************************************
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001306 * DestroyWindow16 (USER.53)
Alexandre Julliard401710d1993-09-04 10:09:32 +00001307 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001308BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00001309{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001310 return DestroyWindow(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00001311}
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001312
1313
Alexandre Julliard01d63461997-01-20 19:43:45 +00001314/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001315 * DestroyWindow32 (USER32.135)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001316 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001317BOOL WINAPI DestroyWindow( HWND hwnd )
Alexandre Julliard401710d1993-09-04 10:09:32 +00001318{
Alexandre Julliard0e607781993-11-03 19:23:37 +00001319 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001320 BOOL retvalue;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00001321
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001322 TRACE("(%04x)\n", hwnd);
Alexandre Julliard401710d1993-09-04 10:09:32 +00001323
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001324 /* Initialization */
Alexandre Julliard401710d1993-09-04 10:09:32 +00001325
Alexandre Julliard0e607781993-11-03 19:23:37 +00001326 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001327 if (wndPtr == pWndDesktop)
1328 {
1329 WIN_ReleaseWndPtr(wndPtr);
1330 return FALSE; /* Can't destroy desktop */
1331 }
Alexandre Julliard58199531994-04-21 01:20:00 +00001332
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001333 /* Call hooks */
1334
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +00001335 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001336 {
1337 retvalue = FALSE;
1338 goto end;
1339 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001340
1341 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1342 {
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +00001343 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001344 /* FIXME: clean up palette - see "Internals" p.352 */
1345 }
1346
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001347 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
Alexandre Julliard77b99181997-09-14 17:17:23 +00001348 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
1349 {
1350 /* Notify the parent window only */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001351 SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
Alexandre Julliard77b99181997-09-14 17:17:23 +00001352 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001353 if( !IsWindow(hwnd) )
1354 {
1355 retvalue = TRUE;
1356 goto end;
1357 }
Alexandre Julliard77b99181997-09-14 17:17:23 +00001358 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001359
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +00001360 CLIPBOARD_Driver->pResetOwner( wndPtr, FALSE ); /* before the window is unmapped */
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001361
Alexandre Julliard58199531994-04-21 01:20:00 +00001362 /* Hide the window */
1363
1364 if (wndPtr->dwStyle & WS_VISIBLE)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001365 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001366 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
Alexandre Julliard01d63461997-01-20 19:43:45 +00001367 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001368 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001369 if (!IsWindow(hwnd))
1370 {
1371 retvalue = TRUE;
1372 goto end;
1373 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001374 }
Alexandre Julliard0e607781993-11-03 19:23:37 +00001375
Alexandre Julliard22945d51995-03-02 17:44:29 +00001376 /* Recursively destroy owned windows */
1377
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001378 if( !(wndPtr->dwStyle & WS_CHILD) )
Alexandre Julliard22945d51995-03-02 17:44:29 +00001379 {
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001380 /* make sure top menu popup doesn't get destroyed */
Alexandre Julliard77b99181997-09-14 17:17:23 +00001381 MENU_PatchResidentPopup( (HQUEUE16)0xFFFF, wndPtr );
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001382
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001383 for (;;)
1384 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001385 WND *siblingPtr = WIN_LockWndPtr(wndPtr->parent->child); /* First sibling */
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001386 while (siblingPtr)
Alexandre Julliard22945d51995-03-02 17:44:29 +00001387 {
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001388 if (siblingPtr->owner == wndPtr)
Patrik Stridvallea584721998-11-01 16:22:07 +00001389 {
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001390 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1391 break;
1392 else
1393 siblingPtr->owner = NULL;
Patrik Stridvallea584721998-11-01 16:22:07 +00001394 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001395 WIN_UpdateWndPtr(&siblingPtr,siblingPtr->next);
Alexandre Julliard22945d51995-03-02 17:44:29 +00001396 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001397 if (siblingPtr)
1398 {
1399 DestroyWindow( siblingPtr->hwndSelf );
1400 WIN_ReleaseWndPtr(siblingPtr);
1401 }
Alexandre Julliard22945d51995-03-02 17:44:29 +00001402 else break;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001403 }
1404
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001405 if( !Options.managed || EVENT_CheckFocus() )
1406 WINPOS_ActivateOtherWindow(wndPtr);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001407
1408 if( wndPtr->owner &&
1409 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1410 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
Alexandre Julliard22945d51995-03-02 17:44:29 +00001411 }
1412
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001413 /* Send destroy messages */
Alexandre Julliard0e607781993-11-03 19:23:37 +00001414
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001415 WIN_SendDestroyMsg( wndPtr );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001416 if (!IsWindow(hwnd))
1417 {
1418 retvalue = TRUE;
1419 goto end;
1420 }
Alexandre Julliard401710d1993-09-04 10:09:32 +00001421
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001422 /* Unlink now so we won't bother with the children later on */
Alexandre Julliard401710d1993-09-04 10:09:32 +00001423
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001424 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1425
1426 /* Destroy the window storage */
1427
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001428 WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001429 retvalue = TRUE;
1430end:
1431 WIN_ReleaseWndPtr(wndPtr);
1432 return retvalue;
Alexandre Julliard401710d1993-09-04 10:09:32 +00001433}
1434
1435
1436/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001437 * CloseWindow16 (USER.43)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001438 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001439BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001440{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001441 return CloseWindow( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001442}
1443
1444
1445/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001446 * CloseWindow32 (USER32.56)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001447 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001448BOOL WINAPI CloseWindow( HWND hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001449{
1450 WND * wndPtr = WIN_FindWndPtr( hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001451 BOOL retvalue;
1452
1453 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD))
1454 {
1455 retvalue = FALSE;
1456 goto end;
1457 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00001458 ShowWindow( hwnd, SW_MINIMIZE );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001459 retvalue = TRUE;
1460end:
1461 WIN_ReleaseWndPtr(wndPtr);
1462 return retvalue;
1463
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001464}
1465
1466
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001467/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001468 * OpenIcon16 (USER.44)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001469 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001470BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001471{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001472 return OpenIcon( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001473}
1474
1475
1476/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001477 * OpenIcon32 (USER32.410)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001478 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001479BOOL WINAPI OpenIcon( HWND hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001480{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001481 if (!IsIconic( hwnd )) return FALSE;
1482 ShowWindow( hwnd, SW_SHOWNORMAL );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001483 return TRUE;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001484}
1485
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001486
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001487/***********************************************************************
1488 * WIN_FindWindow
1489 *
1490 * Implementation of FindWindow() and FindWindowEx().
1491 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001492static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className,
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001493 LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001494{
1495 WND *pWnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001496 HWND retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001497 CLASS *pClass = NULL;
1498
1499 if (child)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001500 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001501 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1502 if (parent)
1503 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001504 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent))
1505 {
1506 retvalue = 0;
1507 goto end;
1508 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001509 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001510 else if (pWnd->parent != pWndDesktop)
1511 {
1512 retvalue = 0;
1513 goto end;
1514 }
1515 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001516 }
1517 else
1518 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001519 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : WIN_LockWndPtr(pWndDesktop)))
1520 {
1521 retvalue = 0;
1522 goto end;
1523 }
1524 WIN_UpdateWndPtr(&pWnd,pWnd->child);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001525 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001526 if (!pWnd)
1527 {
1528 retvalue = 0;
1529 goto end;
1530 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001531
1532 /* For a child window, all siblings will have the same hInstance, */
1533 /* so we can look for the class once and for all. */
1534
1535 if (className && (pWnd->dwStyle & WS_CHILD))
1536 {
1537 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001538 {
1539 retvalue = 0;
1540 goto end;
1541 }
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001542 }
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001543
Alexandre Julliard44ed71f1997-12-21 19:17:50 +00001544
Pavel Roskin598993f1999-03-16 09:53:10 +00001545 for ( ; pWnd ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001546 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001547 if (className && !(pWnd->dwStyle & WS_CHILD))
1548 {
Uwe Bonnesa2b938c1999-07-04 12:52:14 +00001549 if (!((pClass = CLASS_FindClassByAtom( className, pWnd->hInstance))
1550 ||(pClass = CLASS_FindClassByAtom( className, GetExePtr(pWnd->hInstance))))
1551 )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001552 continue; /* Skip this window */
1553 }
Alexandre Julliard44ed71f1997-12-21 19:17:50 +00001554
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001555 if (pClass && (pWnd->class != pClass))
1556 continue; /* Not the right class */
1557
1558 /* Now check the title */
1559
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001560 if (!title)
1561 {
1562 retvalue = pWnd->hwndSelf;
1563 goto end;
Pavel Roskin598993f1999-03-16 09:53:10 +00001564 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001565 if (pWnd->text && !strcmp( pWnd->text, title ))
1566 {
1567 retvalue = pWnd->hwndSelf;
1568 goto end;
Pavel Roskin598993f1999-03-16 09:53:10 +00001569 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001570 }
1571 retvalue = 0;
1572end:
1573 WIN_ReleaseWndPtr(pWnd);
1574 return retvalue;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001575}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001576
1577
1578
1579/***********************************************************************
1580 * FindWindow16 (USER.50)
1581 */
Alexandre Julliardb849d792000-02-13 13:56:13 +00001582HWND16 WINAPI FindWindow16( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001583{
Alexandre Julliardb849d792000-02-13 13:56:13 +00001584 return FindWindowA( className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001585}
1586
1587
1588/***********************************************************************
1589 * FindWindowEx16 (USER.427)
1590 */
Alexandre Julliardb849d792000-02-13 13:56:13 +00001591HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child, LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001592{
Alexandre Julliardb849d792000-02-13 13:56:13 +00001593 return FindWindowExA( parent, child, className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001594}
1595
1596
1597/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001598 * FindWindow32A (USER32.198)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001599 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001600HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001601{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001602 HWND ret = FindWindowExA( 0, 0, className, title );
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001603 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1604 return ret;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001605}
1606
1607
1608/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001609 * FindWindowEx32A (USER32.199)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001610 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001611HWND WINAPI FindWindowExA( HWND parent, HWND child,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001612 LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001613{
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001614 ATOM atom = 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001615
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001616 if (className)
1617 {
1618 /* If the atom doesn't exist, then no class */
1619 /* with this name exists either. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001620 if (!(atom = GlobalFindAtomA( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001621 {
1622 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1623 return 0;
1624 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001625 }
Alexandre Julliard77b99181997-09-14 17:17:23 +00001626 return WIN_FindWindow( parent, child, atom, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001627}
1628
1629
1630/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001631 * FindWindowEx32W (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 char *buffer;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001638 HWND hwnd;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001639
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001640 if (className)
1641 {
1642 /* If the atom doesn't exist, then no class */
1643 /* with this name exists either. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001644 if (!(atom = GlobalFindAtomW( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001645 {
1646 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1647 return 0;
1648 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001649 }
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001650 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
Alexandre Julliard77b99181997-09-14 17:17:23 +00001651 hwnd = WIN_FindWindow( parent, child, atom, buffer );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001652 HeapFree( GetProcessHeap(), 0, buffer );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001653 return hwnd;
1654}
1655
1656
1657/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001658 * FindWindow32W (USER32.201)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001659 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001660HWND WINAPI FindWindowW( LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001661{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001662 return FindWindowExW( 0, 0, className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001663}
1664
1665
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001666/**********************************************************************
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001667 * WIN_GetDesktop
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001668 * returns a locked pointer
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001669 */
1670WND *WIN_GetDesktop(void)
1671{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001672 return WIN_LockWndPtr(pWndDesktop);
1673}
1674/**********************************************************************
1675 * WIN_ReleaseDesktop
1676 * unlock the desktop pointer
1677 */
1678void WIN_ReleaseDesktop(void)
1679{
1680 WIN_ReleaseWndPtr(pWndDesktop);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001681}
1682
1683
1684/**********************************************************************
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001685 * GetDesktopWindow16 (USER.286)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001686 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001687HWND16 WINAPI GetDesktopWindow16(void)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001688{
1689 return (HWND16)pWndDesktop->hwndSelf;
1690}
1691
1692
1693/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001694 * GetDesktopWindow32 (USER32.232)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001695 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001696HWND WINAPI GetDesktopWindow(void)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001697{
Uwe Bonnes73619161999-10-24 20:42:39 +00001698 if (pWndDesktop) return pWndDesktop->hwndSelf;
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001699 ERR( "You need the -desktop option when running with native USER\n" );
Uwe Bonnes73619161999-10-24 20:42:39 +00001700 ExitProcess(1);
Huw D M Davies238b6d71999-10-31 01:56:51 +00001701 return 0;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001702}
1703
1704
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001705/**********************************************************************
1706 * GetDesktopHwnd (USER.278)
1707 *
1708 * Exactly the same thing as GetDesktopWindow(), but not documented.
1709 * Don't ask me why...
1710 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001711HWND16 WINAPI GetDesktopHwnd16(void)
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001712{
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001713 return (HWND16)pWndDesktop->hwndSelf;
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001714}
1715
1716
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001717/*******************************************************************
Alexandre Julliard01d63461997-01-20 19:43:45 +00001718 * EnableWindow16 (USER.34)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001719 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001720BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
Alexandre Julliard01d63461997-01-20 19:43:45 +00001721{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001722 return EnableWindow( hwnd, enable );
Alexandre Julliard01d63461997-01-20 19:43:45 +00001723}
1724
1725
1726/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001727 * EnableWindow32 (USER32.172)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001728 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001729BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001730{
1731 WND *wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001732 BOOL retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001733
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001734 TRACE("EnableWindow32: ( %x, %d )\n", hwnd, enable);
Noel Borthwickb4278561999-02-05 10:37:53 +00001735
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001736 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1737 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1738 {
1739 /* Enable window */
1740 wndPtr->dwStyle &= ~WS_DISABLED;
Alex Korobka4f1ac051999-03-28 09:37:57 +00001741
1742 if( wndPtr->flags & WIN_NATIVE )
1743 wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ACCEPTFOCUS, TRUE );
1744
Alexandre Julliarda3960291999-02-26 11:11:13 +00001745 SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001746 retvalue = TRUE;
1747 goto end;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001748 }
1749 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1750 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00001751 SendMessageA( wndPtr->hwndSelf, WM_CANCELMODE, 0, 0);
1752
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001753 /* Disable window */
1754 wndPtr->dwStyle |= WS_DISABLED;
Alex Korobka4f1ac051999-03-28 09:37:57 +00001755
1756 if( wndPtr->flags & WIN_NATIVE )
1757 wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ACCEPTFOCUS, FALSE );
1758
Francis Beaudet21d50f81999-05-29 14:10:02 +00001759 if (hwnd == GetFocus())
Noel Borthwickb4278561999-02-05 10:37:53 +00001760 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001761 SetFocus( 0 ); /* A disabled window can't have the focus */
Noel Borthwickb4278561999-02-05 10:37:53 +00001762 }
Pascal Lessard31c58541999-06-26 10:17:10 +00001763 if (hwnd == GetCapture())
Noel Borthwickb4278561999-02-05 10:37:53 +00001764 {
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001765 ReleaseCapture(); /* A disabled window can't capture the mouse */
Noel Borthwickb4278561999-02-05 10:37:53 +00001766 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00001767 SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001768 retvalue = FALSE;
1769 goto end;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001770 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001771 retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);
1772end:
1773 WIN_ReleaseWndPtr(wndPtr);
1774 return retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001775}
1776
1777
1778/***********************************************************************
Alexandre Julliard01d63461997-01-20 19:43:45 +00001779 * IsWindowEnabled16 (USER.35)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001780 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001781BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001782{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001783 return IsWindowEnabled(hWnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00001784}
1785
1786
1787/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001788 * IsWindowEnabled32 (USER32.349)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001789 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001790BOOL WINAPI IsWindowEnabled(HWND hWnd)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001791{
1792 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001793 BOOL retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001794
1795 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001796 retvalue = !(wndPtr->dwStyle & WS_DISABLED);
1797 WIN_ReleaseWndPtr(wndPtr);
1798 return retvalue;
1799
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001800}
1801
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001802
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001803/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001804 * IsWindowUnicode (USER32.350)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001805 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001806BOOL WINAPI IsWindowUnicode( HWND hwnd )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001807{
1808 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001809 BOOL retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001810
1811 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001812 retvalue = (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1813 WIN_ReleaseWndPtr(wndPtr);
1814 return retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001815}
1816
1817
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001818/**********************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00001819 * GetWindowWord16 (USER.133)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001820 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001821WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
Alexandre Julliard21979011997-03-05 08:22:35 +00001822{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001823 return GetWindowWord( hwnd, offset );
Alexandre Julliard21979011997-03-05 08:22:35 +00001824}
1825
1826
1827/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001828 * GetWindowWord32 (USER32.314)
Alexandre Julliard21979011997-03-05 08:22:35 +00001829 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001830WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001831{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001832 WORD retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001833 WND * wndPtr = WIN_FindWndPtr( hwnd );
1834 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001835 if (offset >= 0)
1836 {
1837 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1838 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001839 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001840 retvalue = 0;
1841 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001842 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001843 retvalue = *(WORD *)(((char *)wndPtr->wExtra) + offset);
1844 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001845 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001846 switch(offset)
1847 {
Alexandre Julliard77b99181997-09-14 17:17:23 +00001848 case GWW_ID:
1849 if (HIWORD(wndPtr->wIDmenu))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001850 WARN("GWW_ID: discards high bits of 0x%08x!\n",
Alexandre Julliarda845b881998-06-01 10:44:35 +00001851 wndPtr->wIDmenu);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001852 retvalue = (WORD)wndPtr->wIDmenu;
1853 goto end;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001854 case GWW_HWNDPARENT:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001855 retvalue = GetParent(hwnd);
1856 goto end;
Alexandre Julliard77b99181997-09-14 17:17:23 +00001857 case GWW_HINSTANCE:
1858 if (HIWORD(wndPtr->hInstance))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001859 WARN("GWW_HINSTANCE: discards high bits of 0x%08x!\n",
Alexandre Julliarda845b881998-06-01 10:44:35 +00001860 wndPtr->hInstance);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001861 retvalue = (WORD)wndPtr->hInstance;
1862 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001863 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001864 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001865 retvalue = 0;
1866 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001867 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001868end:
1869 WIN_ReleaseWndPtr(wndPtr);
1870 return retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001871}
1872
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00001873/**********************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00001874 * SetWindowWord16 (USER.134)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001875 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001876WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
Alexandre Julliard21979011997-03-05 08:22:35 +00001877{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001878 return SetWindowWord( hwnd, offset, newval );
Alexandre Julliard21979011997-03-05 08:22:35 +00001879}
1880
1881
1882/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001883 * SetWindowWord32 (USER32.524)
Alexandre Julliard21979011997-03-05 08:22:35 +00001884 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001885WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001886{
1887 WORD *ptr, retval;
1888 WND * wndPtr = WIN_FindWndPtr( hwnd );
1889 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001890 if (offset >= 0)
1891 {
1892 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1893 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001894 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001895 retval = 0;
1896 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001897 }
1898 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1899 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001900 else switch(offset)
1901 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001902 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1903 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001904 case GWW_HWNDPARENT: retval = SetParent( hwnd, newval );
1905 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001906 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001907 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001908 retval = 0;
1909 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001910 }
1911 retval = *ptr;
1912 *ptr = newval;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001913end:
1914 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001915 return retval;
1916}
1917
1918
1919/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001920 * WIN_GetWindowLong
1921 *
1922 * Helper function for GetWindowLong().
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001923 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001924static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001925{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001926 LONG retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001927 WND * wndPtr = WIN_FindWndPtr( hwnd );
1928 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001929 if (offset >= 0)
1930 {
1931 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1932 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001933 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001934 retvalue = 0;
1935 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001936 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001937 retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
Alexandre Julliard3051b641996-07-05 17:14:13 +00001938 /* Special case for dialog window procedure */
1939 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001940 {
1941 retvalue = (LONG)WINPROC_GetProc( (HWINDOWPROC)retvalue, type );
1942 goto end;
1943 }
1944 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001945 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001946 switch(offset)
1947 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001948 case GWL_USERDATA: retvalue = wndPtr->userdata;
1949 goto end;
1950 case GWL_STYLE: retvalue = wndPtr->dwStyle;
1951 goto end;
1952 case GWL_EXSTYLE: retvalue = wndPtr->dwExStyle;
1953 goto end;
1954 case GWL_ID: retvalue = (LONG)wndPtr->wIDmenu;
1955 goto end;
1956 case GWL_WNDPROC: retvalue = (LONG)WINPROC_GetProc( wndPtr->winproc,
Alexandre Julliard3051b641996-07-05 17:14:13 +00001957 type );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001958 goto end;
1959 case GWL_HWNDPARENT: retvalue = GetParent(hwnd);
1960 goto end;
1961 case GWL_HINSTANCE: retvalue = wndPtr->hInstance;
1962 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001963 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001964 WARN("Unknown offset %d\n", offset );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001965 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001966 retvalue = 0;
1967end:
1968 WIN_ReleaseWndPtr(wndPtr);
1969 return retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001970}
1971
1972
1973/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001974 * WIN_SetWindowLong
1975 *
1976 * Helper function for SetWindowLong().
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001977 *
1978 * 0 is the failure code. However, in the case of failure SetLastError
1979 * must be set to distinguish between a 0 return value and a failure.
1980 *
1981 * FIXME: The error values for SetLastError may not be right. Can
1982 * someone check with the real thing?
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001983 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001984static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
Alexandre Julliard3051b641996-07-05 17:14:13 +00001985 WINDOWPROCTYPE type )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001986{
1987 LONG *ptr, retval;
1988 WND * wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001989 STYLESTRUCT style;
1990
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001991 TRACE("%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001992
1993 if (!wndPtr)
1994 {
1995 /* Is this the right error? */
1996 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1997 return 0;
1998 }
1999
Alexandre Julliard3051b641996-07-05 17:14:13 +00002000 if (offset >= 0)
2001 {
2002 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
2003 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002004 WARN("Invalid offset %d\n", offset );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002005
2006 /* Is this the right error? */
2007 SetLastError( ERROR_OUTOFMEMORY );
2008
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002009 retval = 0;
2010 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002011 }
2012 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
2013 /* Special case for dialog window procedure */
2014 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
2015 {
2016 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002017 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
2018 type, WIN_PROC_WINDOW );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002019 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002020 }
2021 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002022 else switch(offset)
2023 {
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002024 case GWL_ID:
2025 ptr = (DWORD*)&wndPtr->wIDmenu;
2026 break;
2027 case GWL_HINSTANCE:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002028 retval = SetWindowWord( hwnd, offset, newval );
2029 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002030 case GWL_WNDPROC:
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002031 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
2032 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002033 type, WIN_PROC_WINDOW );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002034 goto end;;
Alexandre Julliardca22b331996-07-12 19:02:39 +00002035 case GWL_STYLE:
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002036 style.styleOld = wndPtr->dwStyle;
2037 newval &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way */
2038 style.styleNew = newval | (style.styleOld & (WS_VISIBLE | WS_CHILD));
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002039
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002040 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002041 SendMessageA(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002042 wndPtr->dwStyle = style.styleNew;
2043 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002044 SendMessageA(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002045 retval = style.styleOld;
2046 goto end;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002047
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002048 case GWL_USERDATA:
2049 ptr = &wndPtr->userdata;
2050 break;
2051 case GWL_EXSTYLE:
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002052 style.styleOld = wndPtr->dwExStyle;
2053 style.styleNew = newval;
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002054 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002055 SendMessageA(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002056 wndPtr->dwExStyle = newval;
2057 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002058 SendMessageA(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002059 retval = style.styleOld;
2060 goto end;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002061
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002062 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002063 WARN("Invalid offset %d\n", offset );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002064
2065 /* Don't think this is right error but it should do */
2066 SetLastError( ERROR_OUTOFMEMORY );
2067
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002068 retval = 0;
2069 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002070 }
2071 retval = *ptr;
2072 *ptr = newval;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002073end:
2074 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002075 return retval;
2076}
2077
2078
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002079/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002080 * GetWindowLong16 (USER.135)
2081 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002082LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002083{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002084 return WIN_GetWindowLong( (HWND)hwnd, offset, WIN_PROC_16 );
Alexandre Julliard3051b641996-07-05 17:14:13 +00002085}
2086
2087
2088/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002089 * GetWindowLong32A (USER32.305)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002090 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002091LONG WINAPI GetWindowLongA( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002092{
2093 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
2094}
2095
2096
2097/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002098 * GetWindowLong32W (USER32.306)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002099 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002100LONG WINAPI GetWindowLongW( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002101{
2102 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
2103}
2104
2105
2106/**********************************************************************
2107 * SetWindowLong16 (USER.136)
2108 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002109LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002110{
2111 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
2112}
2113
2114
2115/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002116 * SetWindowLong32A (USER32.517)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002117 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002118LONG WINAPI SetWindowLongA( HWND hwnd, INT offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002119{
2120 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
2121}
2122
2123
2124/**********************************************************************
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002125 * SetWindowLong32W (USER32.518) Set window attribute
2126 *
2127 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
2128 * value in a window's extra memory.
2129 *
2130 * The _hwnd_ parameter specifies the window. is the handle to a
2131 * window that has extra memory. The _newval_ parameter contains the
2132 * new attribute or extra memory value. If positive, the _offset_
2133 * parameter is the byte-addressed location in the window's extra
2134 * memory to set. If negative, _offset_ specifies the window
2135 * attribute to set, and should be one of the following values:
2136 *
2137 * GWL_EXSTYLE The window's extended window style
2138 *
2139 * GWL_STYLE The window's window style.
2140 *
2141 * GWL_WNDPROC Pointer to the window's window procedure.
2142 *
2143 * GWL_HINSTANCE The window's pplication instance handle.
2144 *
2145 * GWL_ID The window's identifier.
2146 *
2147 * GWL_USERDATA The window's user-specified data.
2148 *
2149 * If the window is a dialog box, the _offset_ parameter can be one of
2150 * the following values:
2151 *
2152 * DWL_DLGPROC The address of the window's dialog box procedure.
2153 *
2154 * DWL_MSGRESULT The return value of a message
2155 * that the dialog box procedure processed.
2156 *
2157 * DWL_USER Application specific information.
2158 *
2159 * RETURNS
2160 *
2161 * If successful, returns the previous value located at _offset_. Otherwise,
2162 * returns 0.
2163 *
2164 * NOTES
2165 *
2166 * Extra memory for a window class is specified by a nonzero cbWndExtra
2167 * parameter of the WNDCLASS structure passed to RegisterClass() at the
2168 * time of class creation.
2169 *
2170 * Using GWL_WNDPROC to set a new window procedure effectively creates
2171 * a window subclass. Use CallWindowProc() in the new windows procedure
2172 * to pass messages to the superclass's window procedure.
2173 *
2174 * The user data is reserved for use by the application which created
2175 * the window.
2176 *
2177 * Do not use GWL_STYLE to change the window's WS_DISABLE style;
2178 * instead, call the EnableWindow() function to change the window's
2179 * disabled state.
2180 *
2181 * Do not use GWL_HWNDPARENT to reset the window's parent, use
2182 * SetParent() instead.
2183 *
Alexandre Julliard638f1691999-01-17 16:32:32 +00002184 * Win95:
2185 * When offset is GWL_STYLE and the calling app's ver is 4.0,
2186 * it sends WM_STYLECHANGING before changing the settings
2187 * and WM_STYLECHANGED afterwards.
2188 * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
2189 *
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002190 * BUGS
2191 *
Alexandre Julliard638f1691999-01-17 16:32:32 +00002192 * GWL_STYLE does not dispatch WM_STYLE... messages.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002193 *
2194 * CONFORMANCE
2195 *
2196 * ECMA-234, Win32
2197 *
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002198 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002199LONG WINAPI SetWindowLongW(
2200 HWND hwnd, /* window to alter */
2201 INT offset, /* offset, in bytes, of location to alter */
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002202 LONG newval /* new value of location */
2203) {
Alexandre Julliard3051b641996-07-05 17:14:13 +00002204 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002205}
2206
2207
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002208/*******************************************************************
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002209 * GetWindowText16 (USER.36)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002210 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002211INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002212{
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002213 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
Alexandre Julliard0e607781993-11-03 19:23:37 +00002214}
2215
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002216
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002217/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002218 * GetWindowText32A (USER32.309)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002219 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002220INT WINAPI GetWindowTextA( HWND hwnd, LPSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002221{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002222 return (INT)SendMessageA( hwnd, WM_GETTEXT, nMaxCount,
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002223 (LPARAM)lpString );
2224}
2225
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002226/*******************************************************************
2227 * InternalGetWindowText (USER32.326)
2228 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002229INT WINAPI InternalGetWindowText(HWND hwnd,LPWSTR lpString,INT nMaxCount )
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002230{
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002231 FIXME("(0x%08x,%p,0x%x),stub!\n",hwnd,lpString,nMaxCount);
Alexandre Julliarda3960291999-02-26 11:11:13 +00002232 return GetWindowTextW(hwnd,lpString,nMaxCount);
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002233}
2234
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002235
2236/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002237 * GetWindowText32W (USER32.312)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002238 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002239INT WINAPI GetWindowTextW( HWND hwnd, LPWSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002240{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002241 return (INT)SendMessageW( hwnd, WM_GETTEXT, nMaxCount,
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002242 (LPARAM)lpString );
2243}
2244
2245
2246/*******************************************************************
2247 * SetWindowText16 (USER.37)
2248 */
Paul Quinn1beaae51998-12-15 15:38:36 +00002249BOOL16 WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002250{
Paul Quinn1beaae51998-12-15 15:38:36 +00002251 return (BOOL16)SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002252}
2253
2254
2255/*******************************************************************
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002256 * SetWindowText32A (USER32.521)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002257 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002258BOOL WINAPI SetWindowTextA( HWND hwnd, LPCSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002259{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002260 return (BOOL)SendMessageA( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002261}
2262
2263
2264/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002265 * SetWindowText32W (USER32.523)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002266 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002267BOOL WINAPI SetWindowTextW( HWND hwnd, LPCWSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002268{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002269 return (BOOL)SendMessageW( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002270}
2271
2272
Alexandre Julliard0e607781993-11-03 19:23:37 +00002273/*******************************************************************
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002274 * GetWindowTextLength16 (USER.38)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002275 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002276INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002277{
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002278 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002279}
2280
2281
Alexandre Julliard0e607781993-11-03 19:23:37 +00002282/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002283 * GetWindowTextLength32A (USER32.310)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002284 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002285INT WINAPI GetWindowTextLengthA( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002286{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002287 return SendMessageA( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002288}
2289
2290/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002291 * GetWindowTextLength32W (USER32.311)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002292 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002293INT WINAPI GetWindowTextLengthW( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002294{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002295 return SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002296}
2297
Alexandre Julliard21979011997-03-05 08:22:35 +00002298
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002299/*******************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00002300 * IsWindow16 (USER.47)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002301 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002302BOOL16 WINAPI IsWindow16( HWND16 hwnd )
Alexandre Julliard21979011997-03-05 08:22:35 +00002303{
Alexandre Julliard4220b291999-07-11 17:20:01 +00002304 CURRENT_STACK16->es = USER_HeapSel;
Alexandre Julliarda3960291999-02-26 11:11:13 +00002305 return IsWindow( hwnd );
Alexandre Julliard21979011997-03-05 08:22:35 +00002306}
2307
2308
2309/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002310 * IsWindow32 (USER32.348)
Alexandre Julliard21979011997-03-05 08:22:35 +00002311 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002312BOOL WINAPI IsWindow( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002313{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002314 WND * wndPtr;
2315 BOOL retvalue;
2316
2317 if(!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
2318 retvalue = (wndPtr->dwMagic == WND_MAGIC);
2319 WIN_ReleaseWndPtr(wndPtr);
2320 return retvalue;
2321
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002322}
2323
2324
2325/*****************************************************************
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002326 * GetParent16 (USER.46)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002327 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002328HWND16 WINAPI GetParent16( HWND16 hwnd )
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002329{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002330 return (HWND16)GetParent( hwnd );
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002331}
2332
2333
2334/*****************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002335 * GetParent32 (USER32.278)
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002336 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002337HWND WINAPI GetParent( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002338{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002339 WND *wndPtr;
2340 HWND retvalue;
2341
2342 if(!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
2343 if ((!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD))))
2344 {
2345 WIN_ReleaseWndPtr(wndPtr);
2346 return 0;
2347 }
2348 WIN_UpdateWndPtr(&wndPtr,((wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner));
2349 retvalue = wndPtr ? wndPtr->hwndSelf : 0;
2350
2351 WIN_ReleaseWndPtr(wndPtr);
2352 return retvalue;
2353
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002354}
2355
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002356/*****************************************************************
2357 * WIN_GetTopParent
2358 *
2359 * Get the top-level parent for a child window.
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002360 * returns a locked pointer
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002361 */
2362WND* WIN_GetTopParentPtr( WND* pWnd )
2363{
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002364 WND *tmpWnd = WIN_LockWndPtr(pWnd);
2365
2366 while( tmpWnd && (tmpWnd->dwStyle & WS_CHILD))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002367 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002368 WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002369 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002370 return tmpWnd;
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002371}
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002372
2373/*****************************************************************
2374 * WIN_GetTopParent
2375 *
2376 * Get the top-level parent for a child window.
2377 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002378HWND WIN_GetTopParent( HWND hwnd )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002379{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002380 HWND retvalue;
2381 WND *tmpPtr = WIN_FindWndPtr(hwnd);
2382 WND *wndPtr = WIN_GetTopParentPtr (tmpPtr );
2383
2384 retvalue = wndPtr ? wndPtr->hwndSelf : 0;
2385 WIN_ReleaseWndPtr(tmpPtr);
2386 WIN_ReleaseWndPtr(wndPtr);
2387 return retvalue;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002388}
2389
2390
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002391/*****************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002392 * SetParent16 (USER.233)
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002393 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002394HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002395{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002396 return SetParent( hwndChild, hwndNewParent );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002397}
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002398
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002399
2400/*****************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002401 * SetParent32 (USER32.495)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002402 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002403HWND WINAPI SetParent( HWND hwndChild, HWND hwndNewParent )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002404{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002405 WND *wndPtr;
2406 DWORD dwStyle;
2407 WND *pWndNewParent;
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002408 WND *pWndOldParent;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002409 HWND retvalue;
2410
2411
2412 if(!(wndPtr = WIN_FindWndPtr(hwndChild))) return 0;
2413
2414 dwStyle = wndPtr->dwStyle;
2415
2416 pWndNewParent = hwndNewParent ? WIN_FindWndPtr(hwndNewParent)
2417 : WIN_LockWndPtr(pWndDesktop);
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002418
2419 /* Windows hides the window first, then shows it again
2420 * including the WM_SHOWWINDOW messages and all */
2421 if (dwStyle & WS_VISIBLE)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002422 ShowWindow( hwndChild, SW_HIDE );
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002423
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002424 pWndOldParent = WIN_LockWndPtr((*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent));
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002425
Noel Borthwick463eb291999-01-20 13:50:13 +00002426 /* SetParent32 additionally needs to make hwndChild the topmost window
2427 in the x-order and send the expected WM_WINDOWPOSCHANGING and
2428 WM_WINDOWPOSCHANGED notification messages.
2429 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002430 SetWindowPos( hwndChild, HWND_TOPMOST, 0, 0, 0, 0,
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002431 SWP_NOMOVE|SWP_NOSIZE|((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
2432 /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
2433 * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
2434
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002435 retvalue = pWndOldParent?pWndOldParent->hwndSelf:0;
2436
2437 WIN_ReleaseWndPtr(pWndOldParent);
2438 WIN_ReleaseWndPtr(pWndNewParent);
2439 WIN_ReleaseWndPtr(wndPtr);
2440
2441 return retvalue;
2442
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002443}
2444
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002445/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002446 * IsChild16 (USER.48)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002447 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002448BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002449{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002450 return IsChild(parent,child);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002451}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002452
2453
Alexandre Julliard01d63461997-01-20 19:43:45 +00002454/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002455 * IsChild32 (USER32.339)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002456 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002457BOOL WINAPI IsChild( HWND parent, HWND child )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002458{
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002459 WND * wndPtr = WIN_FindWndPtr( child );
2460 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
Alexandre Julliard0e607781993-11-03 19:23:37 +00002461 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002462 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
2463 if (wndPtr->hwndSelf == parent)
2464 {
2465 WIN_ReleaseWndPtr(wndPtr);
2466 return TRUE;
2467 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002468 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002469 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard0e607781993-11-03 19:23:37 +00002470 return FALSE;
2471}
2472
2473
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002474/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002475 * IsWindowVisible16 (USER.49)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002476 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002477BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002478{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002479 return IsWindowVisible(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002480}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002481
2482
Alexandre Julliard01d63461997-01-20 19:43:45 +00002483/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002484 * IsWindowVisible32 (USER32.351)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002485 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002486BOOL WINAPI IsWindowVisible( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002487{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002488 BOOL retval;
Alexandre Julliardded30381995-07-06 17:18:27 +00002489 WND *wndPtr = WIN_FindWndPtr( hwnd );
2490 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
2491 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002492 if (!(wndPtr->dwStyle & WS_VISIBLE))
2493 {
2494 WIN_ReleaseWndPtr(wndPtr);
2495 return FALSE;
2496 }
2497 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
Alexandre Julliardded30381995-07-06 17:18:27 +00002498 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002499 retval = (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
2500 WIN_ReleaseWndPtr(wndPtr);
2501 return retval;
2502
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002503}
2504
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002505
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002506/***********************************************************************
2507 * WIN_IsWindowDrawable
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002508 *
2509 * hwnd is drawable when it is visible, all parents are not
2510 * minimized, and it is itself not minimized unless we are
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002511 * trying to draw its default class icon.
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002512 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002513BOOL WIN_IsWindowDrawable( WND* wnd, BOOL icon )
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002514{
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002515 if( (wnd->dwStyle & WS_MINIMIZE &&
2516 icon && wnd->class->hIcon) ||
2517 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
2518 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
2519 if( wnd->dwStyle & WS_MINIMIZE ||
2520 !(wnd->dwStyle & WS_VISIBLE) ) break;
2521 return (wnd == NULL);
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002522}
2523
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002524
Alexandre Julliard0e607781993-11-03 19:23:37 +00002525/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002526 * GetTopWindow16 (USER.229)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002527 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002528HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002529{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002530 return GetTopWindow(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002531}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002532
2533
Alexandre Julliard01d63461997-01-20 19:43:45 +00002534/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002535 * GetTopWindow32 (USER.229)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002536 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002537HWND WINAPI GetTopWindow( HWND hwnd )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002538{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002539 HWND retval;
Francis Beaudetb7e8e801999-05-22 10:46:30 +00002540 WND * wndPtr = NULL;
2541
2542 if (hwnd!=0)
2543 wndPtr = WIN_FindWndPtr( hwnd );
2544 else
2545 wndPtr = WIN_GetDesktop();
2546
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002547 if (wndPtr && wndPtr->child)
2548 {
2549 retval = wndPtr->child->hwndSelf;
2550 }
2551 else retval = 0;
2552 WIN_ReleaseWndPtr(wndPtr);
2553 return retval;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002554}
2555
2556
2557/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002558 * GetWindow16 (USER.262)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002559 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002560HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002561{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002562 return GetWindow( hwnd,rel );
Alexandre Julliard01d63461997-01-20 19:43:45 +00002563}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002564
2565
Alexandre Julliard01d63461997-01-20 19:43:45 +00002566/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002567 * GetWindow32 (USER32.302)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002568 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002569HWND WINAPI GetWindow( HWND hwnd, WORD rel )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002570{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002571 HWND retval;
2572
Alexandre Julliard0e607781993-11-03 19:23:37 +00002573 WND * wndPtr = WIN_FindWndPtr( hwnd );
2574 if (!wndPtr) return 0;
2575 switch(rel)
2576 {
2577 case GW_HWNDFIRST:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002578 if (wndPtr->parent) retval = wndPtr->parent->child->hwndSelf;
2579 else retval = 0;
2580 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002581
2582 case GW_HWNDLAST:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002583 if (!wndPtr->parent)
2584 {
2585 retval = 0; /* Desktop window */
2586 goto end;
2587 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002588 while (wndPtr->next)
2589 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002590 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002591 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002592 retval = wndPtr->hwndSelf;
2593 goto end;
2594
2595 case GW_HWNDNEXT:
2596 if (!wndPtr->next) retval = 0;
2597 else retval = wndPtr->next->hwndSelf;
2598 goto end;
2599
2600 case GW_HWNDPREV:
2601 if (!wndPtr->parent)
2602 {
2603 retval = 0; /* Desktop window */
2604 goto end;
2605 }
2606 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent->child); /* First sibling */
2607 if (wndPtr->hwndSelf == hwnd)
2608 {
2609 retval = 0; /* First in list */
2610 goto end;
2611 }
2612 while (wndPtr->next)
2613 {
2614 if (wndPtr->next->hwndSelf == hwnd)
2615 {
2616 retval = wndPtr->hwndSelf;
2617 goto end;
2618 }
2619 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
2620 }
2621 retval = 0;
2622 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002623
2624 case GW_OWNER:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002625 retval = wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
2626 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002627
2628 case GW_CHILD:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002629 retval = wndPtr->child ? wndPtr->child->hwndSelf : 0;
2630 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002631 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002632 retval = 0;
2633end:
2634 WIN_ReleaseWndPtr(wndPtr);
2635 return retval;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002636}
2637
2638
2639/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002640 * GetNextWindow16 (USER.230)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002641 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002642HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002643{
2644 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
Alexandre Julliard01d63461997-01-20 19:43:45 +00002645 return GetWindow16( hwnd, flag );
Alexandre Julliard0e607781993-11-03 19:23:37 +00002646}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002647
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002648/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002649 * ShowOwnedPopups16 (USER.265)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002650 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002651void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002652{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002653 ShowOwnedPopups( owner, fShow );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002654}
2655
2656
2657/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002658 * ShowOwnedPopups32 (USER32.531)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002659 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002660BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL fShow )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002661{
Noomen Hamzaa018d851999-09-28 16:26:09 +00002662 UINT totalChild=0, count=0;
2663
2664 WND **pWnd = WIN_BuildWinArray(WIN_GetDesktop(), 0, &totalChild);
2665
2666 if (!pWnd) return TRUE;
2667
2668 for (; count < totalChild; count++)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002669 {
Noomen Hamzaa018d851999-09-28 16:26:09 +00002670 if (pWnd[count]->owner && (pWnd[count]->owner->hwndSelf == owner) && (pWnd[count]->dwStyle & WS_POPUP))
2671 SendMessageA(pWnd[count]->hwndSelf, WM_SHOWWINDOW, fShow ? SW_SHOW : SW_HIDE,IsIconic(owner) ? SW_PARENTOPENING : SW_PARENTCLOSING);
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002672 }
Noomen Hamzaa018d851999-09-28 16:26:09 +00002673
2674 WIN_ReleaseDesktop();
2675 WIN_ReleaseWinArray(pWnd);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002676 return TRUE;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002677}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002678
2679
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002680/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002681 * GetLastActivePopup16 (USER.287)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002682 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002683HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002684{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002685 return GetLastActivePopup( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002686}
2687
2688/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002689 * GetLastActivePopup32 (USER32.256)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002690 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002691HWND WINAPI GetLastActivePopup( HWND hwnd )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002692{
2693 WND *wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002694 HWND retval;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002695 wndPtr = WIN_FindWndPtr(hwnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002696 if (!wndPtr) return hwnd;
2697 retval = wndPtr->hwndLastActive;
2698 WIN_ReleaseWndPtr(wndPtr);
2699 return retval;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002700}
2701
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002702
2703/*******************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002704 * WIN_BuildWinArray
2705 *
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002706 * Build an array of pointers to the children of a given window.
Alexandre Julliard90476d62000-02-16 22:47:24 +00002707 * The array must be freed with WIN_ReleaseWinArray. Return NULL
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002708 * when no windows are found.
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002709 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002710WND **WIN_BuildWinArray( WND *wndPtr, UINT bwaFlags, UINT* pTotal )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002711{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002712 /* Future : this function will lock all windows associated with this array */
2713
Alexandre Julliard3051b641996-07-05 17:14:13 +00002714 WND **list, **ppWnd;
2715 WND *pWnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002716 UINT count = 0, skipOwned, skipHidden;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002717 DWORD skipFlags;
2718
2719 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2720 skipOwned = bwaFlags & BWA_SKIPOWNED;
2721 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2722 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002723
2724 /* First count the windows */
2725
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002726 if (!wndPtr)
2727 wndPtr = WIN_GetDesktop();
2728
2729 pWnd = WIN_LockWndPtr(wndPtr->child);
2730 while (pWnd)
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002731 {
Alex Korobka44a1b591999-04-01 12:03:52 +00002732 if( !(pWnd->dwStyle & skipFlags) && !(skipOwned && pWnd->owner) &&
2733 (!skipHidden || (pWnd->dwStyle & WS_VISIBLE)) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002734 count++;
Alex Korobka44a1b591999-04-01 12:03:52 +00002735 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002736 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002737
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002738 if( count )
2739 {
2740 /* Now build the list of all windows */
Alexandre Julliard3051b641996-07-05 17:14:13 +00002741
Alexandre Julliard90476d62000-02-16 22:47:24 +00002742 if ((list = (WND **)HeapAlloc( GetProcessHeap(), 0, sizeof(WND *) * (count + 1))))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002743 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002744 for (pWnd = WIN_LockWndPtr(wndPtr->child), ppWnd = list, count = 0; pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002745 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002746 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) );
2747 else if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002748 {
2749 *ppWnd++ = pWnd;
2750 count++;
2751 }
2752 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002753 WIN_ReleaseWndPtr(pWnd);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002754 *ppWnd = NULL;
2755 }
2756 else count = 0;
2757 } else list = NULL;
2758
2759 if( pTotal ) *pTotal = count;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002760 return list;
2761}
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002762/*******************************************************************
2763 * WIN_ReleaseWinArray
2764 */
2765void WIN_ReleaseWinArray(WND **wndArray)
2766{
2767 /* Future : this function will also unlock all windows associated with wndArray */
Alexandre Julliard90476d62000-02-16 22:47:24 +00002768 HeapFree( GetProcessHeap(), 0, wndArray );
Alexandre Julliard3051b641996-07-05 17:14:13 +00002769
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002770}
Alexandre Julliard3051b641996-07-05 17:14:13 +00002771
2772/*******************************************************************
2773 * EnumWindows16 (USER.54)
2774 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002775BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002776{
2777 WND **list, **ppWnd;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002778
Alexandre Julliard594997c1995-04-30 10:05:20 +00002779 /* We have to build a list of all windows first, to avoid */
2780 /* unpleasant side-effects, for instance if the callback */
2781 /* function changes the Z-order of the windows. */
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002782
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002783 if (!(list = WIN_BuildWinArray(WIN_GetDesktop(), 0, NULL )))
2784 {
2785 WIN_ReleaseDesktop();
2786 return FALSE;
2787 }
Alexandre Julliard594997c1995-04-30 10:05:20 +00002788
Alexandre Julliard3051b641996-07-05 17:14:13 +00002789 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002790
Alexandre Julliard3051b641996-07-05 17:14:13 +00002791 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002792 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002793 LRESULT lpEnumFuncRetval;
2794 int iWndsLocks = 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002795 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002796 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Francois Boisvertd96bc151999-04-02 10:34:43 +00002797
2798 /* To avoid any deadlocks, all the locks on the windows
2799 structures must be suspended before the control
2800 is passed to the application */
2801 iWndsLocks = WIN_SuspendWndsLock();
2802 lpEnumFuncRetval = lpEnumFunc( (*ppWnd)->hwndSelf, lParam);
2803 WIN_RestoreWndsLock(iWndsLocks);
2804
2805 if (!lpEnumFuncRetval) break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002806 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002807 WIN_ReleaseWinArray(list);
2808 WIN_ReleaseDesktop();
Alexandre Julliard3051b641996-07-05 17:14:13 +00002809 return TRUE;
2810}
2811
2812
2813/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002814 * EnumWindows32 (USER32.193)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002815 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002816BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002817{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002818 return (BOOL)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002819}
2820
Alexandre Julliard594997c1995-04-30 10:05:20 +00002821
2822/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002823 * EnumTaskWindows16 (USER.225)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002824 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002825BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2826 LPARAM lParam )
Alexandre Julliard594997c1995-04-30 10:05:20 +00002827{
Alexandre Julliard3051b641996-07-05 17:14:13 +00002828 WND **list, **ppWnd;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002829
2830 /* This function is the same as EnumWindows(), */
Per Ångströma47bc3a1998-11-14 17:00:37 +00002831 /* except for an added check on the window's task. */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002832
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002833 if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
2834 {
2835 WIN_ReleaseDesktop();
2836 return FALSE;
2837 }
Alexandre Julliard594997c1995-04-30 10:05:20 +00002838
Alexandre Julliard3051b641996-07-05 17:14:13 +00002839 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002840
Alexandre Julliard3051b641996-07-05 17:14:13 +00002841 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002842 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002843 LRESULT funcRetval;
2844 int iWndsLocks = 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002845 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002846 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Per Ångströma47bc3a1998-11-14 17:00:37 +00002847 if (QUEUE_GetQueueTask((*ppWnd)->hmemTaskQ) != hTask) continue;
Francois Boisvertd96bc151999-04-02 10:34:43 +00002848
2849 /* To avoid any deadlocks, all the locks on the windows
2850 structures must be suspended before the control
2851 is passed to the application */
2852 iWndsLocks = WIN_SuspendWndsLock();
2853 funcRetval = func( (*ppWnd)->hwndSelf, lParam );
2854 WIN_RestoreWndsLock(iWndsLocks);
2855
2856 if (!funcRetval) break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002857 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002858 WIN_ReleaseWinArray(list);
2859 WIN_ReleaseDesktop();
Alexandre Julliard594997c1995-04-30 10:05:20 +00002860 return TRUE;
2861}
2862
2863
Alexandre Julliard3051b641996-07-05 17:14:13 +00002864/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002865 * EnumThreadWindows (USER32.190)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002866 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002867BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002868{
Alexandre Julliard0a860a01999-06-22 11:43:42 +00002869 TEB *teb = THREAD_IdToTEB(id);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002870
Alexandre Julliard0a860a01999-06-22 11:43:42 +00002871 return (BOOL16)EnumTaskWindows16(teb->htask16, (WNDENUMPROC16)func, lParam);
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002872}
2873
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002874
Alexandre Julliard3051b641996-07-05 17:14:13 +00002875/**********************************************************************
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002876 * WIN_EnumChildWindows
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002877 *
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002878 * Helper function for EnumChildWindows().
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002879 */
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002880static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2881 LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002882{
Alexandre Julliard3051b641996-07-05 17:14:13 +00002883 WND **childList;
2884 BOOL16 ret = FALSE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002885
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002886 for ( ; *ppWnd; ppWnd++)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002887 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002888 int iWndsLocks = 0;
2889
Alexandre Julliard3051b641996-07-05 17:14:13 +00002890 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002891 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002892 /* Build children list first */
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002893 childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
Francois Boisvertd96bc151999-04-02 10:34:43 +00002894
2895 /* To avoid any deadlocks, all the locks on the windows
2896 structures must be suspended before the control
2897 is passed to the application */
2898 iWndsLocks = WIN_SuspendWndsLock();
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002899 ret = func( (*ppWnd)->hwndSelf, lParam );
Francois Boisvertd96bc151999-04-02 10:34:43 +00002900 WIN_RestoreWndsLock(iWndsLocks);
2901
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002902 if (childList)
2903 {
2904 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002905 WIN_ReleaseWinArray(childList);
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002906 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002907 if (!ret) return FALSE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002908 }
2909 return TRUE;
2910}
2911
2912
2913/**********************************************************************
2914 * EnumChildWindows16 (USER.55)
2915 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002916BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2917 LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002918{
2919 WND **list, *pParent;
2920
2921 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002922 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL )))
2923 {
2924 WIN_ReleaseWndPtr(pParent);
2925 return FALSE;
2926 }
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002927 WIN_EnumChildWindows( list, func, lParam );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002928 WIN_ReleaseWinArray(list);
2929 WIN_ReleaseWndPtr(pParent);
Alexandre Julliard3051b641996-07-05 17:14:13 +00002930 return TRUE;
2931}
2932
2933
2934/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002935 * EnumChildWindows32 (USER32.178)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002936 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002937BOOL WINAPI EnumChildWindows( HWND parent, WNDENUMPROC func,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002938 LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002939{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002940 return (BOOL)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002941 lParam );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002942}
2943
Alexandre Julliard594997c1995-04-30 10:05:20 +00002944
Alexandre Julliard58199531994-04-21 01:20:00 +00002945/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002946 * AnyPopup16 (USER.52)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002947 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002948BOOL16 WINAPI AnyPopup16(void)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002949{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002950 return AnyPopup();
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002951}
2952
2953
2954/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002955 * AnyPopup32 (USER32.4)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002956 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002957BOOL WINAPI AnyPopup(void)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002958{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002959 WND *wndPtr = WIN_LockWndPtr(pWndDesktop->child);
2960 BOOL retvalue;
2961
2962 while (wndPtr)
2963 {
2964 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE))
2965 {
2966 retvalue = TRUE;
2967 goto end;
2968}
2969 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
2970 }
2971 retvalue = FALSE;
2972end:
2973 WIN_ReleaseWndPtr(wndPtr);
2974 return retvalue;
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002975}
2976
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002977
Alexandre Julliard73450d61994-05-18 18:29:32 +00002978/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002979 * FlashWindow16 (USER.105)
Alexandre Julliard73450d61994-05-18 18:29:32 +00002980 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002981BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002982{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002983 return FlashWindow( hWnd, bInvert );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002984}
2985
2986
2987/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002988 * FlashWindow32 (USER32.202)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002989 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002990BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert )
Alexandre Julliard73450d61994-05-18 18:29:32 +00002991{
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002992 WND *wndPtr = WIN_FindWndPtr(hWnd);
2993
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002994 TRACE("%04x\n", hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002995
2996 if (!wndPtr) return FALSE;
2997
2998 if (wndPtr->dwStyle & WS_MINIMIZE)
2999 {
3000 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
3001 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003002 HDC hDC = GetDC(hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003003
Alexandre Julliard530ee841996-10-23 16:59:13 +00003004 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003005 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
3006
Alexandre Julliarda3960291999-02-26 11:11:13 +00003007 ReleaseDC( hWnd, hDC );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003008 wndPtr->flags |= WIN_NCACTIVATED;
3009 }
3010 else
3011 {
Alexandre Julliard1e37a181996-08-18 16:21:52 +00003012 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
3013 RDW_UPDATENOW | RDW_FRAME, 0 );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003014 wndPtr->flags &= ~WIN_NCACTIVATED;
3015 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003016 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003017 return TRUE;
3018 }
3019 else
3020 {
Alexandre Julliard530ee841996-10-23 16:59:13 +00003021 WPARAM16 wparam;
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003022 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
Alexandre Julliarda3960291999-02-26 11:11:13 +00003023 else wparam = (hWnd == GetActiveWindow());
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003024
Alexandre Julliard2d93d001996-05-21 15:01:41 +00003025 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003026 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003027 return wparam;
3028 }
Alexandre Julliard73450d61994-05-18 18:29:32 +00003029}
3030
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003031
3032/*******************************************************************
Alexandre Julliard18f92e71996-07-17 20:02:21 +00003033 * SetSysModalWindow16 (USER.188)
Alexandre Julliard58199531994-04-21 01:20:00 +00003034 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003035HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
Alexandre Julliard58199531994-04-21 01:20:00 +00003036{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003037 HWND hWndOldModal = hwndSysModal;
Alexandre Julliardd4719651995-12-12 18:49:11 +00003038 hwndSysModal = hWnd;
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00003039 FIXME("EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
Alexandre Julliardd4719651995-12-12 18:49:11 +00003040 return hWndOldModal;
Alexandre Julliard58199531994-04-21 01:20:00 +00003041}
3042
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003043
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003044/*******************************************************************
Alexandre Julliard18f92e71996-07-17 20:02:21 +00003045 * GetSysModalWindow16 (USER.52)
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003046 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003047HWND16 WINAPI GetSysModalWindow16(void)
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003048{
Alexandre Julliardd4719651995-12-12 18:49:11 +00003049 return hwndSysModal;
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003050}
Alexandre Julliardade697e1995-11-26 13:59:11 +00003051
Alexandre Julliard18f92e71996-07-17 20:02:21 +00003052
Alexandre Julliardade697e1995-11-26 13:59:11 +00003053/*******************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003054 * GetWindowContextHelpId (USER32.303)
3055 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003056DWORD WINAPI GetWindowContextHelpId( HWND hwnd )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003057{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003058 DWORD retval;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003059 WND *wnd = WIN_FindWndPtr( hwnd );
3060 if (!wnd) return 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003061 retval = wnd->helpContext;
3062 WIN_ReleaseWndPtr(wnd);
3063 return retval;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003064}
3065
3066
3067/*******************************************************************
3068 * SetWindowContextHelpId (USER32.515)
3069 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003070BOOL WINAPI SetWindowContextHelpId( HWND hwnd, DWORD id )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003071{
3072 WND *wnd = WIN_FindWndPtr( hwnd );
3073 if (!wnd) return FALSE;
3074 wnd->helpContext = id;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003075 WIN_ReleaseWndPtr(wnd);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003076 return TRUE;
3077}
3078
3079
3080/*******************************************************************
Alexandre Julliardade697e1995-11-26 13:59:11 +00003081 * DRAG_QueryUpdate
3082 *
3083 * recursively find a child that contains spDragInfo->pt point
3084 * and send WM_QUERYDROPOBJECT
3085 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003086BOOL16 DRAG_QueryUpdate( HWND hQueryWnd, SEGPTR spDragInfo, BOOL bNoSend )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003087{
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003088 BOOL16 wParam,bResult = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003089 POINT pt;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003090 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
3091 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003092 RECT tempRect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003093
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003094 if( !ptrQueryWnd || !ptrDragInfo )
3095 {
3096 WIN_ReleaseWndPtr(ptrQueryWnd);
3097 return 0;
3098 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003099
Alexandre Julliardd37eb361997-07-20 16:23:21 +00003100 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003101
Alexandre Julliarda3960291999-02-26 11:11:13 +00003102 GetWindowRect(hQueryWnd,&tempRect);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003103
Alexandre Julliarda3960291999-02-26 11:11:13 +00003104 if( !PtInRect(&tempRect,pt) ||
Alexandre Julliardade697e1995-11-26 13:59:11 +00003105 (ptrQueryWnd->dwStyle & WS_DISABLED) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003106 {
3107 WIN_ReleaseWndPtr(ptrQueryWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003108 return 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003109 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003110
3111 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
3112 {
3113 tempRect = ptrQueryWnd->rectClient;
3114 if(ptrQueryWnd->dwStyle & WS_CHILD)
Alexandre Julliarda3960291999-02-26 11:11:13 +00003115 MapWindowPoints( ptrQueryWnd->parent->hwndSelf, 0,
3116 (LPPOINT)&tempRect, 2 );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003117
Alexandre Julliarda3960291999-02-26 11:11:13 +00003118 if (PtInRect( &tempRect, pt))
Alexandre Julliardade697e1995-11-26 13:59:11 +00003119 {
3120 wParam = 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003121
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003122 for (ptrWnd = WIN_LockWndPtr(ptrQueryWnd->child); ptrWnd ;WIN_UpdateWndPtr(&ptrWnd,ptrWnd->next))
3123 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003124 if( ptrWnd->dwStyle & WS_VISIBLE )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003125 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003126 GetWindowRect( ptrWnd->hwndSelf, &tempRect );
3127 if (PtInRect( &tempRect, pt )) break;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003128 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003129 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003130
3131 if(ptrWnd)
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003132 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +00003133 TRACE_(msg)("hwnd = %04x, %d %d - %d %d\n",
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003134 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
3135 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
3136 if( !(ptrWnd->dwStyle & WS_DISABLED) )
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003137 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003138
3139 WIN_ReleaseWndPtr(ptrWnd);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003140 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003141
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003142 if(bResult)
3143 {
3144 WIN_ReleaseWndPtr(ptrQueryWnd);
3145 return bResult;
3146 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003147 }
3148 else wParam = 1;
3149 }
3150 else wParam = 1;
3151
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00003152 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003153
3154 ptrDragInfo->hScope = hQueryWnd;
3155
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003156 bResult = ( bNoSend )
3157 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
3158 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
Alexandre Julliard530ee841996-10-23 16:59:13 +00003159 (WPARAM16)wParam ,(LPARAM) spDragInfo );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003160 if( !bResult )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00003161 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003162
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003163 WIN_ReleaseWndPtr(ptrQueryWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003164 return bResult;
3165}
3166
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003167
Alexandre Julliardade697e1995-11-26 13:59:11 +00003168/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003169 * DragDetect (USER.465)
Alexandre Julliardade697e1995-11-26 13:59:11 +00003170 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003171BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003172{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003173 POINT pt32;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003174 CONV_POINT16TO32( &pt, &pt32 );
Alexandre Julliarda3960291999-02-26 11:11:13 +00003175 return DragDetect( hWnd, pt32 );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003176}
3177
3178/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00003179 * DragDetect32 (USER32.151)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003180 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003181BOOL WINAPI DragDetect( HWND hWnd, POINT pt )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003182{
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003183 MSG16 msg;
3184 RECT16 rect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003185
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003186 rect.left = pt.x - wDragWidth;
3187 rect.right = pt.x + wDragWidth;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003188
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003189 rect.top = pt.y - wDragHeight;
3190 rect.bottom = pt.y + wDragHeight;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003191
Alexandre Julliarda3960291999-02-26 11:11:13 +00003192 SetCapture(hWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003193
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003194 while(1)
3195 {
3196 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
3197 {
3198 if( msg.message == WM_LBUTTONUP )
3199 {
3200 ReleaseCapture();
3201 return 0;
3202 }
3203 if( msg.message == WM_MOUSEMOVE )
3204 {
3205 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003206 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003207 ReleaseCapture();
3208 return 1;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003209 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003210 }
3211 }
3212 WaitMessage();
3213 }
3214 return 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003215}
3216
3217/******************************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00003218 * DragObject16 (USER.464)
Alexandre Julliardade697e1995-11-26 13:59:11 +00003219 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003220DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
3221 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003222{
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003223 MSG16 msg;
3224 LPDRAGINFO lpDragInfo;
3225 SEGPTR spDragInfo;
3226 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
3227 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
3228 WND *wndPtr = WIN_FindWndPtr(hWnd);
3229 HCURSOR16 hCurrentCursor = 0;
3230 HWND16 hCurrentWnd = 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003231
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003232 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
3233 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003234
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003235 if( !lpDragInfo || !spDragInfo )
3236 {
3237 WIN_ReleaseWndPtr(wndPtr);
3238 return 0L;
3239 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003240
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003241 hBummer = LoadCursor16(0, IDC_BUMMER16);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003242
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003243 if( !hBummer || !wndPtr )
3244 {
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00003245 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003246 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003247 return 0L;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003248 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003249
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003250 if(hCursor)
3251 {
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003252 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003253 {
3254 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003255 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003256 return 0L;
3257 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003258
3259 if( hDragCursor == hCursor ) hDragCursor = 0;
3260 else hCursor = hDragCursor;
3261
Alexandre Julliarda3960291999-02-26 11:11:13 +00003262 hOldCursor = SetCursor(hDragCursor);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003263 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003264
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003265 lpDragInfo->hWnd = hWnd;
3266 lpDragInfo->hScope = 0;
3267 lpDragInfo->wFlags = wObj;
3268 lpDragInfo->hList = szList; /* near pointer! */
3269 lpDragInfo->hOfStruct = hOfStruct;
3270 lpDragInfo->l = 0L;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003271
Alexandre Julliarda3960291999-02-26 11:11:13 +00003272 SetCapture(hWnd);
3273 ShowCursor( TRUE );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003274
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003275 do
3276 {
3277 do{ WaitMessage(); }
3278 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003279
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003280 *(lpDragInfo+1) = *lpDragInfo;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003281
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003282 lpDragInfo->pt = msg.pt;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003283
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003284 /* update DRAGINFO struct */
Alexandre Julliard06c275a1999-05-02 14:32:27 +00003285 TRACE_(msg)("lpDI->hScope = %04x\n",lpDragInfo->hScope);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003286
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003287 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
3288 hCurrentCursor = hCursor;
3289 else
Alexandre Julliardade697e1995-11-26 13:59:11 +00003290 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003291 hCurrentCursor = hBummer;
3292 lpDragInfo->hScope = 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003293 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003294 if( hCurrentCursor )
Alexandre Julliarda3960291999-02-26 11:11:13 +00003295 SetCursor(hCurrentCursor);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003296
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003297 /* send WM_DRAGLOOP */
3298 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
3299 (LPARAM) spDragInfo );
3300 /* send WM_DRAGSELECT or WM_DRAGMOVE */
3301 if( hCurrentWnd != lpDragInfo->hScope )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003302 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003303 if( hCurrentWnd )
3304 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
Alexandre Julliardade697e1995-11-26 13:59:11 +00003305 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
3306 HIWORD(spDragInfo)) );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003307 hCurrentWnd = lpDragInfo->hScope;
3308 if( hCurrentWnd )
3309 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003310 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003311 else
3312 if( hCurrentWnd )
3313 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
3314
3315 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
3316
3317 ReleaseCapture();
Alexandre Julliarda3960291999-02-26 11:11:13 +00003318 ShowCursor( FALSE );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003319
3320 if( hCursor )
3321 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003322 SetCursor( hOldCursor );
3323 if (hDragCursor) DestroyCursor( hDragCursor );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003324 }
3325
3326 if( hCurrentCursor != hBummer )
3327 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
3328 (WPARAM16)hWnd, (LPARAM)spDragInfo );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003329 else
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003330 msg.lParam = 0;
3331 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003332 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003333
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003334 return (DWORD)(msg.lParam);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003335}