blob: ab364d7edf22b2c456b7118629ab410afea2cb23 [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 *
Andreas Mohr1c20b392000-02-20 19:17:35 +0000709 * 1) not only it checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
Slava Monicha27807d1999-06-05 11:46:35 +0000710 * 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 {
Andreas Mohr1c20b392000-02-20 19:17:35 +00001329 retvalue = FALSE; /* Can't destroy desktop */
1330 goto end;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001331 }
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
1498 if (child)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001499 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001500 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1501 if (parent)
1502 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001503 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent))
1504 {
1505 retvalue = 0;
1506 goto end;
1507 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001508 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001509 else if (pWnd->parent != pWndDesktop)
1510 {
1511 retvalue = 0;
1512 goto end;
1513 }
1514 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001515 }
1516 else
1517 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001518 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : WIN_LockWndPtr(pWndDesktop)))
1519 {
1520 retvalue = 0;
1521 goto end;
1522 }
1523 WIN_UpdateWndPtr(&pWnd,pWnd->child);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001524 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001525 if (!pWnd)
1526 {
1527 retvalue = 0;
1528 goto end;
1529 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001530
Pavel Roskin598993f1999-03-16 09:53:10 +00001531 for ( ; pWnd ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001532 {
Alexandre Julliard4f152392000-02-25 20:45:23 +00001533 if (className && (pWnd->class->atomName != className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001534 continue; /* Not the right class */
1535
1536 /* Now check the title */
1537
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001538 if (!title)
1539 {
1540 retvalue = pWnd->hwndSelf;
1541 goto end;
Pavel Roskin598993f1999-03-16 09:53:10 +00001542 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001543 if (pWnd->text && !strcmp( pWnd->text, title ))
1544 {
1545 retvalue = pWnd->hwndSelf;
1546 goto end;
Pavel Roskin598993f1999-03-16 09:53:10 +00001547 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001548 }
1549 retvalue = 0;
1550end:
1551 WIN_ReleaseWndPtr(pWnd);
1552 return retvalue;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001553}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001554
1555
1556
1557/***********************************************************************
1558 * FindWindow16 (USER.50)
1559 */
Alexandre Julliardb849d792000-02-13 13:56:13 +00001560HWND16 WINAPI FindWindow16( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001561{
Alexandre Julliardb849d792000-02-13 13:56:13 +00001562 return FindWindowA( className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001563}
1564
1565
1566/***********************************************************************
1567 * FindWindowEx16 (USER.427)
1568 */
Alexandre Julliardb849d792000-02-13 13:56:13 +00001569HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child, LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001570{
Alexandre Julliardb849d792000-02-13 13:56:13 +00001571 return FindWindowExA( parent, child, className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001572}
1573
1574
1575/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001576 * FindWindow32A (USER32.198)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001577 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001578HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001579{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001580 HWND ret = FindWindowExA( 0, 0, className, title );
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001581 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1582 return ret;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001583}
1584
1585
1586/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001587 * FindWindowEx32A (USER32.199)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001588 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001589HWND WINAPI FindWindowExA( HWND parent, HWND child,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001590 LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001591{
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001592 ATOM atom = 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001593
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001594 if (className)
1595 {
1596 /* If the atom doesn't exist, then no class */
1597 /* with this name exists either. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001598 if (!(atom = GlobalFindAtomA( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001599 {
1600 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1601 return 0;
1602 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001603 }
Alexandre Julliard77b99181997-09-14 17:17:23 +00001604 return WIN_FindWindow( parent, child, atom, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001605}
1606
1607
1608/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001609 * FindWindowEx32W (USER32.200)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001610 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001611HWND WINAPI FindWindowExW( HWND parent, HWND child,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001612 LPCWSTR className, LPCWSTR 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 char *buffer;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001616 HWND hwnd;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001617
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001618 if (className)
1619 {
1620 /* If the atom doesn't exist, then no class */
1621 /* with this name exists either. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001622 if (!(atom = GlobalFindAtomW( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001623 {
1624 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1625 return 0;
1626 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001627 }
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001628 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
Alexandre Julliard77b99181997-09-14 17:17:23 +00001629 hwnd = WIN_FindWindow( parent, child, atom, buffer );
Alexandre Julliard7ebe1a41996-12-22 18:27:48 +00001630 HeapFree( GetProcessHeap(), 0, buffer );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001631 return hwnd;
1632}
1633
1634
1635/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001636 * FindWindow32W (USER32.201)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001637 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001638HWND WINAPI FindWindowW( LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001639{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001640 return FindWindowExW( 0, 0, className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001641}
1642
1643
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001644/**********************************************************************
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001645 * WIN_GetDesktop
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001646 * returns a locked pointer
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001647 */
1648WND *WIN_GetDesktop(void)
1649{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001650 return WIN_LockWndPtr(pWndDesktop);
1651}
1652/**********************************************************************
1653 * WIN_ReleaseDesktop
1654 * unlock the desktop pointer
1655 */
1656void WIN_ReleaseDesktop(void)
1657{
1658 WIN_ReleaseWndPtr(pWndDesktop);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001659}
1660
1661
1662/**********************************************************************
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001663 * GetDesktopWindow16 (USER.286)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001664 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001665HWND16 WINAPI GetDesktopWindow16(void)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001666{
1667 return (HWND16)pWndDesktop->hwndSelf;
1668}
1669
1670
1671/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001672 * GetDesktopWindow32 (USER32.232)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001673 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001674HWND WINAPI GetDesktopWindow(void)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001675{
Uwe Bonnes73619161999-10-24 20:42:39 +00001676 if (pWndDesktop) return pWndDesktop->hwndSelf;
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001677 ERR( "You need the -desktop option when running with native USER\n" );
Uwe Bonnes73619161999-10-24 20:42:39 +00001678 ExitProcess(1);
Huw D M Davies238b6d71999-10-31 01:56:51 +00001679 return 0;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001680}
1681
1682
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001683/**********************************************************************
1684 * GetDesktopHwnd (USER.278)
1685 *
1686 * Exactly the same thing as GetDesktopWindow(), but not documented.
1687 * Don't ask me why...
1688 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001689HWND16 WINAPI GetDesktopHwnd16(void)
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001690{
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001691 return (HWND16)pWndDesktop->hwndSelf;
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001692}
1693
1694
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001695/*******************************************************************
Alexandre Julliard01d63461997-01-20 19:43:45 +00001696 * EnableWindow16 (USER.34)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001697 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001698BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
Alexandre Julliard01d63461997-01-20 19:43:45 +00001699{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001700 return EnableWindow( hwnd, enable );
Alexandre Julliard01d63461997-01-20 19:43:45 +00001701}
1702
1703
1704/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001705 * EnableWindow32 (USER32.172)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001706 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001707BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001708{
1709 WND *wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001710 BOOL retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001711
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001712 TRACE("EnableWindow32: ( %x, %d )\n", hwnd, enable);
Noel Borthwickb4278561999-02-05 10:37:53 +00001713
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001714 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1715 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1716 {
1717 /* Enable window */
1718 wndPtr->dwStyle &= ~WS_DISABLED;
Alex Korobka4f1ac051999-03-28 09:37:57 +00001719
1720 if( wndPtr->flags & WIN_NATIVE )
1721 wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ACCEPTFOCUS, TRUE );
1722
Alexandre Julliarda3960291999-02-26 11:11:13 +00001723 SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001724 retvalue = TRUE;
1725 goto end;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001726 }
1727 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1728 {
Alex Korobka4f1ac051999-03-28 09:37:57 +00001729 SendMessageA( wndPtr->hwndSelf, WM_CANCELMODE, 0, 0);
1730
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001731 /* Disable window */
1732 wndPtr->dwStyle |= WS_DISABLED;
Alex Korobka4f1ac051999-03-28 09:37:57 +00001733
1734 if( wndPtr->flags & WIN_NATIVE )
1735 wndPtr->pDriver->pSetHostAttr( wndPtr, HAK_ACCEPTFOCUS, FALSE );
1736
Francis Beaudet21d50f81999-05-29 14:10:02 +00001737 if (hwnd == GetFocus())
Noel Borthwickb4278561999-02-05 10:37:53 +00001738 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001739 SetFocus( 0 ); /* A disabled window can't have the focus */
Noel Borthwickb4278561999-02-05 10:37:53 +00001740 }
Pascal Lessard31c58541999-06-26 10:17:10 +00001741 if (hwnd == GetCapture())
Noel Borthwickb4278561999-02-05 10:37:53 +00001742 {
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001743 ReleaseCapture(); /* A disabled window can't capture the mouse */
Noel Borthwickb4278561999-02-05 10:37:53 +00001744 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00001745 SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001746 retvalue = FALSE;
1747 goto end;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001748 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001749 retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);
1750end:
1751 WIN_ReleaseWndPtr(wndPtr);
1752 return retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001753}
1754
1755
1756/***********************************************************************
Alexandre Julliard01d63461997-01-20 19:43:45 +00001757 * IsWindowEnabled16 (USER.35)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001758 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001759BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001760{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001761 return IsWindowEnabled(hWnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00001762}
1763
1764
1765/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001766 * IsWindowEnabled32 (USER32.349)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001767 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001768BOOL WINAPI IsWindowEnabled(HWND hWnd)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001769{
1770 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001771 BOOL retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001772
1773 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001774 retvalue = !(wndPtr->dwStyle & WS_DISABLED);
1775 WIN_ReleaseWndPtr(wndPtr);
1776 return retvalue;
1777
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001778}
1779
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001780
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001781/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001782 * IsWindowUnicode (USER32.350)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001783 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001784BOOL WINAPI IsWindowUnicode( HWND hwnd )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001785{
1786 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001787 BOOL retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001788
1789 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001790 retvalue = (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1791 WIN_ReleaseWndPtr(wndPtr);
1792 return retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001793}
1794
1795
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001796/**********************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00001797 * GetWindowWord16 (USER.133)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001798 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001799WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
Alexandre Julliard21979011997-03-05 08:22:35 +00001800{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001801 return GetWindowWord( hwnd, offset );
Alexandre Julliard21979011997-03-05 08:22:35 +00001802}
1803
1804
1805/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001806 * GetWindowWord32 (USER32.314)
Alexandre Julliard21979011997-03-05 08:22:35 +00001807 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001808WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001809{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001810 WORD retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001811 WND * wndPtr = WIN_FindWndPtr( hwnd );
1812 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001813 if (offset >= 0)
1814 {
1815 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1816 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001817 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001818 retvalue = 0;
1819 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001820 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001821 retvalue = *(WORD *)(((char *)wndPtr->wExtra) + offset);
1822 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001823 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001824 switch(offset)
1825 {
Alexandre Julliard77b99181997-09-14 17:17:23 +00001826 case GWW_ID:
1827 if (HIWORD(wndPtr->wIDmenu))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001828 WARN("GWW_ID: discards high bits of 0x%08x!\n",
Alexandre Julliarda845b881998-06-01 10:44:35 +00001829 wndPtr->wIDmenu);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001830 retvalue = (WORD)wndPtr->wIDmenu;
1831 goto end;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001832 case GWW_HWNDPARENT:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001833 retvalue = GetParent(hwnd);
1834 goto end;
Alexandre Julliard77b99181997-09-14 17:17:23 +00001835 case GWW_HINSTANCE:
1836 if (HIWORD(wndPtr->hInstance))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001837 WARN("GWW_HINSTANCE: discards high bits of 0x%08x!\n",
Alexandre Julliarda845b881998-06-01 10:44:35 +00001838 wndPtr->hInstance);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001839 retvalue = (WORD)wndPtr->hInstance;
1840 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001841 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001842 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001843 retvalue = 0;
1844 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001845 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001846end:
1847 WIN_ReleaseWndPtr(wndPtr);
1848 return retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001849}
1850
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00001851/**********************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00001852 * SetWindowWord16 (USER.134)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001853 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001854WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
Alexandre Julliard21979011997-03-05 08:22:35 +00001855{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001856 return SetWindowWord( hwnd, offset, newval );
Alexandre Julliard21979011997-03-05 08:22:35 +00001857}
1858
1859
1860/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00001861 * SetWindowWord32 (USER32.524)
Alexandre Julliard21979011997-03-05 08:22:35 +00001862 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001863WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001864{
1865 WORD *ptr, retval;
1866 WND * wndPtr = WIN_FindWndPtr( hwnd );
1867 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001868 if (offset >= 0)
1869 {
1870 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1871 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001872 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001873 retval = 0;
1874 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001875 }
1876 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1877 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001878 else switch(offset)
1879 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001880 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1881 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001882 case GWW_HWNDPARENT: retval = SetParent( hwnd, newval );
1883 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001884 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001885 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001886 retval = 0;
1887 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001888 }
1889 retval = *ptr;
1890 *ptr = newval;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001891end:
1892 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001893 return retval;
1894}
1895
1896
1897/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001898 * WIN_GetWindowLong
1899 *
1900 * Helper function for GetWindowLong().
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001901 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001902static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001903{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001904 LONG retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001905 WND * wndPtr = WIN_FindWndPtr( hwnd );
1906 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001907 if (offset >= 0)
1908 {
1909 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1910 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001911 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001912 retvalue = 0;
1913 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001914 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001915 retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
Alexandre Julliard3051b641996-07-05 17:14:13 +00001916 /* Special case for dialog window procedure */
1917 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001918 {
1919 retvalue = (LONG)WINPROC_GetProc( (HWINDOWPROC)retvalue, type );
1920 goto end;
1921 }
1922 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001923 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001924 switch(offset)
1925 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001926 case GWL_USERDATA: retvalue = wndPtr->userdata;
1927 goto end;
1928 case GWL_STYLE: retvalue = wndPtr->dwStyle;
1929 goto end;
1930 case GWL_EXSTYLE: retvalue = wndPtr->dwExStyle;
1931 goto end;
1932 case GWL_ID: retvalue = (LONG)wndPtr->wIDmenu;
1933 goto end;
1934 case GWL_WNDPROC: retvalue = (LONG)WINPROC_GetProc( wndPtr->winproc,
Alexandre Julliard3051b641996-07-05 17:14:13 +00001935 type );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001936 goto end;
1937 case GWL_HWNDPARENT: retvalue = GetParent(hwnd);
1938 goto end;
1939 case GWL_HINSTANCE: retvalue = wndPtr->hInstance;
1940 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001941 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001942 WARN("Unknown offset %d\n", offset );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001943 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001944 retvalue = 0;
1945end:
1946 WIN_ReleaseWndPtr(wndPtr);
1947 return retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001948}
1949
1950
1951/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001952 * WIN_SetWindowLong
1953 *
1954 * Helper function for SetWindowLong().
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001955 *
1956 * 0 is the failure code. However, in the case of failure SetLastError
1957 * must be set to distinguish between a 0 return value and a failure.
1958 *
1959 * FIXME: The error values for SetLastError may not be right. Can
1960 * someone check with the real thing?
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001961 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001962static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
Alexandre Julliard3051b641996-07-05 17:14:13 +00001963 WINDOWPROCTYPE type )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001964{
1965 LONG *ptr, retval;
1966 WND * wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001967 STYLESTRUCT style;
1968
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001969 TRACE("%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001970
1971 if (!wndPtr)
1972 {
1973 /* Is this the right error? */
1974 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1975 return 0;
1976 }
1977
Alexandre Julliard3051b641996-07-05 17:14:13 +00001978 if (offset >= 0)
1979 {
1980 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1981 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001982 WARN("Invalid offset %d\n", offset );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001983
1984 /* Is this the right error? */
1985 SetLastError( ERROR_OUTOFMEMORY );
1986
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001987 retval = 0;
1988 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001989 }
1990 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1991 /* Special case for dialog window procedure */
1992 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1993 {
1994 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00001995 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1996 type, WIN_PROC_WINDOW );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001997 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001998 }
1999 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002000 else switch(offset)
2001 {
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002002 case GWL_ID:
2003 ptr = (DWORD*)&wndPtr->wIDmenu;
2004 break;
2005 case GWL_HINSTANCE:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002006 retval = SetWindowWord( hwnd, offset, newval );
2007 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002008 case GWL_WNDPROC:
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002009 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
2010 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002011 type, WIN_PROC_WINDOW );
Andreas Mohr1c20b392000-02-20 19:17:35 +00002012 goto end;
Alexandre Julliardca22b331996-07-12 19:02:39 +00002013 case GWL_STYLE:
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002014 style.styleOld = wndPtr->dwStyle;
2015 newval &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way */
2016 style.styleNew = newval | (style.styleOld & (WS_VISIBLE | WS_CHILD));
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002017
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002018 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002019 SendMessageA(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002020 wndPtr->dwStyle = style.styleNew;
2021 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002022 SendMessageA(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002023 retval = style.styleOld;
2024 goto end;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002025
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002026 case GWL_USERDATA:
2027 ptr = &wndPtr->userdata;
2028 break;
2029 case GWL_EXSTYLE:
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002030 style.styleOld = wndPtr->dwExStyle;
2031 style.styleNew = newval;
Alexandre Julliarda0d77311998-09-13 16:32:00 +00002032 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002033 SendMessageA(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002034 wndPtr->dwExStyle = newval;
2035 if (wndPtr->flags & WIN_ISWIN32)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002036 SendMessageA(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002037 retval = style.styleOld;
2038 goto end;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002039
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002040 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002041 WARN("Invalid offset %d\n", offset );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00002042
2043 /* Don't think this is right error but it should do */
2044 SetLastError( ERROR_OUTOFMEMORY );
2045
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002046 retval = 0;
2047 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002048 }
2049 retval = *ptr;
2050 *ptr = newval;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002051end:
2052 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002053 return retval;
2054}
2055
2056
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002057/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002058 * GetWindowLong16 (USER.135)
2059 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002060LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002061{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002062 return WIN_GetWindowLong( (HWND)hwnd, offset, WIN_PROC_16 );
Alexandre Julliard3051b641996-07-05 17:14:13 +00002063}
2064
2065
2066/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002067 * GetWindowLong32A (USER32.305)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002068 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002069LONG WINAPI GetWindowLongA( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002070{
2071 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
2072}
2073
2074
2075/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002076 * GetWindowLong32W (USER32.306)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002077 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002078LONG WINAPI GetWindowLongW( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002079{
2080 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
2081}
2082
2083
2084/**********************************************************************
2085 * SetWindowLong16 (USER.136)
2086 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002087LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002088{
2089 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
2090}
2091
2092
2093/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002094 * SetWindowLong32A (USER32.517)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002095 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002096LONG WINAPI SetWindowLongA( HWND hwnd, INT offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002097{
2098 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
2099}
2100
2101
2102/**********************************************************************
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002103 * SetWindowLong32W (USER32.518) Set window attribute
2104 *
2105 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
2106 * value in a window's extra memory.
2107 *
2108 * The _hwnd_ parameter specifies the window. is the handle to a
2109 * window that has extra memory. The _newval_ parameter contains the
2110 * new attribute or extra memory value. If positive, the _offset_
2111 * parameter is the byte-addressed location in the window's extra
2112 * memory to set. If negative, _offset_ specifies the window
2113 * attribute to set, and should be one of the following values:
2114 *
2115 * GWL_EXSTYLE The window's extended window style
2116 *
2117 * GWL_STYLE The window's window style.
2118 *
2119 * GWL_WNDPROC Pointer to the window's window procedure.
2120 *
2121 * GWL_HINSTANCE The window's pplication instance handle.
2122 *
2123 * GWL_ID The window's identifier.
2124 *
2125 * GWL_USERDATA The window's user-specified data.
2126 *
2127 * If the window is a dialog box, the _offset_ parameter can be one of
2128 * the following values:
2129 *
2130 * DWL_DLGPROC The address of the window's dialog box procedure.
2131 *
2132 * DWL_MSGRESULT The return value of a message
2133 * that the dialog box procedure processed.
2134 *
2135 * DWL_USER Application specific information.
2136 *
2137 * RETURNS
2138 *
2139 * If successful, returns the previous value located at _offset_. Otherwise,
2140 * returns 0.
2141 *
2142 * NOTES
2143 *
2144 * Extra memory for a window class is specified by a nonzero cbWndExtra
2145 * parameter of the WNDCLASS structure passed to RegisterClass() at the
2146 * time of class creation.
2147 *
2148 * Using GWL_WNDPROC to set a new window procedure effectively creates
2149 * a window subclass. Use CallWindowProc() in the new windows procedure
2150 * to pass messages to the superclass's window procedure.
2151 *
2152 * The user data is reserved for use by the application which created
2153 * the window.
2154 *
2155 * Do not use GWL_STYLE to change the window's WS_DISABLE style;
2156 * instead, call the EnableWindow() function to change the window's
2157 * disabled state.
2158 *
2159 * Do not use GWL_HWNDPARENT to reset the window's parent, use
2160 * SetParent() instead.
2161 *
Alexandre Julliard638f1691999-01-17 16:32:32 +00002162 * Win95:
2163 * When offset is GWL_STYLE and the calling app's ver is 4.0,
2164 * it sends WM_STYLECHANGING before changing the settings
2165 * and WM_STYLECHANGED afterwards.
2166 * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
2167 *
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002168 * BUGS
2169 *
Alexandre Julliard638f1691999-01-17 16:32:32 +00002170 * GWL_STYLE does not dispatch WM_STYLE... messages.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002171 *
2172 * CONFORMANCE
2173 *
2174 * ECMA-234, Win32
2175 *
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002176 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002177LONG WINAPI SetWindowLongW(
2178 HWND hwnd, /* window to alter */
2179 INT offset, /* offset, in bytes, of location to alter */
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002180 LONG newval /* new value of location */
2181) {
Alexandre Julliard3051b641996-07-05 17:14:13 +00002182 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002183}
2184
2185
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002186/*******************************************************************
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002187 * GetWindowText16 (USER.36)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002188 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002189INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002190{
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002191 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
Alexandre Julliard0e607781993-11-03 19:23:37 +00002192}
2193
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002194
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002195/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002196 * GetWindowText32A (USER32.309)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002197 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002198INT WINAPI GetWindowTextA( HWND hwnd, LPSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002199{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002200 return (INT)SendMessageA( hwnd, WM_GETTEXT, nMaxCount,
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002201 (LPARAM)lpString );
2202}
2203
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002204/*******************************************************************
2205 * InternalGetWindowText (USER32.326)
2206 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002207INT WINAPI InternalGetWindowText(HWND hwnd,LPWSTR lpString,INT nMaxCount )
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002208{
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002209 FIXME("(0x%08x,%p,0x%x),stub!\n",hwnd,lpString,nMaxCount);
Alexandre Julliarda3960291999-02-26 11:11:13 +00002210 return GetWindowTextW(hwnd,lpString,nMaxCount);
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002211}
2212
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002213
2214/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002215 * GetWindowText32W (USER32.312)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002216 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002217INT WINAPI GetWindowTextW( HWND hwnd, LPWSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002218{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002219 return (INT)SendMessageW( hwnd, WM_GETTEXT, nMaxCount,
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002220 (LPARAM)lpString );
2221}
2222
2223
2224/*******************************************************************
2225 * SetWindowText16 (USER.37)
2226 */
Paul Quinn1beaae51998-12-15 15:38:36 +00002227BOOL16 WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002228{
Paul Quinn1beaae51998-12-15 15:38:36 +00002229 return (BOOL16)SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002230}
2231
2232
2233/*******************************************************************
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002234 * SetWindowText32A (USER32.521)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002235 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002236BOOL WINAPI SetWindowTextA( HWND hwnd, LPCSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002237{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002238 return (BOOL)SendMessageA( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002239}
2240
2241
2242/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002243 * SetWindowText32W (USER32.523)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002244 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002245BOOL WINAPI SetWindowTextW( HWND hwnd, LPCWSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002246{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002247 return (BOOL)SendMessageW( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002248}
2249
2250
Alexandre Julliard0e607781993-11-03 19:23:37 +00002251/*******************************************************************
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002252 * GetWindowTextLength16 (USER.38)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002253 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002254INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002255{
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002256 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002257}
2258
2259
Alexandre Julliard0e607781993-11-03 19:23:37 +00002260/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002261 * GetWindowTextLength32A (USER32.310)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002262 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002263INT WINAPI GetWindowTextLengthA( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002264{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002265 return SendMessageA( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002266}
2267
2268/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002269 * GetWindowTextLength32W (USER32.311)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002270 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002271INT WINAPI GetWindowTextLengthW( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002272{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002273 return SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002274}
2275
Alexandre Julliard21979011997-03-05 08:22:35 +00002276
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002277/*******************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00002278 * IsWindow16 (USER.47)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002279 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002280BOOL16 WINAPI IsWindow16( HWND16 hwnd )
Alexandre Julliard21979011997-03-05 08:22:35 +00002281{
Alexandre Julliard4220b291999-07-11 17:20:01 +00002282 CURRENT_STACK16->es = USER_HeapSel;
Alexandre Julliarda3960291999-02-26 11:11:13 +00002283 return IsWindow( hwnd );
Alexandre Julliard21979011997-03-05 08:22:35 +00002284}
2285
2286
2287/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002288 * IsWindow32 (USER32.348)
Alexandre Julliard21979011997-03-05 08:22:35 +00002289 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002290BOOL WINAPI IsWindow( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002291{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002292 WND * wndPtr;
2293 BOOL retvalue;
2294
2295 if(!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
2296 retvalue = (wndPtr->dwMagic == WND_MAGIC);
2297 WIN_ReleaseWndPtr(wndPtr);
2298 return retvalue;
2299
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002300}
2301
2302
2303/*****************************************************************
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002304 * GetParent16 (USER.46)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002305 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002306HWND16 WINAPI GetParent16( HWND16 hwnd )
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002307{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002308 return (HWND16)GetParent( hwnd );
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002309}
2310
2311
2312/*****************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002313 * GetParent32 (USER32.278)
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002314 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002315HWND WINAPI GetParent( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002316{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002317 WND *wndPtr;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002318 HWND retvalue = 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002319
2320 if(!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
2321 if ((!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD))))
Andreas Mohr1c20b392000-02-20 19:17:35 +00002322 goto end;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002323
Andreas Mohr1c20b392000-02-20 19:17:35 +00002324 WIN_UpdateWndPtr(&wndPtr,((wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner));
2325 if (wndPtr)
2326 retvalue = wndPtr->hwndSelf;
2327
2328end:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002329 WIN_ReleaseWndPtr(wndPtr);
2330 return retvalue;
2331
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002332}
2333
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002334/*****************************************************************
2335 * WIN_GetTopParent
2336 *
2337 * Get the top-level parent for a child window.
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002338 * returns a locked pointer
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002339 */
2340WND* WIN_GetTopParentPtr( WND* pWnd )
2341{
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002342 WND *tmpWnd = WIN_LockWndPtr(pWnd);
2343
2344 while( tmpWnd && (tmpWnd->dwStyle & WS_CHILD))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002345 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002346 WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002347 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002348 return tmpWnd;
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002349}
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002350
2351/*****************************************************************
2352 * WIN_GetTopParent
2353 *
2354 * Get the top-level parent for a child window.
2355 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002356HWND WIN_GetTopParent( HWND hwnd )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002357{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002358 HWND retvalue;
2359 WND *tmpPtr = WIN_FindWndPtr(hwnd);
2360 WND *wndPtr = WIN_GetTopParentPtr (tmpPtr );
2361
2362 retvalue = wndPtr ? wndPtr->hwndSelf : 0;
2363 WIN_ReleaseWndPtr(tmpPtr);
2364 WIN_ReleaseWndPtr(wndPtr);
2365 return retvalue;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002366}
2367
2368
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002369/*****************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002370 * SetParent16 (USER.233)
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002371 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002372HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002373{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002374 return SetParent( hwndChild, hwndNewParent );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002375}
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002376
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002377
2378/*****************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002379 * SetParent32 (USER32.495)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002380 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002381HWND WINAPI SetParent( HWND hwndChild, HWND hwndNewParent )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002382{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002383 WND *wndPtr;
2384 DWORD dwStyle;
2385 WND *pWndNewParent;
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002386 WND *pWndOldParent;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002387 HWND retvalue;
2388
2389
2390 if(!(wndPtr = WIN_FindWndPtr(hwndChild))) return 0;
2391
2392 dwStyle = wndPtr->dwStyle;
2393
2394 pWndNewParent = hwndNewParent ? WIN_FindWndPtr(hwndNewParent)
2395 : WIN_LockWndPtr(pWndDesktop);
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002396
2397 /* Windows hides the window first, then shows it again
2398 * including the WM_SHOWWINDOW messages and all */
2399 if (dwStyle & WS_VISIBLE)
Alexandre Julliarda3960291999-02-26 11:11:13 +00002400 ShowWindow( hwndChild, SW_HIDE );
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002401
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002402 pWndOldParent = WIN_LockWndPtr((*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent));
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002403
Noel Borthwick463eb291999-01-20 13:50:13 +00002404 /* SetParent32 additionally needs to make hwndChild the topmost window
2405 in the x-order and send the expected WM_WINDOWPOSCHANGING and
2406 WM_WINDOWPOSCHANGED notification messages.
2407 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002408 SetWindowPos( hwndChild, HWND_TOPMOST, 0, 0, 0, 0,
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002409 SWP_NOMOVE|SWP_NOSIZE|((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
2410 /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
2411 * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
2412
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002413 retvalue = pWndOldParent?pWndOldParent->hwndSelf:0;
2414
2415 WIN_ReleaseWndPtr(pWndOldParent);
2416 WIN_ReleaseWndPtr(pWndNewParent);
2417 WIN_ReleaseWndPtr(wndPtr);
2418
2419 return retvalue;
2420
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002421}
2422
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002423/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002424 * IsChild16 (USER.48)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002425 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002426BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002427{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002428 return IsChild(parent,child);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002429}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002430
2431
Alexandre Julliard01d63461997-01-20 19:43:45 +00002432/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002433 * IsChild32 (USER32.339)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002434 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002435BOOL WINAPI IsChild( HWND parent, HWND child )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002436{
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002437 WND * wndPtr = WIN_FindWndPtr( child );
2438 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
Alexandre Julliard0e607781993-11-03 19:23:37 +00002439 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002440 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
2441 if (wndPtr->hwndSelf == parent)
Andreas Mohr1c20b392000-02-20 19:17:35 +00002442 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002443 WIN_ReleaseWndPtr(wndPtr);
2444 return TRUE;
2445 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002446 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002447 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard0e607781993-11-03 19:23:37 +00002448 return FALSE;
2449}
2450
2451
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002452/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002453 * IsWindowVisible16 (USER.49)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002454 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002455BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002456{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002457 return IsWindowVisible(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002458}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002459
2460
Alexandre Julliard01d63461997-01-20 19:43:45 +00002461/***********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002462 * IsWindowVisible32 (USER32.351)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002463 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002464BOOL WINAPI IsWindowVisible( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002465{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002466 BOOL retval;
Alexandre Julliardded30381995-07-06 17:18:27 +00002467 WND *wndPtr = WIN_FindWndPtr( hwnd );
2468 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
2469 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002470 if (!(wndPtr->dwStyle & WS_VISIBLE))
2471 {
2472 WIN_ReleaseWndPtr(wndPtr);
2473 return FALSE;
2474 }
2475 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
Alexandre Julliardded30381995-07-06 17:18:27 +00002476 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002477 retval = (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
2478 WIN_ReleaseWndPtr(wndPtr);
2479 return retval;
2480
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002481}
2482
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002483
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002484/***********************************************************************
2485 * WIN_IsWindowDrawable
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002486 *
2487 * hwnd is drawable when it is visible, all parents are not
2488 * minimized, and it is itself not minimized unless we are
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002489 * trying to draw its default class icon.
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002490 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002491BOOL WIN_IsWindowDrawable( WND* wnd, BOOL icon )
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002492{
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002493 if( (wnd->dwStyle & WS_MINIMIZE &&
2494 icon && wnd->class->hIcon) ||
2495 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
2496 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
2497 if( wnd->dwStyle & WS_MINIMIZE ||
2498 !(wnd->dwStyle & WS_VISIBLE) ) break;
2499 return (wnd == NULL);
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002500}
2501
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002502
Alexandre Julliard0e607781993-11-03 19:23:37 +00002503/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002504 * GetTopWindow16 (USER.229)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002505 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002506HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002507{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002508 return GetTopWindow(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002509}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002510
2511
Alexandre Julliard01d63461997-01-20 19:43:45 +00002512/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002513 * GetTopWindow32 (USER.229)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002514 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002515HWND WINAPI GetTopWindow( HWND hwnd )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002516{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002517 HWND retval = 0;
2518 WND * wndPtr = (hwnd) ?
2519 WIN_FindWndPtr( hwnd ) : WIN_GetDesktop();
Francis Beaudetb7e8e801999-05-22 10:46:30 +00002520
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002521 if (wndPtr && wndPtr->child)
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002522 retval = wndPtr->child->hwndSelf;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002523
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002524 WIN_ReleaseWndPtr(wndPtr);
2525 return retval;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002526}
2527
2528
2529/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002530 * GetWindow16 (USER.262)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002531 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002532HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002533{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002534 return GetWindow( hwnd,rel );
Alexandre Julliard01d63461997-01-20 19:43:45 +00002535}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002536
2537
Alexandre Julliard01d63461997-01-20 19:43:45 +00002538/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002539 * GetWindow32 (USER32.302)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002540 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002541HWND WINAPI GetWindow( HWND hwnd, WORD rel )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002542{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002543 HWND retval;
2544
Alexandre Julliard0e607781993-11-03 19:23:37 +00002545 WND * wndPtr = WIN_FindWndPtr( hwnd );
2546 if (!wndPtr) return 0;
2547 switch(rel)
2548 {
2549 case GW_HWNDFIRST:
Andreas Mohr1c20b392000-02-20 19:17:35 +00002550 retval = wndPtr->parent ? wndPtr->parent->child->hwndSelf : 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002551 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002552
2553 case GW_HWNDLAST:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002554 if (!wndPtr->parent)
2555 {
2556 retval = 0; /* Desktop window */
2557 goto end;
2558 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002559 while (wndPtr->next)
2560 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002561 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002562 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002563 retval = wndPtr->hwndSelf;
2564 goto end;
2565
2566 case GW_HWNDNEXT:
Andreas Mohr1c20b392000-02-20 19:17:35 +00002567 retval = wndPtr->next ? wndPtr->next->hwndSelf : 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002568 goto end;
2569
2570 case GW_HWNDPREV:
2571 if (!wndPtr->parent)
2572 {
2573 retval = 0; /* Desktop window */
2574 goto end;
2575 }
2576 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent->child); /* First sibling */
2577 if (wndPtr->hwndSelf == hwnd)
2578 {
2579 retval = 0; /* First in list */
2580 goto end;
2581 }
2582 while (wndPtr->next)
2583 {
2584 if (wndPtr->next->hwndSelf == hwnd)
Andreas Mohr1c20b392000-02-20 19:17:35 +00002585 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002586 retval = wndPtr->hwndSelf;
2587 goto end;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002588 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002589 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
2590 }
2591 retval = 0;
2592 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002593
2594 case GW_OWNER:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002595 retval = wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
2596 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002597
2598 case GW_CHILD:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002599 retval = wndPtr->child ? wndPtr->child->hwndSelf : 0;
2600 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002601 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002602 retval = 0;
2603end:
2604 WIN_ReleaseWndPtr(wndPtr);
2605 return retval;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002606}
2607
2608
2609/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002610 * GetNextWindow16 (USER.230)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002611 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002612HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002613{
2614 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
Alexandre Julliard01d63461997-01-20 19:43:45 +00002615 return GetWindow16( hwnd, flag );
Alexandre Julliard0e607781993-11-03 19:23:37 +00002616}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002617
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002618/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002619 * ShowOwnedPopups16 (USER.265)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002620 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002621void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002622{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002623 ShowOwnedPopups( owner, fShow );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002624}
2625
2626
2627/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002628 * ShowOwnedPopups32 (USER32.531)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002629 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002630BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL fShow )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002631{
Noomen Hamzaa018d851999-09-28 16:26:09 +00002632 UINT totalChild=0, count=0;
2633
2634 WND **pWnd = WIN_BuildWinArray(WIN_GetDesktop(), 0, &totalChild);
2635
2636 if (!pWnd) return TRUE;
2637
2638 for (; count < totalChild; count++)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002639 {
Noomen Hamzaa018d851999-09-28 16:26:09 +00002640 if (pWnd[count]->owner && (pWnd[count]->owner->hwndSelf == owner) && (pWnd[count]->dwStyle & WS_POPUP))
Noomen Hamzaff727762000-02-18 19:11:04 +00002641 {
2642 if (fShow)
2643 {
2644 if (pWnd[count]->flags & WIN_NEEDS_SHOW_OWNEDPOPUP)
2645 {
2646 SendMessageA(pWnd[count]->hwndSelf, WM_SHOWWINDOW, SW_SHOW, IsIconic(owner) ? SW_PARENTOPENING : SW_PARENTCLOSING);
2647 pWnd[count]->flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
2648 }
2649 }
2650 else
2651 {
2652 if (IsWindowVisible(pWnd[count]->hwndSelf))
2653 {
2654 SendMessageA(pWnd[count]->hwndSelf, WM_SHOWWINDOW, SW_HIDE, IsIconic(owner) ? SW_PARENTOPENING : SW_PARENTCLOSING);
2655 pWnd[count]->flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
2656 }
2657 }
2658 }
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002659 }
Noomen Hamzaa018d851999-09-28 16:26:09 +00002660
2661 WIN_ReleaseDesktop();
2662 WIN_ReleaseWinArray(pWnd);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002663 return TRUE;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002664}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002665
2666
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002667/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002668 * GetLastActivePopup16 (USER.287)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002669 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002670HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002671{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002672 return GetLastActivePopup( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002673}
2674
2675/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002676 * GetLastActivePopup32 (USER32.256)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002677 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002678HWND WINAPI GetLastActivePopup( HWND hwnd )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002679{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002680 HWND retval;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002681 WND *wndPtr =WIN_FindWndPtr(hwnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002682 if (!wndPtr) return hwnd;
2683 retval = wndPtr->hwndLastActive;
2684 WIN_ReleaseWndPtr(wndPtr);
2685 return retval;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002686}
2687
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002688
2689/*******************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002690 * WIN_BuildWinArray
2691 *
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002692 * Build an array of pointers to the children of a given window.
Alexandre Julliard90476d62000-02-16 22:47:24 +00002693 * The array must be freed with WIN_ReleaseWinArray. Return NULL
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002694 * when no windows are found.
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002695 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002696WND **WIN_BuildWinArray( WND *wndPtr, UINT bwaFlags, UINT* pTotal )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002697{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002698 /* Future: this function will lock all windows associated with this array */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002699
Alexandre Julliard3051b641996-07-05 17:14:13 +00002700 WND **list, **ppWnd;
2701 WND *pWnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002702 UINT count = 0, skipOwned, skipHidden;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002703 DWORD skipFlags;
2704
2705 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2706 skipOwned = bwaFlags & BWA_SKIPOWNED;
2707 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2708 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002709
2710 /* First count the windows */
2711
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002712 if (!wndPtr)
2713 wndPtr = WIN_GetDesktop();
2714
2715 pWnd = WIN_LockWndPtr(wndPtr->child);
2716 while (pWnd)
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002717 {
Alex Korobka44a1b591999-04-01 12:03:52 +00002718 if( !(pWnd->dwStyle & skipFlags) && !(skipOwned && pWnd->owner) &&
2719 (!skipHidden || (pWnd->dwStyle & WS_VISIBLE)) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002720 count++;
Alex Korobka44a1b591999-04-01 12:03:52 +00002721 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002722 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002723
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002724 if( count )
2725 {
2726 /* Now build the list of all windows */
Alexandre Julliard3051b641996-07-05 17:14:13 +00002727
Alexandre Julliard90476d62000-02-16 22:47:24 +00002728 if ((list = (WND **)HeapAlloc( GetProcessHeap(), 0, sizeof(WND *) * (count + 1))))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002729 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002730 for (pWnd = WIN_LockWndPtr(wndPtr->child), ppWnd = list, count = 0; pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002731 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002732 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) );
2733 else if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002734 {
2735 *ppWnd++ = pWnd;
2736 count++;
2737 }
2738 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002739 WIN_ReleaseWndPtr(pWnd);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002740 *ppWnd = NULL;
2741 }
2742 else count = 0;
2743 } else list = NULL;
2744
2745 if( pTotal ) *pTotal = count;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002746 return list;
2747}
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002748/*******************************************************************
2749 * WIN_ReleaseWinArray
2750 */
2751void WIN_ReleaseWinArray(WND **wndArray)
2752{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002753 /* Future: this function will also unlock all windows associated with wndArray */
Alexandre Julliard90476d62000-02-16 22:47:24 +00002754 HeapFree( GetProcessHeap(), 0, wndArray );
Alexandre Julliard3051b641996-07-05 17:14:13 +00002755
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002756}
Alexandre Julliard3051b641996-07-05 17:14:13 +00002757
2758/*******************************************************************
2759 * EnumWindows16 (USER.54)
2760 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002761BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002762{
2763 WND **list, **ppWnd;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002764
Alexandre Julliard594997c1995-04-30 10:05:20 +00002765 /* We have to build a list of all windows first, to avoid */
Andreas Mohr1c20b392000-02-20 19:17:35 +00002766 /* unpleasant side-effects, for instance if the callback */
2767 /* function changes the Z-order of the windows. */
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002768
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002769 if (!(list = WIN_BuildWinArray(WIN_GetDesktop(), 0, NULL )))
2770 {
2771 WIN_ReleaseDesktop();
2772 return FALSE;
2773 }
Alexandre Julliard594997c1995-04-30 10:05:20 +00002774
Alexandre Julliard3051b641996-07-05 17:14:13 +00002775 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002776
Alexandre Julliard3051b641996-07-05 17:14:13 +00002777 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002778 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002779 LRESULT lpEnumFuncRetval;
2780 int iWndsLocks = 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002781 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002782 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Francois Boisvertd96bc151999-04-02 10:34:43 +00002783
2784 /* To avoid any deadlocks, all the locks on the windows
2785 structures must be suspended before the control
2786 is passed to the application */
2787 iWndsLocks = WIN_SuspendWndsLock();
2788 lpEnumFuncRetval = lpEnumFunc( (*ppWnd)->hwndSelf, lParam);
2789 WIN_RestoreWndsLock(iWndsLocks);
2790
2791 if (!lpEnumFuncRetval) break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002792 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002793 WIN_ReleaseWinArray(list);
2794 WIN_ReleaseDesktop();
Alexandre Julliard3051b641996-07-05 17:14:13 +00002795 return TRUE;
2796}
2797
2798
2799/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002800 * EnumWindows32 (USER32.193)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002801 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002802BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002803{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002804 return (BOOL)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002805}
2806
Alexandre Julliard594997c1995-04-30 10:05:20 +00002807
2808/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002809 * EnumTaskWindows16 (USER.225)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002810 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002811BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2812 LPARAM lParam )
Alexandre Julliard594997c1995-04-30 10:05:20 +00002813{
Alexandre Julliard3051b641996-07-05 17:14:13 +00002814 WND **list, **ppWnd;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002815
2816 /* This function is the same as EnumWindows(), */
Per Ångströma47bc3a1998-11-14 17:00:37 +00002817 /* except for an added check on the window's task. */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002818
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002819 if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
2820 {
2821 WIN_ReleaseDesktop();
2822 return FALSE;
2823 }
Alexandre Julliard594997c1995-04-30 10:05:20 +00002824
Alexandre Julliard3051b641996-07-05 17:14:13 +00002825 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002826
Alexandre Julliard3051b641996-07-05 17:14:13 +00002827 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002828 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002829 LRESULT funcRetval;
2830 int iWndsLocks = 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002831 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002832 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Per Ångströma47bc3a1998-11-14 17:00:37 +00002833 if (QUEUE_GetQueueTask((*ppWnd)->hmemTaskQ) != hTask) continue;
Francois Boisvertd96bc151999-04-02 10:34:43 +00002834
2835 /* To avoid any deadlocks, all the locks on the windows
2836 structures must be suspended before the control
2837 is passed to the application */
2838 iWndsLocks = WIN_SuspendWndsLock();
2839 funcRetval = func( (*ppWnd)->hwndSelf, lParam );
2840 WIN_RestoreWndsLock(iWndsLocks);
2841
2842 if (!funcRetval) break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002843 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002844 WIN_ReleaseWinArray(list);
2845 WIN_ReleaseDesktop();
Alexandre Julliard594997c1995-04-30 10:05:20 +00002846 return TRUE;
2847}
2848
2849
Alexandre Julliard3051b641996-07-05 17:14:13 +00002850/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002851 * EnumThreadWindows (USER32.190)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002852 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002853BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002854{
Alexandre Julliard0a860a01999-06-22 11:43:42 +00002855 TEB *teb = THREAD_IdToTEB(id);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002856
Alexandre Julliard0a860a01999-06-22 11:43:42 +00002857 return (BOOL16)EnumTaskWindows16(teb->htask16, (WNDENUMPROC16)func, lParam);
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002858}
2859
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002860
Alexandre Julliard3051b641996-07-05 17:14:13 +00002861/**********************************************************************
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002862 * WIN_EnumChildWindows
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002863 *
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002864 * Helper function for EnumChildWindows().
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002865 */
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002866static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2867 LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002868{
Alexandre Julliard3051b641996-07-05 17:14:13 +00002869 WND **childList;
2870 BOOL16 ret = FALSE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002871
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002872 for ( ; *ppWnd; ppWnd++)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002873 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002874 int iWndsLocks = 0;
2875
Alexandre Julliard3051b641996-07-05 17:14:13 +00002876 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002877 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002878 /* Build children list first */
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002879 childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
Francois Boisvertd96bc151999-04-02 10:34:43 +00002880
2881 /* To avoid any deadlocks, all the locks on the windows
2882 structures must be suspended before the control
2883 is passed to the application */
2884 iWndsLocks = WIN_SuspendWndsLock();
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002885 ret = func( (*ppWnd)->hwndSelf, lParam );
Francois Boisvertd96bc151999-04-02 10:34:43 +00002886 WIN_RestoreWndsLock(iWndsLocks);
2887
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002888 if (childList)
2889 {
2890 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002891 WIN_ReleaseWinArray(childList);
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002892 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002893 if (!ret) return FALSE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002894 }
2895 return TRUE;
2896}
2897
2898
2899/**********************************************************************
2900 * EnumChildWindows16 (USER.55)
2901 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002902BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2903 LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002904{
2905 WND **list, *pParent;
2906
2907 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002908 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL )))
2909 {
2910 WIN_ReleaseWndPtr(pParent);
2911 return FALSE;
2912 }
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002913 WIN_EnumChildWindows( list, func, lParam );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002914 WIN_ReleaseWinArray(list);
2915 WIN_ReleaseWndPtr(pParent);
Alexandre Julliard3051b641996-07-05 17:14:13 +00002916 return TRUE;
2917}
2918
2919
2920/**********************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002921 * EnumChildWindows32 (USER32.178)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002922 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002923BOOL WINAPI EnumChildWindows( HWND parent, WNDENUMPROC func,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002924 LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002925{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002926 return (BOOL)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002927 lParam );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002928}
2929
Alexandre Julliard594997c1995-04-30 10:05:20 +00002930
Alexandre Julliard58199531994-04-21 01:20:00 +00002931/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002932 * AnyPopup16 (USER.52)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002933 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002934BOOL16 WINAPI AnyPopup16(void)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002935{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002936 return AnyPopup();
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002937}
2938
2939
2940/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002941 * AnyPopup32 (USER32.4)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002942 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002943BOOL WINAPI AnyPopup(void)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002944{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002945 WND *wndPtr = WIN_LockWndPtr(pWndDesktop->child);
2946 BOOL retvalue;
2947
2948 while (wndPtr)
2949 {
2950 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE))
2951 {
2952 retvalue = TRUE;
2953 goto end;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002954 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002955 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
2956 }
2957 retvalue = FALSE;
2958end:
2959 WIN_ReleaseWndPtr(wndPtr);
2960 return retvalue;
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002961}
2962
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002963
Alexandre Julliard73450d61994-05-18 18:29:32 +00002964/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002965 * FlashWindow16 (USER.105)
Alexandre Julliard73450d61994-05-18 18:29:32 +00002966 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002967BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002968{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002969 return FlashWindow( hWnd, bInvert );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002970}
2971
2972
2973/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00002974 * FlashWindow32 (USER32.202)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002975 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002976BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert )
Alexandre Julliard73450d61994-05-18 18:29:32 +00002977{
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002978 WND *wndPtr = WIN_FindWndPtr(hWnd);
2979
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002980 TRACE("%04x\n", hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002981
2982 if (!wndPtr) return FALSE;
2983
2984 if (wndPtr->dwStyle & WS_MINIMIZE)
2985 {
2986 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2987 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002988 HDC hDC = GetDC(hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002989
Alexandre Julliard530ee841996-10-23 16:59:13 +00002990 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002991 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2992
Alexandre Julliarda3960291999-02-26 11:11:13 +00002993 ReleaseDC( hWnd, hDC );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002994 wndPtr->flags |= WIN_NCACTIVATED;
2995 }
2996 else
2997 {
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002998 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2999 RDW_UPDATENOW | RDW_FRAME, 0 );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003000 wndPtr->flags &= ~WIN_NCACTIVATED;
3001 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003002 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003003 return TRUE;
3004 }
3005 else
3006 {
Alexandre Julliard530ee841996-10-23 16:59:13 +00003007 WPARAM16 wparam;
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003008 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
Alexandre Julliarda3960291999-02-26 11:11:13 +00003009 else wparam = (hWnd == GetActiveWindow());
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003010
Alexandre Julliard2d93d001996-05-21 15:01:41 +00003011 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003012 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003013 return wparam;
3014 }
Alexandre Julliard73450d61994-05-18 18:29:32 +00003015}
3016
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003017
3018/*******************************************************************
Alexandre Julliard18f92e71996-07-17 20:02:21 +00003019 * SetSysModalWindow16 (USER.188)
Alexandre Julliard58199531994-04-21 01:20:00 +00003020 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003021HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
Alexandre Julliard58199531994-04-21 01:20:00 +00003022{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003023 HWND hWndOldModal = hwndSysModal;
Alexandre Julliardd4719651995-12-12 18:49:11 +00003024 hwndSysModal = hWnd;
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00003025 FIXME("EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
Alexandre Julliardd4719651995-12-12 18:49:11 +00003026 return hWndOldModal;
Alexandre Julliard58199531994-04-21 01:20:00 +00003027}
3028
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003029
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003030/*******************************************************************
Alexandre Julliard18f92e71996-07-17 20:02:21 +00003031 * GetSysModalWindow16 (USER.52)
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003032 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003033HWND16 WINAPI GetSysModalWindow16(void)
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003034{
Alexandre Julliardd4719651995-12-12 18:49:11 +00003035 return hwndSysModal;
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003036}
Alexandre Julliardade697e1995-11-26 13:59:11 +00003037
Alexandre Julliard18f92e71996-07-17 20:02:21 +00003038
Alexandre Julliardade697e1995-11-26 13:59:11 +00003039/*******************************************************************
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003040 * GetWindowContextHelpId (USER32.303)
3041 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003042DWORD WINAPI GetWindowContextHelpId( HWND hwnd )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003043{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003044 DWORD retval;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003045 WND *wnd = WIN_FindWndPtr( hwnd );
3046 if (!wnd) return 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003047 retval = wnd->helpContext;
3048 WIN_ReleaseWndPtr(wnd);
3049 return retval;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003050}
3051
3052
3053/*******************************************************************
3054 * SetWindowContextHelpId (USER32.515)
3055 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003056BOOL WINAPI SetWindowContextHelpId( HWND hwnd, DWORD id )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003057{
3058 WND *wnd = WIN_FindWndPtr( hwnd );
3059 if (!wnd) return FALSE;
3060 wnd->helpContext = id;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003061 WIN_ReleaseWndPtr(wnd);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003062 return TRUE;
3063}
3064
3065
3066/*******************************************************************
Alexandre Julliardade697e1995-11-26 13:59:11 +00003067 * DRAG_QueryUpdate
3068 *
3069 * recursively find a child that contains spDragInfo->pt point
3070 * and send WM_QUERYDROPOBJECT
3071 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003072BOOL16 DRAG_QueryUpdate( HWND hQueryWnd, SEGPTR spDragInfo, BOOL bNoSend )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003073{
Andreas Mohr1c20b392000-02-20 19:17:35 +00003074 BOOL16 wParam, bResult = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003075 POINT pt;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003076 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
3077 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003078 RECT tempRect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003079
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003080 if( !ptrQueryWnd || !ptrDragInfo )
Andreas Mohr1c20b392000-02-20 19:17:35 +00003081 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003082
Alexandre Julliardd37eb361997-07-20 16:23:21 +00003083 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003084
Alexandre Julliarda3960291999-02-26 11:11:13 +00003085 GetWindowRect(hQueryWnd,&tempRect);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003086
Alexandre Julliarda3960291999-02-26 11:11:13 +00003087 if( !PtInRect(&tempRect,pt) ||
Alexandre Julliardade697e1995-11-26 13:59:11 +00003088 (ptrQueryWnd->dwStyle & WS_DISABLED) )
Andreas Mohr1c20b392000-02-20 19:17:35 +00003089 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003090
3091 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
3092 {
3093 tempRect = ptrQueryWnd->rectClient;
3094 if(ptrQueryWnd->dwStyle & WS_CHILD)
Alexandre Julliarda3960291999-02-26 11:11:13 +00003095 MapWindowPoints( ptrQueryWnd->parent->hwndSelf, 0,
3096 (LPPOINT)&tempRect, 2 );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003097
Alexandre Julliarda3960291999-02-26 11:11:13 +00003098 if (PtInRect( &tempRect, pt))
Alexandre Julliardade697e1995-11-26 13:59:11 +00003099 {
3100 wParam = 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003101
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003102 for (ptrWnd = WIN_LockWndPtr(ptrQueryWnd->child); ptrWnd ;WIN_UpdateWndPtr(&ptrWnd,ptrWnd->next))
3103 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003104 if( ptrWnd->dwStyle & WS_VISIBLE )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003105 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003106 GetWindowRect( ptrWnd->hwndSelf, &tempRect );
3107 if (PtInRect( &tempRect, pt )) break;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003108 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003109 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003110
3111 if(ptrWnd)
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003112 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +00003113 TRACE_(msg)("hwnd = %04x, %d %d - %d %d\n",
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003114 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
3115 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
3116 if( !(ptrWnd->dwStyle & WS_DISABLED) )
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003117 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003118
3119 WIN_ReleaseWndPtr(ptrWnd);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003120 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003121
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003122 if(bResult)
Andreas Mohr1c20b392000-02-20 19:17:35 +00003123 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003124 }
3125 else wParam = 1;
3126 }
3127 else wParam = 1;
3128
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00003129 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003130
3131 ptrDragInfo->hScope = hQueryWnd;
3132
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003133 bResult = ( bNoSend )
3134 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
3135 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
Alexandre Julliard530ee841996-10-23 16:59:13 +00003136 (WPARAM16)wParam ,(LPARAM) spDragInfo );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003137 if( !bResult )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00003138 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003139
Andreas Mohr1c20b392000-02-20 19:17:35 +00003140end:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003141 WIN_ReleaseWndPtr(ptrQueryWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003142 return bResult;
3143}
3144
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003145
Alexandre Julliardade697e1995-11-26 13:59:11 +00003146/*******************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003147 * DragDetect (USER.465)
Alexandre Julliardade697e1995-11-26 13:59:11 +00003148 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003149BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003150{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003151 POINT pt32;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003152 CONV_POINT16TO32( &pt, &pt32 );
Alexandre Julliarda3960291999-02-26 11:11:13 +00003153 return DragDetect( hWnd, pt32 );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003154}
3155
3156/*******************************************************************
Alexandre Julliarda11d7b11998-03-01 20:05:02 +00003157 * DragDetect32 (USER32.151)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003158 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003159BOOL WINAPI DragDetect( HWND hWnd, POINT pt )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003160{
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003161 MSG16 msg;
3162 RECT16 rect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003163
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003164 rect.left = pt.x - wDragWidth;
3165 rect.right = pt.x + wDragWidth;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003166
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003167 rect.top = pt.y - wDragHeight;
3168 rect.bottom = pt.y + wDragHeight;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003169
Alexandre Julliarda3960291999-02-26 11:11:13 +00003170 SetCapture(hWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003171
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003172 while(1)
3173 {
3174 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
3175 {
3176 if( msg.message == WM_LBUTTONUP )
3177 {
3178 ReleaseCapture();
3179 return 0;
3180 }
3181 if( msg.message == WM_MOUSEMOVE )
3182 {
3183 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003184 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003185 ReleaseCapture();
3186 return 1;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003187 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003188 }
3189 }
3190 WaitMessage();
3191 }
3192 return 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003193}
3194
3195/******************************************************************************
Alexandre Julliard21979011997-03-05 08:22:35 +00003196 * DragObject16 (USER.464)
Alexandre Julliardade697e1995-11-26 13:59:11 +00003197 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003198DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
3199 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003200{
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003201 MSG16 msg;
3202 LPDRAGINFO lpDragInfo;
3203 SEGPTR spDragInfo;
3204 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
3205 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
3206 WND *wndPtr = WIN_FindWndPtr(hWnd);
3207 HCURSOR16 hCurrentCursor = 0;
3208 HWND16 hCurrentWnd = 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003209
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003210 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
3211 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003212
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003213 if( !lpDragInfo || !spDragInfo )
3214 {
3215 WIN_ReleaseWndPtr(wndPtr);
3216 return 0L;
3217 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003218
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003219 hBummer = LoadCursor16(0, IDC_BUMMER16);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003220
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003221 if( !hBummer || !wndPtr )
3222 {
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00003223 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003224 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003225 return 0L;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003226 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003227
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003228 if(hCursor)
3229 {
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003230 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003231 {
3232 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003233 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003234 return 0L;
3235 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003236
3237 if( hDragCursor == hCursor ) hDragCursor = 0;
3238 else hCursor = hDragCursor;
3239
Alexandre Julliarda3960291999-02-26 11:11:13 +00003240 hOldCursor = SetCursor(hDragCursor);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003241 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003242
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003243 lpDragInfo->hWnd = hWnd;
3244 lpDragInfo->hScope = 0;
3245 lpDragInfo->wFlags = wObj;
3246 lpDragInfo->hList = szList; /* near pointer! */
3247 lpDragInfo->hOfStruct = hOfStruct;
3248 lpDragInfo->l = 0L;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003249
Alexandre Julliarda3960291999-02-26 11:11:13 +00003250 SetCapture(hWnd);
3251 ShowCursor( TRUE );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003252
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003253 do
3254 {
3255 do{ WaitMessage(); }
3256 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003257
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003258 *(lpDragInfo+1) = *lpDragInfo;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003259
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003260 lpDragInfo->pt = msg.pt;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003261
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003262 /* update DRAGINFO struct */
Alexandre Julliard06c275a1999-05-02 14:32:27 +00003263 TRACE_(msg)("lpDI->hScope = %04x\n",lpDragInfo->hScope);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003264
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003265 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
3266 hCurrentCursor = hCursor;
3267 else
Alexandre Julliardade697e1995-11-26 13:59:11 +00003268 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003269 hCurrentCursor = hBummer;
3270 lpDragInfo->hScope = 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003271 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003272 if( hCurrentCursor )
Alexandre Julliarda3960291999-02-26 11:11:13 +00003273 SetCursor(hCurrentCursor);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003274
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003275 /* send WM_DRAGLOOP */
3276 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
3277 (LPARAM) spDragInfo );
3278 /* send WM_DRAGSELECT or WM_DRAGMOVE */
3279 if( hCurrentWnd != lpDragInfo->hScope )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003280 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003281 if( hCurrentWnd )
3282 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
Alexandre Julliardade697e1995-11-26 13:59:11 +00003283 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
3284 HIWORD(spDragInfo)) );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003285 hCurrentWnd = lpDragInfo->hScope;
3286 if( hCurrentWnd )
3287 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003288 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003289 else
3290 if( hCurrentWnd )
3291 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
3292
3293 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
3294
3295 ReleaseCapture();
Alexandre Julliarda3960291999-02-26 11:11:13 +00003296 ShowCursor( FALSE );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003297
3298 if( hCursor )
3299 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003300 SetCursor( hOldCursor );
3301 if (hDragCursor) DestroyCursor( hDragCursor );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003302 }
3303
3304 if( hCurrentCursor != hBummer )
3305 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
3306 (WPARAM16)hWnd, (LPARAM)spDragInfo );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003307 else
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003308 msg.lParam = 0;
3309 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003310 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003311
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003312 return (DWORD)(msg.lParam);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003313}