blob: 419397d27e9728ec6001d95d314f40babc0c8777 [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"
Marcus Meissner317af321999-02-17 13:51:06 +000010#include "wine/winbase16.h"
Michael Veksler9d14a001999-05-08 12:40:24 +000011#include "wine/winuser16.h"
Alexandre Julliardcb10fda2000-08-06 02:41:16 +000012#include "wine/unicode.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000013#include "win.h"
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000014#include "heap.h"
Alexandre Julliardf0b23541993-09-29 12:21:49 +000015#include "user.h"
Alexandre Julliard5f721f81994-01-04 20:14:34 +000016#include "dce.h"
Alexandre Julliard91222da2000-12-10 23:01:33 +000017#include "controls.h"
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000018#include "cursoricon.h"
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000019#include "hook.h"
Alexandre Julliardef702d81996-05-28 18:54:58 +000020#include "message.h"
Alexandre Julliardb817f4f1996-03-14 18:08:34 +000021#include "queue.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000022#include "winpos.h"
Alexandre Julliard767e6f61998-08-09 12:47:43 +000023#include "winerror.h"
Alexandre Julliard4220b291999-07-11 17:20:01 +000024#include "stackframe.h"
25#include "debugtools.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000026
Alexandre Julliardb8774f92000-05-30 17:50:41 +000027DEFAULT_DEBUG_CHANNEL(win);
28DECLARE_DEBUG_CHANNEL(msg);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000029
Patrik Stridvallb87fe2e1999-04-01 08:16:08 +000030/**********************************************************************/
31
Alexandre Julliard59730ae1996-03-24 16:20:51 +000032/* Desktop window */
33static WND *pWndDesktop = NULL;
34
Alexandre Julliarda3960291999-02-26 11:11:13 +000035static HWND hwndSysModal = 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +000036
Alexandre Julliardd4719651995-12-12 18:49:11 +000037static WORD wDragWidth = 4;
38static WORD wDragHeight= 3;
Alexandre Julliardade697e1995-11-26 13:59:11 +000039
Francois Boisvert93e3f901999-02-25 17:32:31 +000040/* thread safeness */
Alexandre Julliardab687972000-11-15 23:41:46 +000041static SYSLEVEL WIN_SysLevel = { CRITICAL_SECTION_INIT, 2 };
Ulrich Weigandef61c0b1999-05-08 09:45:50 +000042
43/***********************************************************************
Francois Boisvert93e3f901999-02-25 17:32:31 +000044 * WIN_LockWnds
45 *
46 * Locks access to all WND structures for thread safeness
47 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000048void WIN_LockWnds( void )
Francois Boisvert93e3f901999-02-25 17:32:31 +000049{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000050 _EnterSysLevel( &WIN_SysLevel );
Francois Boisvert93e3f901999-02-25 17:32:31 +000051}
52
53/***********************************************************************
54 * WIN_UnlockWnds
55 *
56 * Unlocks access to all WND structures
57 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000058void WIN_UnlockWnds( void )
Ove Kaavenbcb4bb61999-05-12 10:07:02 +000059{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000060 _LeaveSysLevel( &WIN_SysLevel );
Francois Boisvert93e3f901999-02-25 17:32:31 +000061}
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000062
Francois Boisvert93e3f901999-02-25 17:32:31 +000063/***********************************************************************
64 * WIN_SuspendWndsLock
65 *
66 * Suspend the lock on WND structures.
67 * Returns the number of locks suspended
68 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000069int WIN_SuspendWndsLock( void )
Francois Boisvert93e3f901999-02-25 17:32:31 +000070{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000071 int isuspendedLocks = _ConfirmSysLevel( &WIN_SysLevel );
72 int count = isuspendedLocks;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +000073
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000074 while ( count-- > 0 )
75 _LeaveSysLevel( &WIN_SysLevel );
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +000076
Francois Boisvert93e3f901999-02-25 17:32:31 +000077 return isuspendedLocks;
Francois Boisvert93e3f901999-02-25 17:32:31 +000078}
79
80/***********************************************************************
81 * WIN_RestoreWndsLock
82 *
83 * Restore the suspended locks on WND structures
84 */
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000085void WIN_RestoreWndsLock( int ipreviousLocks )
Francois Boisvert93e3f901999-02-25 17:32:31 +000086{
Ulrich Weigandc5b8b3a1999-05-22 16:28:47 +000087 while ( ipreviousLocks-- > 0 )
88 _EnterSysLevel( &WIN_SysLevel );
Francois Boisvert93e3f901999-02-25 17:32:31 +000089}
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +000090
Alexandre Julliard401710d1993-09-04 10:09:32 +000091/***********************************************************************
92 * WIN_FindWndPtr
93 *
94 * Return a pointer to the WND structure corresponding to a HWND.
Alexandre Julliard401710d1993-09-04 10:09:32 +000095 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000096WND * WIN_FindWndPtr( HWND hwnd )
Alexandre Julliard401710d1993-09-04 10:09:32 +000097{
98 WND * ptr;
99
Francois Boisvert93e3f901999-02-25 17:32:31 +0000100 if (!hwnd || HIWORD(hwnd)) goto error2;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000101 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000102 /* Lock all WND structures for thread safeness*/
103 WIN_LockWnds();
104 /*and increment destruction monitoring*/
Francois Boisvert93e3f901999-02-25 17:32:31 +0000105 ptr->irefCount++;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000106
Eric Pouechb9544f11999-02-14 14:09:42 +0000107 if (ptr->dwMagic != WND_MAGIC) goto error;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000108 if (ptr->hwndSelf != hwnd)
109 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000110 ERR("Can't happen: hwnd %04x self pointer is %04x\n",hwnd, ptr->hwndSelf );
Eric Pouechb9544f11999-02-14 14:09:42 +0000111 goto error;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000112 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000113 /* returns a locked pointer */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000114 return ptr;
Eric Pouechb9544f11999-02-14 14:09:42 +0000115 error:
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000116 /* Unlock all WND structures for thread safeness*/
117 WIN_UnlockWnds();
118 /* and decrement destruction monitoring value */
Francois Boisvert93e3f901999-02-25 17:32:31 +0000119 ptr->irefCount--;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000120
Francois Boisvert93e3f901999-02-25 17:32:31 +0000121error2:
Juergen Schmied1e0bc841999-02-28 11:08:13 +0000122 if ( hwnd!=0 )
123 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
Eric Pouechb9544f11999-02-14 14:09:42 +0000124 return NULL;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000125}
126
Francois Boisvert93e3f901999-02-25 17:32:31 +0000127/***********************************************************************
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000128 * WIN_LockWndPtr
129 *
130 * Use in case the wnd ptr is not initialized with WIN_FindWndPtr
131 * but by initWndPtr;
132 * Returns the locked initialisation pointer
133 */
134WND *WIN_LockWndPtr(WND *initWndPtr)
135{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000136 if(!initWndPtr) return 0;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000137
138 /* Lock all WND structures for thread safeness*/
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000139 WIN_LockWnds();
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000140 /*and increment destruction monitoring*/
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000141 initWndPtr->irefCount++;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000142
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000143 return initWndPtr;
144
145}
146
147/***********************************************************************
Francois Boisvert93e3f901999-02-25 17:32:31 +0000148 * WIN_ReleaseWndPtr
149 *
150 * Release the pointer to the WND structure.
151 */
152void WIN_ReleaseWndPtr(WND *wndPtr)
153{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000154 if(!wndPtr) return;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000155
156 /*Decrement destruction monitoring value*/
Francois Boisvert93e3f901999-02-25 17:32:31 +0000157 wndPtr->irefCount--;
Francois Boisvert86e2e111999-04-03 11:13:33 +0000158 /* Check if it's time to release the memory*/
159 if(wndPtr->irefCount == 0 && !wndPtr->dwMagic)
Francois Boisvert93e3f901999-02-25 17:32:31 +0000160 {
Francois Boisvert86e2e111999-04-03 11:13:33 +0000161 /* Release memory */
162 USER_HEAP_FREE( wndPtr->hwndSelf);
Francis Beaudet48126471999-05-22 19:21:01 +0000163 wndPtr->hwndSelf = 0;
Francois Boisvert93e3f901999-02-25 17:32:31 +0000164 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000165 else if(wndPtr->irefCount < 0)
166 {
167 /* This else if is useful to monitor the WIN_ReleaseWndPtr function */
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000168 ERR("forgot a Lock on %p somewhere\n",wndPtr);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000169 }
170 /*unlock all WND structures for thread safeness*/
Francois Boisvert93e3f901999-02-25 17:32:31 +0000171 WIN_UnlockWnds();
Francois Boisvert93e3f901999-02-25 17:32:31 +0000172}
173
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000174/***********************************************************************
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000175 * WIN_UpdateWndPtr
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000176 *
177 * Updates the value of oldPtr to newPtr.
178 */
179void WIN_UpdateWndPtr(WND **oldPtr, WND *newPtr)
180{
181 WND *tmpWnd = NULL;
182
183 tmpWnd = WIN_LockWndPtr(newPtr);
184 WIN_ReleaseWndPtr(*oldPtr);
185 *oldPtr = tmpWnd;
186
187}
Alexandre Julliard401710d1993-09-04 10:09:32 +0000188
189/***********************************************************************
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000190 * WIN_DumpWindow
191 *
192 * Dump the content of a window structure to stderr.
193 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000194void WIN_DumpWindow( HWND hwnd )
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000195{
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000196 WND *ptr;
197 char className[80];
198 int i;
199
200 if (!(ptr = WIN_FindWndPtr( hwnd )))
201 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000202 WARN("%04x is not a window handle\n", hwnd );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000203 return;
204 }
205
Alexandre Julliarda3960291999-02-26 11:11:13 +0000206 if (!GetClassNameA( hwnd, className, sizeof(className ) ))
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000207 strcpy( className, "#NULL#" );
208
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000209 TRACE("Window %04x (%p):\n", hwnd, ptr );
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000210 DPRINTF( "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000211 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000212 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000213 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000214 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000215 ptr->next, ptr->child, ptr->parent, ptr->owner,
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000216 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000217 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000218 ptr->dwStyle, ptr->dwExStyle, (UINT)ptr->winproc,
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +0000219 ptr->text ? debugstr_w(ptr->text) : "",
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000220 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
221 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
Alexandre Julliard23946ad1997-06-16 17:43:53 +0000222 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000223 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000224
Alexandre Julliard98779062000-12-07 23:39:16 +0000225 if (ptr->cbWndExtra)
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000226 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000227 DPRINTF( "extra bytes:" );
Alexandre Julliard98779062000-12-07 23:39:16 +0000228 for (i = 0; i < ptr->cbWndExtra; i++)
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000229 DPRINTF( " %02x", *((BYTE*)ptr->wExtra+i) );
230 DPRINTF( "\n" );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000231 }
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000232 DPRINTF( "\n" );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000233 WIN_ReleaseWndPtr(ptr);
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000234}
235
236
237/***********************************************************************
238 * WIN_WalkWindows
239 *
240 * Walk the windows tree and print each window on stderr.
241 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000242void WIN_WalkWindows( HWND hwnd, int indent )
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000243{
244 WND *ptr;
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000245 char className[80];
246
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000247 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : WIN_GetDesktop();
248
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000249 if (!ptr)
250 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000251 WARN("Invalid window handle %04x\n", hwnd );
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000252 return;
253 }
254
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000255 if (!indent) /* first time around */
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000256 DPRINTF( "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
Rein Klazesd62c62b1998-10-11 14:05:34 +0000257 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc"
258 " Text");
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000259
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000260 while (ptr)
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000261 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000262 DPRINTF( "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000263
Dmitry Timoshkovdc830b52001-03-28 18:46:08 +0000264 GetClassNameA( ptr->hwndSelf, className, sizeof(className) );
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000265 DPRINTF( "%08lx %-6.4x %-17.17s %08x %08x %.14s\n",
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000266 (DWORD)ptr, ptr->hmemTaskQ, className,
Alexandre Julliarda3960291999-02-26 11:11:13 +0000267 (UINT)ptr->dwStyle, (UINT)ptr->winproc,
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +0000268 ptr->text ? debugstr_w(ptr->text) : "<null>");
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000269
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000270 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000271 WIN_UpdateWndPtr(&ptr,ptr->next);
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000272 }
273}
274
Alexandre Julliardaca05781994-10-17 18:12:41 +0000275/***********************************************************************
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000276 * WIN_UnlinkWindow
277 *
278 * Remove a window from the siblings linked list.
279 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000280BOOL WIN_UnlinkWindow( HWND hwnd )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000281{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000282 WND *wndPtr, **ppWnd;
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000283 BOOL ret = FALSE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000284
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000285 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
286 else if(!wndPtr->parent)
287 {
288 WIN_ReleaseWndPtr(wndPtr);
289 return FALSE;
290 }
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000291
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000292 ppWnd = &wndPtr->parent->child;
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000293 while (*ppWnd && *ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
294 if (*ppWnd)
295 {
296 *ppWnd = wndPtr->next;
297 ret = TRUE;
298 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000299 WIN_ReleaseWndPtr(wndPtr);
Eric Pouech3be8e3b1999-04-18 13:13:40 +0000300 return ret;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000301}
302
303
304/***********************************************************************
305 * WIN_LinkWindow
306 *
307 * Insert a window into the siblings linked list.
308 * The window is inserted after the specified window, which can also
309 * be specified as HWND_TOP or HWND_BOTTOM.
310 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000311BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000312{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000313 WND *wndPtr, **ppWnd;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000314
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000315 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
316 else if(!wndPtr->parent)
317 {
318 WIN_ReleaseWndPtr(wndPtr);
319 return FALSE;
320 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000321 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
322 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000323 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000324 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000325 while (*ppWnd) ppWnd = &(*ppWnd)->next;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000326 }
327 else /* Normal case */
328 {
329 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000330 if (!afterPtr)
331 {
332 WIN_ReleaseWndPtr(wndPtr);
333 return FALSE;
334 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000335 ppWnd = &afterPtr->next;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000336 WIN_ReleaseWndPtr(afterPtr);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000337 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000338 wndPtr->next = *ppWnd;
339 *ppWnd = wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000340 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000341 return TRUE;
342}
343
344
345/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000346 * WIN_FindWinToRepaint
347 *
348 * Find a window that needs repaint.
349 */
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000350HWND WIN_FindWinToRepaint( HWND hwnd )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000351{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000352 HWND hwndRet;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000353 WND *pWnd;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000354
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000355 /* Note: the desktop window never gets WM_PAINT messages
356 * The real reason why is because Windows DesktopWndProc
357 * does ValidateRgn inside WM_ERASEBKGND handler.
358 */
Alexandre Julliard43230042001-05-16 19:52:29 +0000359 if (hwnd == GetDesktopWindow()) hwnd = 0;
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000360
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000361 pWnd = hwnd ? WIN_FindWndPtr(hwnd) : WIN_LockWndPtr(pWndDesktop->child);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000362
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000363 for ( ; pWnd ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard401710d1993-09-04 10:09:32 +0000364 {
Alexandre Julliarde658d821997-11-30 17:45:40 +0000365 if (!(pWnd->dwStyle & WS_VISIBLE))
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000366 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000367 TRACE("skipping window %04x\n",
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000368 pWnd->hwndSelf );
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000369 }
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000370 else if ((pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)) &&
371 GetWindowThreadProcessId( pWnd->hwndSelf, NULL ) == GetCurrentThreadId())
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000372 break;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000373
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000374 else if (pWnd->child )
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000375 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf )) )
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000376 {
377 WIN_ReleaseWndPtr(pWnd);
378 return hwndRet;
379 }
380
Alexandre Julliard401710d1993-09-04 10:09:32 +0000381 }
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000382
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000383 if(!pWnd)
384 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000385 return 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000386 }
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000387
388 hwndRet = pWnd->hwndSelf;
389
390 /* look among siblings if we got a transparent window */
391 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
392 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
393 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000394 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000395 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000396 if (pWnd)
397 {
398 hwndRet = pWnd->hwndSelf;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000399 WIN_ReleaseWndPtr(pWnd);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000400 }
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000401 TRACE("found %04x\n",hwndRet);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000402 return hwndRet;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000403}
404
405
406/***********************************************************************
Alexandre Julliardaca05781994-10-17 18:12:41 +0000407 * WIN_DestroyWindow
408 *
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000409 * Destroy storage associated to a window. "Internals" p.358
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000410 * returns a locked wndPtr->next
Alexandre Julliardaca05781994-10-17 18:12:41 +0000411 */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000412static WND* WIN_DestroyWindow( WND* wndPtr )
Alexandre Julliardaca05781994-10-17 18:12:41 +0000413{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000414 HWND hwnd = wndPtr->hwndSelf;
Alexandre Julliard349a9531997-02-02 19:01:52 +0000415 WND *pWnd;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000416
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000417 TRACE("%04x\n", wndPtr->hwndSelf );
Alexandre Julliard75d86e11996-11-17 18:59:11 +0000418
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000419 /* free child windows */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000420 WIN_LockWndPtr(wndPtr->child);
Alexandre Julliard349a9531997-02-02 19:01:52 +0000421 while ((pWnd = wndPtr->child))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000422 {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000423 wndPtr->child = WIN_DestroyWindow( pWnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000424 WIN_ReleaseWndPtr(pWnd);
425 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000426
Francis Beaudet7c2f0fe1999-03-21 08:50:41 +0000427 /*
428 * Clear the update region to make sure no WM_PAINT messages will be
429 * generated for this window while processing the WM_NCDESTROY.
430 */
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000431 RedrawWindow( wndPtr->hwndSelf, NULL, 0,
432 RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_NOCHILDREN);
Francis Beaudet7c2f0fe1999-03-21 08:50:41 +0000433
434 /*
435 * Send the WM_NCDESTROY to the window being destroyed.
436 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000437 SendMessageA( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000438
439 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
440
Alexandre Julliardde424282001-08-10 22:51:42 +0000441 WINPOS_CheckInternalPos( hwnd );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000442 if( hwnd == GetCapture()) ReleaseCapture();
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000443
444 /* free resources associated with the window */
445
446 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000447 PROPERTY_RemoveWindowProps( wndPtr );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000448
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000449 /* toss stale messages from the queue */
450
Alexandre Julliard51ab43b2001-05-18 22:51:56 +0000451 QUEUE_CleanupWindow( hwnd );
452 wndPtr->hmemTaskQ = 0;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000453
454 if (!(wndPtr->dwStyle & WS_CHILD))
Guy Albertelli38db0982000-05-11 00:06:38 +0000455 if (wndPtr->wIDmenu)
456 {
457 DestroyMenu( wndPtr->wIDmenu );
458 wndPtr->wIDmenu = 0;
459 }
460 if (wndPtr->hSysMenu)
461 {
462 DestroyMenu( wndPtr->hSysMenu );
463 wndPtr->hSysMenu = 0;
464 }
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +0000465 USER_Driver.pDestroyWindow( wndPtr->hwndSelf );
Alexandre Julliard85ed45e1998-08-22 19:03:56 +0000466 DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000467 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
Alexandre Julliard98779062000-12-07 23:39:16 +0000468 CLASS_RemoveWindow( wndPtr->class );
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000469 wndPtr->class = NULL;
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +0000470 wndPtr->dwMagic = 0; /* Mark it as invalid */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000471
472 WIN_UpdateWndPtr(&pWnd,wndPtr->next);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000473
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000474 return pWnd;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000475}
476
Alexandre Julliardaca05781994-10-17 18:12:41 +0000477/***********************************************************************
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000478 * WIN_DestroyThreadWindows
Alexandre Julliard77b99181997-09-14 17:17:23 +0000479 *
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000480 * Destroy all children of 'wnd' owned by the current thread.
Alexandre Julliard77b99181997-09-14 17:17:23 +0000481 * Return TRUE if something was done.
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000482 */
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000483BOOL WIN_DestroyThreadWindows( HWND hwnd )
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000484{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000485 BOOL ret = FALSE;
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000486 WND *wnd = WIN_FindWndPtr( hwnd );
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000487
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000488 if (!wnd) return FALSE;
489 while (wnd->child)
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000490 {
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000491 WND *tmp = WIN_LockWndPtr(wnd->child);
492 ret = FALSE;
493 while (tmp)
Alexandre Julliard77b99181997-09-14 17:17:23 +0000494 {
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000495 if (GetWindowThreadProcessId( tmp->hwndSelf, NULL ) == GetCurrentThreadId())
Alexandre Julliard77b99181997-09-14 17:17:23 +0000496 {
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000497 DestroyWindow( tmp->hwndSelf );
Alexandre Julliard77b99181997-09-14 17:17:23 +0000498 ret = TRUE;
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000499 break;
Alexandre Julliard77b99181997-09-14 17:17:23 +0000500 }
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000501 if (tmp->child && WIN_DestroyThreadWindows( tmp->hwndSelf ))
502 ret = TRUE;
503 else
504 WIN_UpdateWndPtr(&tmp,tmp->next);
Alexandre Julliard77b99181997-09-14 17:17:23 +0000505 }
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000506 WIN_ReleaseWndPtr(tmp);
507 if (!ret) break;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000508 }
Alexandre Julliard4b0343d2001-06-20 22:55:31 +0000509 WIN_ReleaseWndPtr( wnd );
Alexandre Julliard77b99181997-09-14 17:17:23 +0000510 return ret;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000511}
512
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000513/***********************************************************************
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000514 * WIN_CreateDesktopWindow
515 *
516 * Create the desktop window.
517 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000518BOOL WIN_CreateDesktopWindow(void)
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000519{
Alexandre Julliard98779062000-12-07 23:39:16 +0000520 struct tagCLASS *class;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000521 HWND hwndDesktop;
Alexandre Julliard98779062000-12-07 23:39:16 +0000522 INT wndExtra;
523 DWORD clsStyle;
524 WNDPROC winproc;
525 DCE *dce;
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000526 CREATESTRUCTA cs;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000527
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000528 TRACE("Creating desktop window\n");
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000529
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000530
Alexandre Julliard91222da2000-12-10 23:01:33 +0000531 if (!WINPOS_CreateInternalPosAtom() ||
532 !(class = CLASS_AddWindow( (ATOM)LOWORD(DESKTOP_CLASS_ATOM), 0, WIN_PROC_32W,
Alexandre Julliard98779062000-12-07 23:39:16 +0000533 &wndExtra, &winproc, &clsStyle, &dce )))
534 return FALSE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000535
Alexandre Julliard98779062000-12-07 23:39:16 +0000536 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND) + wndExtra );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000537 if (!hwndDesktop) return FALSE;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000538 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000539
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000540 pWndDesktop->next = NULL;
541 pWndDesktop->child = NULL;
542 pWndDesktop->parent = NULL;
543 pWndDesktop->owner = NULL;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000544 pWndDesktop->class = class;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000545 pWndDesktop->dwMagic = WND_MAGIC;
546 pWndDesktop->hwndSelf = hwndDesktop;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000547 pWndDesktop->hInstance = 0;
548 pWndDesktop->rectWindow.left = 0;
549 pWndDesktop->rectWindow.top = 0;
Marcus Meissnerddca3151999-05-22 11:33:23 +0000550 pWndDesktop->rectWindow.right = GetSystemMetrics(SM_CXSCREEN);
551 pWndDesktop->rectWindow.bottom = GetSystemMetrics(SM_CYSCREEN);
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000552 pWndDesktop->rectClient = pWndDesktop->rectWindow;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000553 pWndDesktop->text = NULL;
Alexandre Julliard43230042001-05-16 19:52:29 +0000554 pWndDesktop->hmemTaskQ = 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000555 pWndDesktop->hrgnUpdate = 0;
556 pWndDesktop->hwndLastActive = hwndDesktop;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000557 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
558 WS_CLIPSIBLINGS;
559 pWndDesktop->dwExStyle = 0;
Alexandre Julliard98779062000-12-07 23:39:16 +0000560 pWndDesktop->clsStyle = clsStyle;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000561 pWndDesktop->dce = NULL;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000562 pWndDesktop->pVScroll = NULL;
563 pWndDesktop->pHScroll = NULL;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000564 pWndDesktop->pProp = NULL;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000565 pWndDesktop->wIDmenu = 0;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000566 pWndDesktop->helpContext = 0;
Alexandre Julliard26320d12001-03-23 23:45:45 +0000567 pWndDesktop->flags = 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000568 pWndDesktop->hSysMenu = 0;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000569 pWndDesktop->userdata = 0;
Alexandre Julliard98779062000-12-07 23:39:16 +0000570 pWndDesktop->winproc = winproc;
571 pWndDesktop->cbWndExtra = wndExtra;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000572 pWndDesktop->irefCount = 0;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +0000573
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000574 cs.lpCreateParams = NULL;
575 cs.hInstance = 0;
576 cs.hMenu = 0;
577 cs.hwndParent = 0;
578 cs.x = 0;
579 cs.y = 0;
580 cs.cx = pWndDesktop->rectWindow.right;
581 cs.cy = pWndDesktop->rectWindow.bottom;
582 cs.style = pWndDesktop->dwStyle;
583 cs.dwExStyle = pWndDesktop->dwExStyle;
584 cs.lpszName = NULL;
585 cs.lpszClass = DESKTOP_CLASS_ATOM;
Alexandre Julliard91222da2000-12-10 23:01:33 +0000586
Gerard Patelad363032001-06-06 21:26:50 +0000587 if (!USER_Driver.pCreateWindow( hwndDesktop, &cs, FALSE )) return FALSE;
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000588
Alexandre Julliard1e37a181996-08-18 16:21:52 +0000589 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000590 return TRUE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000591}
592
593
594/***********************************************************************
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000595 * WIN_FixCoordinates
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000596 *
Gerard Patel78f52b52000-05-31 19:23:20 +0000597 * Fix the coordinates - Helper for WIN_CreateWindowEx.
598 * returns default show mode in sw.
599 * Note: the feature presented as undocumented *is* in the MSDN since 1993.
600 */
601static void WIN_FixCoordinates( CREATESTRUCTA *cs, INT *sw)
602{
603 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16 ||
604 cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
605 {
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000606 if (cs->style & (WS_CHILD | WS_POPUP))
Gerard Patel78f52b52000-05-31 19:23:20 +0000607 {
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000608 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16) cs->x = cs->y = 0;
609 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16) cs->cx = cs->cy = 0;
Gerard Patel78f52b52000-05-31 19:23:20 +0000610 }
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000611 else /* overlapped window */
Gerard Patel78f52b52000-05-31 19:23:20 +0000612 {
Alexandre Julliard6aa28432000-06-08 01:01:09 +0000613 STARTUPINFOA info;
614
615 GetStartupInfoA( &info );
616
617 if (cs->x == CW_USEDEFAULT || cs->x == CW_USEDEFAULT16)
618 {
619 /* Never believe Microsoft's documentation... CreateWindowEx doc says
620 * that if an overlapped window is created with WS_VISIBLE style bit
621 * set and the x parameter is set to CW_USEDEFAULT, the system ignores
622 * the y parameter. However, disassembling NT implementation (WIN32K.SYS)
623 * reveals that
624 *
625 * 1) not only it checks for CW_USEDEFAULT but also for CW_USEDEFAULT16
626 * 2) it does not ignore the y parameter as the docs claim; instead, it
627 * uses it as second parameter to ShowWindow() unless y is either
628 * CW_USEDEFAULT or CW_USEDEFAULT16.
629 *
630 * The fact that we didn't do 2) caused bogus windows pop up when wine
631 * was running apps that were using this obscure feature. Example -
632 * calc.exe that comes with Win98 (only Win98, it's different from
633 * the one that comes with Win95 and NT)
634 */
635 if (cs->y != CW_USEDEFAULT && cs->y != CW_USEDEFAULT16) *sw = cs->y;
636 cs->x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : 0;
637 cs->y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : 0;
638 }
639
640 if (cs->cx == CW_USEDEFAULT || cs->cx == CW_USEDEFAULT16)
641 {
642 if (info.dwFlags & STARTF_USESIZE)
643 {
644 cs->cx = info.dwXSize;
645 cs->cy = info.dwYSize;
646 }
647 else /* if no other hint from the app, pick 3/4 of the screen real estate */
648 {
649 RECT r;
650 SystemParametersInfoA( SPI_GETWORKAREA, 0, &r, 0);
651 cs->cx = (((r.right - r.left) * 3) / 4) - cs->x;
652 cs->cy = (((r.bottom - r.top) * 3) / 4) - cs->y;
653 }
654 }
Gerard Patel78f52b52000-05-31 19:23:20 +0000655 }
656 }
657}
658
659/***********************************************************************
660 * WIN_CreateWindowEx
661 *
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000662 * Implementation of CreateWindowEx().
Alexandre Julliard401710d1993-09-04 10:09:32 +0000663 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000664static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom,
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000665 WINDOWPROCTYPE type )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000666{
Slava Monicha27807d1999-06-05 11:46:35 +0000667 INT sw = SW_SHOW;
Alexandre Julliard98779062000-12-07 23:39:16 +0000668 struct tagCLASS *classPtr;
Alexandre Julliardd2e1c1a1996-03-09 16:12:43 +0000669 WND *wndPtr;
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000670 HWND hwnd, hwndLinkAfter;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000671 POINT maxSize, maxPos, minTrack, maxTrack;
Alexandre Julliard98779062000-12-07 23:39:16 +0000672 INT wndExtra;
673 DWORD clsStyle;
674 WNDPROC winproc;
675 DCE *dce;
Gerard Patelad363032001-06-06 21:26:50 +0000676 BOOL unicode = (type == WIN_PROC_32W);
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000677
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000678 TRACE("%s %s %08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000679 (type == WIN_PROC_32W) ? debugres_w((LPWSTR)cs->lpszName) : debugres_a(cs->lpszName),
680 (type == WIN_PROC_32W) ? debugres_w((LPWSTR)cs->lpszClass) : debugres_a(cs->lpszClass),
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000681 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
682 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000683
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000684 TRACE("winproc type is %d (%s)\n", type, (type == WIN_PROC_16) ? "WIN_PROC_16" :
685 ((type == WIN_PROC_32A) ? "WIN_PROC_32A" : "WIN_PROC_32W") );
686
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000687 /* Find the parent window */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000688
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000689 if (cs->hwndParent)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000690 {
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000691 /* Make sure parent is valid */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000692 if (!IsWindow( cs->hwndParent ))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000693 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000694 WARN("Bad parent %04x\n", cs->hwndParent );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000695 return 0;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000696 }
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000697 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000698 WARN("No parent for child window\n" );
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000699 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000700 }
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000701
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000702 /* Find the window class */
Alexandre Julliard98779062000-12-07 23:39:16 +0000703 if (!(classPtr = CLASS_AddWindow( classAtom, cs->hInstance, type,
704 &wndExtra, &winproc, &clsStyle, &dce )))
Alexandre Julliard808cb041995-08-17 17:11:36 +0000705 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +0000706 WARN("Bad class '%s'\n", cs->lpszClass );
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000707 return 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000708 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000709
Gerard Patel78f52b52000-05-31 19:23:20 +0000710 WIN_FixCoordinates(cs, &sw); /* fix default coordinates */
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000711
Bill Medland3f68bc92001-07-20 18:36:25 +0000712 /* Correct the window style - stage 1
713 *
714 * These are patches that appear to affect both the style loaded into the
715 * WIN structure and passed in the CreateStruct to the WM_CREATE etc.
716 *
717 * WS_EX_WINDOWEDGE appears to be enforced based on the other styles, so
718 * why does the user get to set it?
719 */
720
721 /* This has been tested for WS_CHILD | WS_VISIBLE. It has not been
722 * tested for WS_POPUP
723 */
724 if ((cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
725 ((!(cs->dwExStyle & WS_EX_STATICEDGE)) &&
726 (cs->style & (WS_DLGFRAME | WS_THICKFRAME))))
727 cs->dwExStyle |= WS_EX_WINDOWEDGE;
728 else
729 cs->dwExStyle &= ~WS_EX_WINDOWEDGE;
730
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000731 /* Create the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000732
Alexandre Julliard98779062000-12-07 23:39:16 +0000733 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + wndExtra - sizeof(wndPtr->wExtra) )))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000734 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000735 TRACE("out of memory\n" );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000736 return 0;
737 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000738
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000739 /* Fill the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000740
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000741 wndPtr = WIN_LockWndPtr((WND *) USER_HEAP_LIN_ADDR( hwnd ));
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000742 wndPtr->next = NULL;
743 wndPtr->child = NULL;
744
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000745 if ((cs->style & WS_CHILD) && cs->hwndParent)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000746 {
747 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
748 wndPtr->owner = NULL;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000749 WIN_ReleaseWndPtr(wndPtr->parent);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000750 }
751 else
752 {
753 wndPtr->parent = pWndDesktop;
754 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
755 wndPtr->owner = NULL;
756 else
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000757 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000758 WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
759 wndPtr->owner = WIN_GetTopParentPtr(tmpWnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000760 WIN_ReleaseWndPtr(wndPtr->owner);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000761 WIN_ReleaseWndPtr(tmpWnd);
Slava Monicha27807d1999-06-05 11:46:35 +0000762 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000763 }
Slava Monicha27807d1999-06-05 11:46:35 +0000764
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000765
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000766 wndPtr->class = classPtr;
Alexandre Julliard98779062000-12-07 23:39:16 +0000767 wndPtr->winproc = winproc;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000768 wndPtr->dwMagic = WND_MAGIC;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000769 wndPtr->hwndSelf = hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000770 wndPtr->hInstance = cs->hInstance;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000771 wndPtr->text = NULL;
Alexandre Julliard8afe6622001-07-26 20:12:22 +0000772 wndPtr->hmemTaskQ = InitThreadInput16( 0, 0 );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000773 wndPtr->hrgnUpdate = 0;
Huw D M Daviesa14ca862000-07-29 11:31:29 +0000774 wndPtr->hrgnWnd = 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000775 wndPtr->hwndLastActive = hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000776 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
777 wndPtr->dwExStyle = cs->dwExStyle;
Alexandre Julliard98779062000-12-07 23:39:16 +0000778 wndPtr->clsStyle = clsStyle;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000779 wndPtr->wIDmenu = 0;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000780 wndPtr->helpContext = 0;
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000781 wndPtr->flags = (type == WIN_PROC_16) ? 0 : WIN_ISWIN32;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000782 wndPtr->pVScroll = NULL;
783 wndPtr->pHScroll = NULL;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000784 wndPtr->pProp = NULL;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000785 wndPtr->userdata = 0;
Alexandre Julliard7ff1c411997-05-25 13:58:18 +0000786 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
787 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
Alexandre Julliard98779062000-12-07 23:39:16 +0000788 wndPtr->cbWndExtra = wndExtra;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000789 wndPtr->irefCount = 1;
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000790
Alexandre Julliard98779062000-12-07 23:39:16 +0000791 if (wndExtra) memset( wndPtr->wExtra, 0, wndExtra);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000792
793 /* Call the WH_CBT hook */
794
NF Stevens181fa7c1998-12-14 14:37:06 +0000795 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
796 ? HWND_BOTTOM : HWND_TOP;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000797
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000798 if (HOOK_IsHooked( WH_CBT ))
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000799 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000800 CBT_CREATEWNDA cbtc;
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000801 LRESULT ret;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000802
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000803 cbtc.lpcs = cs;
804 cbtc.hwndInsertAfter = hwndLinkAfter;
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000805 ret = (type == WIN_PROC_32W) ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000806 : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc);
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000807 if (ret)
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000808 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000809 TRACE("CBT-hook returned 0\n");
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000810 USER_HEAP_FREE( hwnd );
Alexandre Julliard98779062000-12-07 23:39:16 +0000811 CLASS_RemoveWindow( classPtr );
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000812 hwnd = 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000813 goto end;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000814 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000815 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000816
Bill Medland3f68bc92001-07-20 18:36:25 +0000817 /* Correct the window style - stage 2 */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000818
Alex Korobka44a1b591999-04-01 12:03:52 +0000819 if (!(cs->style & WS_CHILD))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000820 {
Alex Korobka44a1b591999-04-01 12:03:52 +0000821 wndPtr->dwStyle |= WS_CLIPSIBLINGS;
822 if (!(cs->style & WS_POPUP))
823 {
824 wndPtr->dwStyle |= WS_CAPTION;
825 wndPtr->flags |= WIN_NEED_SIZE;
826 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000827 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000828
829 /* Get class or window DC if needed */
Alexandre Julliardaca05781994-10-17 18:12:41 +0000830
Alexandre Julliard98779062000-12-07 23:39:16 +0000831 if (clsStyle & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
832 else if (clsStyle & CS_CLASSDC) wndPtr->dce = dce;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000833 else wndPtr->dce = NULL;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000834
Alexandre Julliard5e9dab52000-06-07 02:03:19 +0000835 /* Initialize the dimensions before sending WM_GETMINMAXINFO */
836
837 wndPtr->rectWindow.left = cs->x;
838 wndPtr->rectWindow.top = cs->y;
839 wndPtr->rectWindow.right = cs->x + cs->cx;
840 wndPtr->rectWindow.bottom = cs->y + cs->cy;
841 wndPtr->rectClient = wndPtr->rectWindow;
842
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000843 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
Alexandre Julliard988ca971994-06-21 16:15:21 +0000844
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000845 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000846 {
Alexandre Julliardde424282001-08-10 22:51:42 +0000847 WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack);
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000848 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
849 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000850 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
851 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000852 }
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000853
Lawson Whitney68dd6792000-06-25 12:53:27 +0000854 if (cs->cx < 0) cs->cx = 0;
855 if (cs->cy < 0) cs->cy = 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000856
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000857 wndPtr->rectWindow.left = cs->x;
858 wndPtr->rectWindow.top = cs->y;
859 wndPtr->rectWindow.right = cs->x + cs->cx;
860 wndPtr->rectWindow.bottom = cs->y + cs->cy;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000861 wndPtr->rectClient = wndPtr->rectWindow;
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000862
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000863 /* Set the window menu */
864
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000865 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000866 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000867 if (cs->hMenu) SetMenu(hwnd, cs->hMenu);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000868 else
869 {
Alexandre Julliardac7efef2000-11-27 21:54:01 +0000870 LPCSTR menuName = (LPCSTR)GetClassLongA( hwnd, GCL_MENUNAME );
Alexandre Julliard54c27111998-03-29 19:44:57 +0000871 if (menuName)
872 {
Ulrich Weigand7df1fbb1998-11-01 18:01:53 +0000873 if (HIWORD(cs->hInstance))
Alexandre Julliardac7efef2000-11-27 21:54:01 +0000874 cs->hMenu = LoadMenuA(cs->hInstance,menuName);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000875 else
Alexandre Julliard54c27111998-03-29 19:44:57 +0000876 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
877
Alexandre Julliarda3960291999-02-26 11:11:13 +0000878 if (cs->hMenu) SetMenu( hwnd, cs->hMenu );
Alexandre Julliard54c27111998-03-29 19:44:57 +0000879 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000880 }
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000881 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000882 else wndPtr->wIDmenu = (UINT)cs->hMenu;
Alexandre Julliard490a27e1994-06-08 13:57:50 +0000883
Gerard Patelad363032001-06-06 21:26:50 +0000884 if (!USER_Driver.pCreateWindow( wndPtr->hwndSelf, cs, unicode))
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000885 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000886 WARN("aborted by WM_xxCREATE!\n");
887 WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
888 CLASS_RemoveWindow( classPtr );
889 WIN_ReleaseWndPtr(wndPtr);
890 return 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000891 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000892
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000893 if( (wndPtr->dwStyle & WS_CHILD) && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
894 {
895 /* Notify the parent window only */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000896
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000897 SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
898 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
899 if( !IsWindow(hwnd) )
900 {
901 hwnd = 0;
902 goto end;
903 }
904 }
905
906 if (cs->style & WS_VISIBLE)
907 {
908 /* in case WS_VISIBLE got set in the meantime */
909 wndPtr->dwStyle &= ~WS_VISIBLE;
910 ShowWindow( hwnd, sw );
911 }
912
913 /* Call WH_SHELL hook */
914
915 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
916 HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
917
918 TRACE("created window %04x\n", hwnd);
919 end:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000920 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000921 return hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000922}
923
924
925/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000926 * CreateWindow (USER.41)
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000927 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000928HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
929 DWORD style, INT16 x, INT16 y, INT16 width,
930 INT16 height, HWND16 parent, HMENU16 menu,
931 HINSTANCE16 instance, LPVOID data )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000932{
933 return CreateWindowEx16( 0, className, windowName, style,
934 x, y, width, height, parent, menu, instance, data );
935}
936
937
938/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000939 * CreateWindowEx (USER.452)
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000940 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000941HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
942 LPCSTR windowName, DWORD style, INT16 x,
943 INT16 y, INT16 width, INT16 height,
944 HWND16 parent, HMENU16 menu,
945 HINSTANCE16 instance, LPVOID data )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000946{
947 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000948 CREATESTRUCTA cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +0000949 char buffer[256];
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000950
951 /* Find the class atom */
952
Gerard Patel6fdb5dd2000-02-16 21:23:24 +0000953 if (HIWORD(className))
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000954 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +0000955 if (!(classAtom = GlobalFindAtomA( className )))
956 {
957 ERR( "bad class name %s\n", debugres_a(className) );
958 return 0;
959 }
960 }
961 else
962 {
963 classAtom = LOWORD(className);
964 if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
965 {
966 ERR( "bad atom %x\n", classAtom);
967 return 0;
968 }
969 className = buffer;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000970 }
971
972 /* Fix the coordinates */
973
Alexandre Julliarda3960291999-02-26 11:11:13 +0000974 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)x;
975 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)y;
976 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)width;
977 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)height;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000978
979 /* Create the window */
980
981 cs.lpCreateParams = data;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000982 cs.hInstance = (HINSTANCE)instance;
983 cs.hMenu = (HMENU)menu;
984 cs.hwndParent = (HWND)parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000985 cs.style = style;
986 cs.lpszName = windowName;
987 cs.lpszClass = className;
988 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +0000989
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000990 return WIN_CreateWindowEx( &cs, classAtom, WIN_PROC_16 );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000991}
992
993
994/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000995 * CreateWindowExA (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000996 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000997HWND WINAPI CreateWindowExA( DWORD exStyle, LPCSTR className,
998 LPCSTR windowName, DWORD style, INT x,
999 INT y, INT width, INT height,
1000 HWND parent, HMENU menu,
1001 HINSTANCE instance, LPVOID data )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001002{
1003 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001004 CREATESTRUCTA cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001005 char buffer[256];
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001006
Rein Klazesd4a2cee1999-10-23 13:57:36 +00001007 if(!instance)
1008 instance=GetModuleHandleA(NULL);
1009
Rein Klazes5c6fc1b1998-11-01 14:50:06 +00001010 if(exStyle & WS_EX_MDICHILD)
Dmitry Timoshkov91adf0a2001-02-12 03:40:41 +00001011 return CreateMDIWindowA(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001012
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001013 /* Find the class atom */
1014
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001015 if (HIWORD(className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001016 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001017 if (!(classAtom = GlobalFindAtomA( className )))
1018 {
1019 ERR( "bad class name %s\n", debugres_a(className) );
1020 return 0;
1021 }
1022 }
1023 else
1024 {
1025 classAtom = LOWORD(className);
1026 if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
1027 {
1028 ERR( "bad atom %x\n", classAtom);
1029 return 0;
1030 }
1031 className = buffer;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001032 }
1033
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001034 /* Create the window */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001035
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001036 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001037 cs.hInstance = instance;
1038 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001039 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001040 cs.x = x;
1041 cs.y = y;
1042 cs.cx = width;
1043 cs.cy = height;
1044 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001045 cs.lpszName = windowName;
1046 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001047 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001048
Dmitry Timoshkov5956b982000-11-28 23:53:08 +00001049 return WIN_CreateWindowEx( &cs, classAtom, WIN_PROC_32A );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001050}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001051
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001052
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001053/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001054 * CreateWindowExW (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001055 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001056HWND WINAPI CreateWindowExW( DWORD exStyle, LPCWSTR className,
1057 LPCWSTR windowName, DWORD style, INT x,
1058 INT y, INT width, INT height,
1059 HWND parent, HMENU menu,
1060 HINSTANCE instance, LPVOID data )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001061{
1062 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001063 CREATESTRUCTW cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001064 WCHAR buffer[256];
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001065
Rein Klazesd4a2cee1999-10-23 13:57:36 +00001066 if(!instance)
1067 instance=GetModuleHandleA(NULL);
1068
Rein Klazes5c6fc1b1998-11-01 14:50:06 +00001069 if(exStyle & WS_EX_MDICHILD)
Dmitry Timoshkov91adf0a2001-02-12 03:40:41 +00001070 return CreateMDIWindowW(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
Rein Klazes5c6fc1b1998-11-01 14:50:06 +00001071
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001072 /* Find the class atom */
1073
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001074 if (HIWORD(className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001075 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001076 if (!(classAtom = GlobalFindAtomW( className )))
1077 {
1078 ERR( "bad class name %s\n", debugres_w(className) );
1079 return 0;
1080 }
1081 }
1082 else
1083 {
1084 classAtom = LOWORD(className);
1085 if (!GlobalGetAtomNameW( classAtom, buffer, sizeof(buffer)/sizeof(WCHAR) ))
1086 {
1087 ERR( "bad atom %x\n", classAtom);
1088 return 0;
1089 }
1090 className = buffer;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001091 }
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001092
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001093 /* Create the window */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001094
1095 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001096 cs.hInstance = instance;
1097 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001098 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001099 cs.x = x;
1100 cs.y = y;
1101 cs.cx = width;
1102 cs.cy = height;
1103 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001104 cs.lpszName = windowName;
1105 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001106 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001107
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001108 /* Note: we rely on the fact that CREATESTRUCTA and */
1109 /* CREATESTRUCTW have the same layout. */
Dmitry Timoshkov5956b982000-11-28 23:53:08 +00001110 return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, classAtom, WIN_PROC_32W );
Alexandre Julliard401710d1993-09-04 10:09:32 +00001111}
1112
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001113/***********************************************************************
1114 * WIN_SendDestroyMsg
1115 */
1116static void WIN_SendDestroyMsg( WND* pWnd )
1117{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001118 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret();
Alexandre Julliard42d20f92000-08-10 01:16:19 +00001119 USER_Driver.pResetSelectionOwner( pWnd, TRUE );
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001120
1121 /*
1122 * Send the WM_DESTROY to the window.
1123 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001124 SendMessageA( pWnd->hwndSelf, WM_DESTROY, 0, 0);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001125
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001126 /*
1127 * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
1128 * make sure that the window still exists when we come back.
1129 */
1130 if (IsWindow(pWnd->hwndSelf))
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001131 {
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001132 HWND* pWndArray = NULL;
1133 WND* pChild = NULL;
1134 int nKidCount = 0;
1135
1136 /*
1137 * Now, if the window has kids, we have to send WM_DESTROY messages
1138 * recursively to it's kids. It seems that those calls can also
1139 * trigger re-entrant calls to DestroyWindow for the kids so we must
1140 * protect against corruption of the list of siblings. We first build
1141 * a list of HWNDs representing all the kids.
1142 */
1143 pChild = WIN_LockWndPtr(pWnd->child);
1144 while( pChild )
1145 {
1146 nKidCount++;
1147 WIN_UpdateWndPtr(&pChild,pChild->next);
1148 }
1149
1150 /*
1151 * If there are no kids, we're done.
1152 */
1153 if (nKidCount==0)
1154 return;
1155
1156 pWndArray = HeapAlloc(GetProcessHeap(), 0, nKidCount*sizeof(HWND));
1157
1158 /*
1159 * Sanity check
1160 */
1161 if (pWndArray==NULL)
1162 return;
1163
1164 /*
1165 * Now, enumerate all the kids in a list, since we wait to make the SendMessage
1166 * call, our linked list of siblings should be safe.
1167 */
1168 nKidCount = 0;
1169 pChild = WIN_LockWndPtr(pWnd->child);
1170 while( pChild )
1171 {
1172 pWndArray[nKidCount] = pChild->hwndSelf;
1173 nKidCount++;
1174 WIN_UpdateWndPtr(&pChild,pChild->next);
1175 }
1176
1177 /*
1178 * Now that we have a list, go through that list again and send the destroy
1179 * message to those windows. We are using the HWND to retrieve the
1180 * WND pointer so we are effectively checking that all the kid windows are
1181 * still valid before sending the message.
1182 */
1183 while (nKidCount>0)
1184 {
Pavel Roskinc5012071999-03-19 16:59:18 +00001185 pChild = WIN_FindWndPtr(pWndArray[--nKidCount]);
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001186
1187 if (pChild!=NULL)
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001188 {
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001189 WIN_SendDestroyMsg( pChild );
1190 WIN_ReleaseWndPtr(pChild);
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001191 }
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001192 }
1193
1194 /*
1195 * Cleanup
1196 */
1197 HeapFree(GetProcessHeap(), 0, pWndArray);
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001198 }
1199 else
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001200 WARN("\tdestroyed itself while in WM_DESTROY!\n");
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001201}
1202
1203
1204/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001205 * DestroyWindow (USER.53)
Alexandre Julliard401710d1993-09-04 10:09:32 +00001206 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001207BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00001208{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001209 return DestroyWindow(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00001210}
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001211
1212
Alexandre Julliard01d63461997-01-20 19:43:45 +00001213/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001214 * DestroyWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001215 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001216BOOL WINAPI DestroyWindow( HWND hwnd )
Alexandre Julliard401710d1993-09-04 10:09:32 +00001217{
Alexandre Julliard0e607781993-11-03 19:23:37 +00001218 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001219 BOOL retvalue;
Alexandre Julliard1f029ea2000-11-02 20:08:59 +00001220 HWND h;
1221 BOOL bFocusSet = FALSE;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00001222
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001223 TRACE("(%04x)\n", hwnd);
Alexandre Julliard1f029ea2000-11-02 20:08:59 +00001224
1225 /* Initialization */
Alexandre Julliard401710d1993-09-04 10:09:32 +00001226
Alexandre Julliard0e607781993-11-03 19:23:37 +00001227 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001228 if (wndPtr == pWndDesktop)
1229 {
Andreas Mohr1c20b392000-02-20 19:17:35 +00001230 retvalue = FALSE; /* Can't destroy desktop */
1231 goto end;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001232 }
Alexandre Julliard58199531994-04-21 01:20:00 +00001233
Alexandre Julliard1f029ea2000-11-02 20:08:59 +00001234 /* Look whether the focus is within the tree of windows we will
1235 * be destroying.
1236 */
1237 h = GetFocus16();
1238 while (h && (GetWindowLongA(h,GWL_STYLE) & WS_CHILD))
1239 {
1240 if (h == hwnd)
1241 {
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00001242 SetFocus(GetParent(h));
Alexandre Julliard1f029ea2000-11-02 20:08:59 +00001243 bFocusSet = TRUE;
1244 break;
1245 }
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00001246 h = GetParent(h);
Alexandre Julliard1f029ea2000-11-02 20:08:59 +00001247 }
1248 /* If the focus is on the window we will destroy and it has no parent,
1249 * set the focus to 0.
1250 */
1251 if (! bFocusSet && (h == hwnd))
1252 {
1253 if (!(GetWindowLongA(h,GWL_STYLE) & WS_CHILD))
1254 SetFocus(0);
1255 }
1256
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001257 /* Call hooks */
1258
Alexandre Julliard32ee1682001-05-09 17:33:00 +00001259 if( HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001260 {
1261 retvalue = FALSE;
1262 goto end;
1263 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001264
1265 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1266 {
Alexandre Julliard32ee1682001-05-09 17:33:00 +00001267 HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001268 /* FIXME: clean up palette - see "Internals" p.352 */
1269 }
1270
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001271 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
Alexandre Julliard77b99181997-09-14 17:17:23 +00001272 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
1273 {
1274 /* Notify the parent window only */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001275 SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
Alexandre Julliard77b99181997-09-14 17:17:23 +00001276 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001277 if( !IsWindow(hwnd) )
1278 {
1279 retvalue = TRUE;
1280 goto end;
1281 }
Alexandre Julliard77b99181997-09-14 17:17:23 +00001282 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001283
Alexandre Julliard42d20f92000-08-10 01:16:19 +00001284 USER_Driver.pResetSelectionOwner( wndPtr, FALSE ); /* before the window is unmapped */
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001285
Alexandre Julliard58199531994-04-21 01:20:00 +00001286 /* Hide the window */
1287
1288 if (wndPtr->dwStyle & WS_VISIBLE)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001289 {
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001290 ShowWindow( hwnd, SW_HIDE );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001291 if (!IsWindow(hwnd))
1292 {
1293 retvalue = TRUE;
1294 goto end;
1295 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001296 }
Alexandre Julliard0e607781993-11-03 19:23:37 +00001297
Alexandre Julliard22945d51995-03-02 17:44:29 +00001298 /* Recursively destroy owned windows */
1299
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001300 if( !(wndPtr->dwStyle & WS_CHILD) )
Alexandre Julliard22945d51995-03-02 17:44:29 +00001301 {
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001302 for (;;)
1303 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001304 WND *siblingPtr = WIN_LockWndPtr(wndPtr->parent->child); /* First sibling */
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001305 while (siblingPtr)
Alexandre Julliard22945d51995-03-02 17:44:29 +00001306 {
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001307 if (siblingPtr->owner == wndPtr)
Patrik Stridvallea584721998-11-01 16:22:07 +00001308 {
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001309 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1310 break;
1311 else
1312 siblingPtr->owner = NULL;
Patrik Stridvallea584721998-11-01 16:22:07 +00001313 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001314 WIN_UpdateWndPtr(&siblingPtr,siblingPtr->next);
Alexandre Julliard22945d51995-03-02 17:44:29 +00001315 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001316 if (siblingPtr)
1317 {
1318 DestroyWindow( siblingPtr->hwndSelf );
1319 WIN_ReleaseWndPtr(siblingPtr);
1320 }
Alexandre Julliard22945d51995-03-02 17:44:29 +00001321 else break;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001322 }
1323
Alexandre Julliardde424282001-08-10 22:51:42 +00001324 WINPOS_ActivateOtherWindow(wndPtr->hwndSelf);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001325
1326 if( wndPtr->owner &&
1327 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1328 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
Alexandre Julliard22945d51995-03-02 17:44:29 +00001329 }
1330
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001331 /* Send destroy messages */
Alexandre Julliard0e607781993-11-03 19:23:37 +00001332
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001333 WIN_SendDestroyMsg( wndPtr );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001334 if (!IsWindow(hwnd))
1335 {
1336 retvalue = TRUE;
1337 goto end;
1338 }
Alexandre Julliard401710d1993-09-04 10:09:32 +00001339
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001340 /* Unlink now so we won't bother with the children later on */
Alexandre Julliard401710d1993-09-04 10:09:32 +00001341
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001342 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1343
1344 /* Destroy the window storage */
1345
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001346 WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001347 retvalue = TRUE;
1348end:
1349 WIN_ReleaseWndPtr(wndPtr);
1350 return retvalue;
Alexandre Julliard401710d1993-09-04 10:09:32 +00001351}
1352
1353
1354/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001355 * CloseWindow (USER.43)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001356 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001357BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001358{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001359 return CloseWindow( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001360}
1361
1362
1363/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001364 * CloseWindow (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001365 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001366BOOL WINAPI CloseWindow( HWND hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001367{
1368 WND * wndPtr = WIN_FindWndPtr( hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001369 BOOL retvalue;
1370
1371 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD))
1372 {
1373 retvalue = FALSE;
1374 goto end;
1375 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00001376 ShowWindow( hwnd, SW_MINIMIZE );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001377 retvalue = TRUE;
1378end:
1379 WIN_ReleaseWndPtr(wndPtr);
1380 return retvalue;
1381
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001382}
1383
1384
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001385/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001386 * OpenIcon (USER.44)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001387 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001388BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001389{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001390 return OpenIcon( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001391}
1392
1393
1394/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001395 * OpenIcon (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001396 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001397BOOL WINAPI OpenIcon( HWND hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001398{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001399 if (!IsIconic( hwnd )) return FALSE;
1400 ShowWindow( hwnd, SW_SHOWNORMAL );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001401 return TRUE;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001402}
1403
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001404
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001405/***********************************************************************
1406 * WIN_FindWindow
1407 *
1408 * Implementation of FindWindow() and FindWindowEx().
1409 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001410static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className,
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001411 LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001412{
1413 WND *pWnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001414 HWND retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001415
1416 if (child)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001417 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001418 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1419 if (parent)
1420 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001421 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent))
1422 {
1423 retvalue = 0;
1424 goto end;
1425 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001426 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001427 else if (pWnd->parent != pWndDesktop)
1428 {
1429 retvalue = 0;
1430 goto end;
1431 }
1432 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001433 }
1434 else
1435 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001436 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : WIN_LockWndPtr(pWndDesktop)))
1437 {
1438 retvalue = 0;
1439 goto end;
1440 }
1441 WIN_UpdateWndPtr(&pWnd,pWnd->child);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001442 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001443 if (!pWnd)
1444 {
1445 retvalue = 0;
1446 goto end;
1447 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001448
Pavel Roskin598993f1999-03-16 09:53:10 +00001449 for ( ; pWnd ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001450 {
Alexandre Julliard98779062000-12-07 23:39:16 +00001451 if (className && (GetClassWord(pWnd->hwndSelf, GCW_ATOM) != className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001452 continue; /* Not the right class */
1453
1454 /* Now check the title */
1455
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001456 if (!title)
1457 {
1458 retvalue = pWnd->hwndSelf;
1459 goto end;
Pavel Roskin598993f1999-03-16 09:53:10 +00001460 }
Alexandre Julliardcb10fda2000-08-06 02:41:16 +00001461 if (pWnd->text && !strcmpW( pWnd->text, title ))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001462 {
1463 retvalue = pWnd->hwndSelf;
1464 goto end;
Pavel Roskin598993f1999-03-16 09:53:10 +00001465 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001466 }
1467 retvalue = 0;
Joerg Mayer2563b1b2000-12-22 20:29:41 +00001468 /* In this case we need to check whether other processes
1469 own a window with the given paramters on the Desktop,
1470 but we don't, so let's at least warn about it */
1471 FIXME("Returning 0 without checking other processes\n");
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001472end:
1473 WIN_ReleaseWndPtr(pWnd);
1474 return retvalue;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001475}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001476
1477
1478
1479/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001480 * FindWindow (USER.50)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001481 */
Alexandre Julliardb849d792000-02-13 13:56:13 +00001482HWND16 WINAPI FindWindow16( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001483{
Alexandre Julliardb849d792000-02-13 13:56:13 +00001484 return FindWindowA( className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001485}
1486
1487
1488/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001489 * FindWindowEx (USER.427)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001490 */
Alexandre Julliardb849d792000-02-13 13:56:13 +00001491HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child, LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001492{
Alexandre Julliardb849d792000-02-13 13:56:13 +00001493 return FindWindowExA( parent, child, className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001494}
1495
1496
1497/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001498 * FindWindowA (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001499 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001500HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001501{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001502 HWND ret = FindWindowExA( 0, 0, className, title );
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001503 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1504 return ret;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001505}
1506
1507
1508/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001509 * FindWindowExA (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001510 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001511HWND WINAPI FindWindowExA( HWND parent, HWND child,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001512 LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001513{
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001514 ATOM atom = 0;
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001515 LPWSTR buffer;
1516 HWND hwnd;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001517
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001518 if (className)
1519 {
1520 /* If the atom doesn't exist, then no class */
1521 /* with this name exists either. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001522 if (!(atom = GlobalFindAtomA( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001523 {
1524 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1525 return 0;
1526 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001527 }
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001528
1529 buffer = HEAP_strdupAtoW( GetProcessHeap(), 0, title );
1530 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1531 HeapFree( GetProcessHeap(), 0, buffer );
1532 return hwnd;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001533}
1534
1535
1536/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001537 * FindWindowExW (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001538 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001539HWND WINAPI FindWindowExW( HWND parent, HWND child,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001540 LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001541{
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001542 ATOM atom = 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001543
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001544 if (className)
1545 {
1546 /* If the atom doesn't exist, then no class */
1547 /* with this name exists either. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001548 if (!(atom = GlobalFindAtomW( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001549 {
1550 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1551 return 0;
1552 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001553 }
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001554 return WIN_FindWindow( parent, child, atom, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001555}
1556
1557
1558/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001559 * FindWindowW (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001560 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001561HWND WINAPI FindWindowW( LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001562{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001563 return FindWindowExW( 0, 0, className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001564}
1565
1566
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001567/**********************************************************************
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001568 * WIN_GetDesktop
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001569 * returns a locked pointer
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001570 */
1571WND *WIN_GetDesktop(void)
1572{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001573 return WIN_LockWndPtr(pWndDesktop);
1574}
1575/**********************************************************************
1576 * WIN_ReleaseDesktop
1577 * unlock the desktop pointer
1578 */
1579void WIN_ReleaseDesktop(void)
1580{
1581 WIN_ReleaseWndPtr(pWndDesktop);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001582}
1583
1584
1585/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001586 * GetDesktopWindow (USER.286)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001587 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001588HWND16 WINAPI GetDesktopWindow16(void)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001589{
1590 return (HWND16)pWndDesktop->hwndSelf;
1591}
1592
1593
1594/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001595 * GetDesktopWindow (USER32.@)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001596 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001597HWND WINAPI GetDesktopWindow(void)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001598{
Uwe Bonnes73619161999-10-24 20:42:39 +00001599 if (pWndDesktop) return pWndDesktop->hwndSelf;
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001600 ERR( "You need the -desktop option when running with native USER\n" );
Uwe Bonnes73619161999-10-24 20:42:39 +00001601 ExitProcess(1);
Huw D M Davies238b6d71999-10-31 01:56:51 +00001602 return 0;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001603}
1604
1605
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001606/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001607 * GetDesktopHwnd (USER.278)
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001608 *
1609 * Exactly the same thing as GetDesktopWindow(), but not documented.
1610 * Don't ask me why...
1611 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001612HWND16 WINAPI GetDesktopHwnd16(void)
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001613{
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001614 return (HWND16)pWndDesktop->hwndSelf;
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001615}
1616
1617
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001618/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001619 * EnableWindow (USER.34)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001620 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001621BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
Alexandre Julliard01d63461997-01-20 19:43:45 +00001622{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001623 return EnableWindow( hwnd, enable );
Alexandre Julliard01d63461997-01-20 19:43:45 +00001624}
1625
1626
1627/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001628 * EnableWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001629 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001630BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001631{
1632 WND *wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001633 BOOL retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001634
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001635 TRACE("( %x, %d )\n", hwnd, enable);
1636
1637 if (USER_Driver.pEnableWindow)
1638 return USER_Driver.pEnableWindow( hwnd, enable );
1639
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001640 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001641
1642 retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);
1643
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001644 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1645 {
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001646 wndPtr->dwStyle &= ~WS_DISABLED; /* Enable window */
1647 SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001648 }
1649 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1650 {
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001651 SendMessageA( wndPtr->hwndSelf, WM_CANCELMODE, 0, 0);
Alex Korobka4f1ac051999-03-28 09:37:57 +00001652
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001653 wndPtr->dwStyle |= WS_DISABLED; /* Disable window */
Alex Korobka4f1ac051999-03-28 09:37:57 +00001654
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001655 if (hwnd == GetFocus())
1656 SetFocus( 0 ); /* A disabled window can't have the focus */
Alex Korobka4f1ac051999-03-28 09:37:57 +00001657
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001658 if (hwnd == GetCapture())
1659 ReleaseCapture(); /* A disabled window can't capture the mouse */
1660
1661 SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001662 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001663 WIN_ReleaseWndPtr(wndPtr);
1664 return retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001665}
1666
1667
1668/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001669 * IsWindowEnabled (USER.35)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001670 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001671BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001672{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001673 return IsWindowEnabled(hWnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00001674}
1675
1676
1677/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001678 * IsWindowEnabled (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001679 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001680BOOL WINAPI IsWindowEnabled(HWND hWnd)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001681{
1682 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001683 BOOL retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001684
1685 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001686 retvalue = !(wndPtr->dwStyle & WS_DISABLED);
1687 WIN_ReleaseWndPtr(wndPtr);
1688 return retvalue;
1689
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001690}
1691
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001692
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001693/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001694 * IsWindowUnicode (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001695 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001696BOOL WINAPI IsWindowUnicode( HWND hwnd )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001697{
1698 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001699 BOOL retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001700
1701 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001702 retvalue = (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1703 WIN_ReleaseWndPtr(wndPtr);
1704 return retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001705}
1706
1707
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001708/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001709 * GetWindowWord (USER.133)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001710 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001711WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
Alexandre Julliard21979011997-03-05 08:22:35 +00001712{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001713 return GetWindowWord( hwnd, offset );
Alexandre Julliard21979011997-03-05 08:22:35 +00001714}
1715
1716
1717/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001718 * GetWindowWord (USER32.@)
Alexandre Julliard21979011997-03-05 08:22:35 +00001719 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001720WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001721{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001722 WORD retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001723 WND * wndPtr = WIN_FindWndPtr( hwnd );
1724 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001725 if (offset >= 0)
1726 {
Alexandre Julliard98779062000-12-07 23:39:16 +00001727 if (offset + sizeof(WORD) > wndPtr->cbWndExtra)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001728 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001729 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001730 retvalue = 0;
1731 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001732 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001733 retvalue = *(WORD *)(((char *)wndPtr->wExtra) + offset);
1734 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001735 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001736 switch(offset)
1737 {
Alexandre Julliard77b99181997-09-14 17:17:23 +00001738 case GWW_ID:
1739 if (HIWORD(wndPtr->wIDmenu))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001740 WARN("GWW_ID: discards high bits of 0x%08x!\n",
Alexandre Julliarda845b881998-06-01 10:44:35 +00001741 wndPtr->wIDmenu);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001742 retvalue = (WORD)wndPtr->wIDmenu;
1743 goto end;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001744 case GWW_HWNDPARENT:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001745 retvalue = GetParent(hwnd);
1746 goto end;
Alexandre Julliard77b99181997-09-14 17:17:23 +00001747 case GWW_HINSTANCE:
1748 if (HIWORD(wndPtr->hInstance))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001749 WARN("GWW_HINSTANCE: discards high bits of 0x%08x!\n",
Alexandre Julliarda845b881998-06-01 10:44:35 +00001750 wndPtr->hInstance);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001751 retvalue = (WORD)wndPtr->hInstance;
1752 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001753 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001754 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001755 retvalue = 0;
1756 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001757 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001758end:
1759 WIN_ReleaseWndPtr(wndPtr);
1760 return retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001761}
1762
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00001763/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001764 * SetWindowWord (USER.134)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001765 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001766WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
Alexandre Julliard21979011997-03-05 08:22:35 +00001767{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001768 return SetWindowWord( hwnd, offset, newval );
Alexandre Julliard21979011997-03-05 08:22:35 +00001769}
1770
1771
1772/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001773 * SetWindowWord (USER32.@)
Alexandre Julliard21979011997-03-05 08:22:35 +00001774 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001775WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001776{
1777 WORD *ptr, retval;
1778 WND * wndPtr = WIN_FindWndPtr( hwnd );
1779 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001780 if (offset >= 0)
1781 {
Alexandre Julliard98779062000-12-07 23:39:16 +00001782 if (offset + sizeof(WORD) > wndPtr->cbWndExtra)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001783 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001784 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001785 retval = 0;
1786 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001787 }
1788 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1789 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001790 else switch(offset)
1791 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001792 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1793 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001794 case GWW_HWNDPARENT: retval = SetParent( hwnd, newval );
1795 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001796 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001797 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001798 retval = 0;
1799 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001800 }
1801 retval = *ptr;
1802 *ptr = newval;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001803end:
1804 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001805 return retval;
1806}
1807
1808
1809/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001810 * WIN_GetWindowLong
1811 *
1812 * Helper function for GetWindowLong().
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001813 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001814static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001815{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001816 LONG retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001817 WND * wndPtr = WIN_FindWndPtr( hwnd );
1818 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001819 if (offset >= 0)
1820 {
Alexandre Julliard98779062000-12-07 23:39:16 +00001821 if (offset + sizeof(LONG) > wndPtr->cbWndExtra)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001822 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001823 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001824 retvalue = 0;
1825 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001826 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001827 retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
Alexandre Julliard3051b641996-07-05 17:14:13 +00001828 /* Special case for dialog window procedure */
1829 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001830 {
1831 retvalue = (LONG)WINPROC_GetProc( (HWINDOWPROC)retvalue, type );
1832 goto end;
1833 }
1834 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001835 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001836 switch(offset)
1837 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001838 case GWL_USERDATA: retvalue = wndPtr->userdata;
1839 goto end;
1840 case GWL_STYLE: retvalue = wndPtr->dwStyle;
1841 goto end;
1842 case GWL_EXSTYLE: retvalue = wndPtr->dwExStyle;
1843 goto end;
1844 case GWL_ID: retvalue = (LONG)wndPtr->wIDmenu;
1845 goto end;
1846 case GWL_WNDPROC: retvalue = (LONG)WINPROC_GetProc( wndPtr->winproc,
Alexandre Julliard3051b641996-07-05 17:14:13 +00001847 type );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001848 goto end;
1849 case GWL_HWNDPARENT: retvalue = GetParent(hwnd);
1850 goto end;
1851 case GWL_HINSTANCE: retvalue = wndPtr->hInstance;
1852 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001853 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001854 WARN("Unknown offset %d\n", offset );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001855 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001856 retvalue = 0;
1857end:
1858 WIN_ReleaseWndPtr(wndPtr);
1859 return retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001860}
1861
1862
1863/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001864 * WIN_SetWindowLong
1865 *
1866 * Helper function for SetWindowLong().
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001867 *
1868 * 0 is the failure code. However, in the case of failure SetLastError
1869 * must be set to distinguish between a 0 return value and a failure.
1870 *
1871 * FIXME: The error values for SetLastError may not be right. Can
1872 * someone check with the real thing?
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001873 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001874static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
Alexandre Julliard3051b641996-07-05 17:14:13 +00001875 WINDOWPROCTYPE type )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001876{
1877 LONG *ptr, retval;
1878 WND * wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001879 STYLESTRUCT style;
1880
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001881 TRACE("%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001882
1883 if (!wndPtr)
1884 {
1885 /* Is this the right error? */
1886 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1887 return 0;
1888 }
1889
Alexandre Julliard3051b641996-07-05 17:14:13 +00001890 if (offset >= 0)
1891 {
Alexandre Julliard98779062000-12-07 23:39:16 +00001892 if (offset + sizeof(LONG) > wndPtr->cbWndExtra)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001893 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001894 WARN("Invalid offset %d\n", offset );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001895
1896 /* Is this the right error? */
1897 SetLastError( ERROR_OUTOFMEMORY );
1898
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001899 retval = 0;
1900 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001901 }
1902 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1903 /* Special case for dialog window procedure */
1904 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1905 {
1906 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00001907 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1908 type, WIN_PROC_WINDOW );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001909 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001910 }
1911 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001912 else switch(offset)
1913 {
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001914 case GWL_ID:
1915 ptr = (DWORD*)&wndPtr->wIDmenu;
1916 break;
1917 case GWL_HINSTANCE:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001918 retval = SetWindowWord( hwnd, offset, newval );
1919 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001920 case GWL_WNDPROC:
Dmitry Timoshkov5956b982000-11-28 23:53:08 +00001921 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001922 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00001923 type, WIN_PROC_WINDOW );
Andreas Mohr1c20b392000-02-20 19:17:35 +00001924 goto end;
Alexandre Julliardca22b331996-07-12 19:02:39 +00001925 case GWL_STYLE:
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001926 style.styleOld = wndPtr->dwStyle;
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00001927 style.styleNew = newval;
Alexandre Julliard4b0343d2001-06-20 22:55:31 +00001928 SendMessageA(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001929 wndPtr->dwStyle = style.styleNew;
Alexandre Julliard4b0343d2001-06-20 22:55:31 +00001930 SendMessageA(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001931 retval = style.styleOld;
1932 goto end;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001933
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001934 case GWL_USERDATA:
1935 ptr = &wndPtr->userdata;
1936 break;
1937 case GWL_EXSTYLE:
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001938 style.styleOld = wndPtr->dwExStyle;
1939 style.styleNew = newval;
Alexandre Julliard4b0343d2001-06-20 22:55:31 +00001940 SendMessageA(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001941 wndPtr->dwExStyle = newval;
Alexandre Julliard4b0343d2001-06-20 22:55:31 +00001942 SendMessageA(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001943 retval = style.styleOld;
1944 goto end;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001945
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001946 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001947 WARN("Invalid offset %d\n", offset );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001948
1949 /* Don't think this is right error but it should do */
1950 SetLastError( ERROR_OUTOFMEMORY );
1951
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001952 retval = 0;
1953 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001954 }
1955 retval = *ptr;
1956 *ptr = newval;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001957end:
1958 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001959 return retval;
1960}
1961
1962
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001963/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001964 * GetWindowLong (USER.135)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001965 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001966LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00001967{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001968 return WIN_GetWindowLong( (HWND)hwnd, offset, WIN_PROC_16 );
Alexandre Julliard3051b641996-07-05 17:14:13 +00001969}
1970
1971
1972/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001973 * GetWindowLongA (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001974 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001975LONG WINAPI GetWindowLongA( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00001976{
1977 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1978}
1979
1980
1981/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001982 * GetWindowLongW (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001983 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001984LONG WINAPI GetWindowLongW( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00001985{
1986 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1987}
1988
1989
1990/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001991 * SetWindowLong (USER.136)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001992 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001993LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00001994{
1995 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1996}
1997
1998
1999/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002000 * SetWindowLongA (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002001 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002002LONG WINAPI SetWindowLongA( HWND hwnd, INT offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002003{
2004 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
2005}
2006
2007
2008/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002009 * SetWindowLongW (USER32.@) Set window attribute
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002010 *
2011 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
2012 * value in a window's extra memory.
2013 *
2014 * The _hwnd_ parameter specifies the window. is the handle to a
2015 * window that has extra memory. The _newval_ parameter contains the
2016 * new attribute or extra memory value. If positive, the _offset_
2017 * parameter is the byte-addressed location in the window's extra
2018 * memory to set. If negative, _offset_ specifies the window
2019 * attribute to set, and should be one of the following values:
2020 *
2021 * GWL_EXSTYLE The window's extended window style
2022 *
2023 * GWL_STYLE The window's window style.
2024 *
2025 * GWL_WNDPROC Pointer to the window's window procedure.
2026 *
2027 * GWL_HINSTANCE The window's pplication instance handle.
2028 *
2029 * GWL_ID The window's identifier.
2030 *
2031 * GWL_USERDATA The window's user-specified data.
2032 *
2033 * If the window is a dialog box, the _offset_ parameter can be one of
2034 * the following values:
2035 *
2036 * DWL_DLGPROC The address of the window's dialog box procedure.
2037 *
2038 * DWL_MSGRESULT The return value of a message
2039 * that the dialog box procedure processed.
2040 *
2041 * DWL_USER Application specific information.
2042 *
2043 * RETURNS
2044 *
2045 * If successful, returns the previous value located at _offset_. Otherwise,
2046 * returns 0.
2047 *
2048 * NOTES
2049 *
2050 * Extra memory for a window class is specified by a nonzero cbWndExtra
2051 * parameter of the WNDCLASS structure passed to RegisterClass() at the
2052 * time of class creation.
2053 *
2054 * Using GWL_WNDPROC to set a new window procedure effectively creates
2055 * a window subclass. Use CallWindowProc() in the new windows procedure
2056 * to pass messages to the superclass's window procedure.
2057 *
2058 * The user data is reserved for use by the application which created
2059 * the window.
2060 *
2061 * Do not use GWL_STYLE to change the window's WS_DISABLE style;
2062 * instead, call the EnableWindow() function to change the window's
2063 * disabled state.
2064 *
2065 * Do not use GWL_HWNDPARENT to reset the window's parent, use
2066 * SetParent() instead.
2067 *
Alexandre Julliard638f1691999-01-17 16:32:32 +00002068 * Win95:
2069 * When offset is GWL_STYLE and the calling app's ver is 4.0,
2070 * it sends WM_STYLECHANGING before changing the settings
2071 * and WM_STYLECHANGED afterwards.
2072 * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
2073 *
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002074 * BUGS
2075 *
Alexandre Julliard638f1691999-01-17 16:32:32 +00002076 * GWL_STYLE does not dispatch WM_STYLE... messages.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002077 *
2078 * CONFORMANCE
2079 *
2080 * ECMA-234, Win32
2081 *
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002082 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002083LONG WINAPI SetWindowLongW(
Patrik Stridvall2b3aa612000-12-01 23:58:28 +00002084 HWND hwnd, /* [in] window to alter */
2085 INT offset, /* [in] offset, in bytes, of location to alter */
2086 LONG newval /* [in] new value of location */
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002087) {
Alexandre Julliard3051b641996-07-05 17:14:13 +00002088 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002089}
2090
2091
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002092/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002093 * GetWindowText (USER.36)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002094 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002095INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002096{
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002097 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
Alexandre Julliard0e607781993-11-03 19:23:37 +00002098}
2099
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002100
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002101/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002102 * GetWindowTextA (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002103 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002104INT WINAPI GetWindowTextA( HWND hwnd, LPSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002105{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002106 return (INT)SendMessageA( hwnd, WM_GETTEXT, nMaxCount,
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002107 (LPARAM)lpString );
2108}
2109
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002110/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002111 * InternalGetWindowText (USER32.@)
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002112 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002113INT WINAPI InternalGetWindowText(HWND hwnd,LPWSTR lpString,INT nMaxCount )
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002114{
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00002115 WND *win = WIN_FindWndPtr( hwnd );
2116 if (!win) return 0;
2117 if (win->text) lstrcpynW( lpString, win->text, nMaxCount );
2118 else lpString[0] = 0;
2119 WIN_ReleaseWndPtr( win );
2120 return strlenW(lpString);
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002121}
2122
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002123
2124/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002125 * GetWindowTextW (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002126 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002127INT WINAPI GetWindowTextW( HWND hwnd, LPWSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002128{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002129 return (INT)SendMessageW( hwnd, WM_GETTEXT, nMaxCount,
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002130 (LPARAM)lpString );
2131}
2132
2133
2134/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002135 * SetWindowText (USER.37)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002136 */
Paul Quinn1beaae51998-12-15 15:38:36 +00002137BOOL16 WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002138{
Paul Quinn1beaae51998-12-15 15:38:36 +00002139 return (BOOL16)SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002140}
2141
2142
2143/*******************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +00002144 * SetWindowText (USER32.@)
2145 * SetWindowTextA (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002146 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002147BOOL WINAPI SetWindowTextA( HWND hwnd, LPCSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002148{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002149 return (BOOL)SendMessageA( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002150}
2151
2152
2153/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002154 * SetWindowTextW (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002155 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002156BOOL WINAPI SetWindowTextW( HWND hwnd, LPCWSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002157{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002158 return (BOOL)SendMessageW( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002159}
2160
2161
Alexandre Julliard0e607781993-11-03 19:23:37 +00002162/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002163 * GetWindowTextLength (USER.38)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002164 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002165INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002166{
Alexandre Julliardcb25e252001-08-08 23:28:42 +00002167 return (INT16)GetWindowTextLengthA( hwnd );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002168}
2169
2170
Alexandre Julliard0e607781993-11-03 19:23:37 +00002171/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002172 * GetWindowTextLengthA (USER32.@)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002173 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002174INT WINAPI GetWindowTextLengthA( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002175{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002176 return SendMessageA( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002177}
2178
2179/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002180 * GetWindowTextLengthW (USER32.@)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002181 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002182INT WINAPI GetWindowTextLengthW( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002183{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002184 return SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002185}
2186
Alexandre Julliard21979011997-03-05 08:22:35 +00002187
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002188/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002189 * IsWindow (USER.47)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002190 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002191BOOL16 WINAPI IsWindow16( HWND16 hwnd )
Alexandre Julliard21979011997-03-05 08:22:35 +00002192{
Alexandre Julliard4220b291999-07-11 17:20:01 +00002193 CURRENT_STACK16->es = USER_HeapSel;
Alexandre Julliarda3960291999-02-26 11:11:13 +00002194 return IsWindow( hwnd );
Alexandre Julliard21979011997-03-05 08:22:35 +00002195}
2196
2197
2198/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002199 * IsWindow (USER32.@)
Alexandre Julliard21979011997-03-05 08:22:35 +00002200 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002201BOOL WINAPI IsWindow( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002202{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002203 WND * wndPtr;
2204 BOOL retvalue;
2205
2206 if(!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
2207 retvalue = (wndPtr->dwMagic == WND_MAGIC);
2208 WIN_ReleaseWndPtr(wndPtr);
2209 return retvalue;
2210
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002211}
2212
2213
2214/*****************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002215 * GetParent (USER.46)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002216 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002217HWND16 WINAPI GetParent16( HWND16 hwnd )
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002218{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002219 return (HWND16)GetParent( hwnd );
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002220}
2221
2222
2223/*****************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002224 * GetParent (USER32.@)
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002225 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002226HWND WINAPI GetParent( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002227{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002228 WND *wndPtr;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002229 HWND retvalue = 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002230
2231 if(!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
2232 if ((!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD))))
Andreas Mohr1c20b392000-02-20 19:17:35 +00002233 goto end;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002234
Andreas Mohr1c20b392000-02-20 19:17:35 +00002235 WIN_UpdateWndPtr(&wndPtr,((wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner));
2236 if (wndPtr)
2237 retvalue = wndPtr->hwndSelf;
2238
2239end:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002240 WIN_ReleaseWndPtr(wndPtr);
2241 return retvalue;
2242
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002243}
2244
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002245/*****************************************************************
2246 * WIN_GetTopParent
2247 *
2248 * Get the top-level parent for a child window.
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002249 * returns a locked pointer
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002250 */
2251WND* WIN_GetTopParentPtr( WND* pWnd )
2252{
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002253 WND *tmpWnd = WIN_LockWndPtr(pWnd);
2254
2255 while( tmpWnd && (tmpWnd->dwStyle & WS_CHILD))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002256 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002257 WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002258 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002259 return tmpWnd;
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002260}
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002261
2262/*****************************************************************
2263 * WIN_GetTopParent
2264 *
2265 * Get the top-level parent for a child window.
2266 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002267HWND WIN_GetTopParent( HWND hwnd )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002268{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002269 HWND retvalue;
2270 WND *tmpPtr = WIN_FindWndPtr(hwnd);
2271 WND *wndPtr = WIN_GetTopParentPtr (tmpPtr );
2272
2273 retvalue = wndPtr ? wndPtr->hwndSelf : 0;
2274 WIN_ReleaseWndPtr(tmpPtr);
2275 WIN_ReleaseWndPtr(wndPtr);
2276 return retvalue;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002277}
2278
2279
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002280/*****************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002281 * SetParent (USER.233)
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002282 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002283HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002284{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002285 return SetParent( hwndChild, hwndNewParent );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002286}
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002287
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002288
2289/*****************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002290 * SetParent (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002291 */
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002292HWND WINAPI SetParent( HWND hwnd, HWND parent )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002293{
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002294 WND *wndPtr;
2295 WND *pWndParent;
2296 DWORD dwStyle;
2297 HWND retvalue;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002298
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002299 if (hwnd == GetDesktopWindow()) /* sanity check */
2300 {
2301 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
2302 return 0;
2303 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002304
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002305 if (USER_Driver.pSetParent)
2306 return USER_Driver.pSetParent( hwnd, parent );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002307
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002308 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002309
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002310 dwStyle = wndPtr->dwStyle;
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002311
Alexandre Julliardb19c57c2001-05-10 21:06:56 +00002312 if (!parent) parent = GetDesktopWindow();
2313
2314 if (!(pWndParent = WIN_FindWndPtr(parent)))
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002315 {
2316 WIN_ReleaseWndPtr( wndPtr );
2317 return 0;
2318 }
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002319
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002320 /* Windows hides the window first, then shows it again
2321 * including the WM_SHOWWINDOW messages and all */
2322 if (dwStyle & WS_VISIBLE) ShowWindow( hwnd, SW_HIDE );
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002323
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002324 retvalue = wndPtr->parent->hwndSelf; /* old parent */
2325 if (pWndParent != wndPtr->parent)
2326 {
2327 WIN_UnlinkWindow(wndPtr->hwndSelf);
2328 wndPtr->parent = pWndParent;
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002329
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002330 if (parent != GetDesktopWindow()) /* a child window */
2331 {
2332 if( !( wndPtr->dwStyle & WS_CHILD ) )
2333 {
2334 if( wndPtr->wIDmenu != 0)
2335 {
2336 DestroyMenu( (HMENU) wndPtr->wIDmenu );
2337 wndPtr->wIDmenu = 0;
2338 }
2339 }
2340 }
2341 WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
2342 }
2343 WIN_ReleaseWndPtr( pWndParent );
2344 WIN_ReleaseWndPtr( wndPtr );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002345
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002346 /* SetParent additionally needs to make hwnd the topmost window
2347 in the x-order and send the expected WM_WINDOWPOSCHANGING and
2348 WM_WINDOWPOSCHANGED notification messages.
2349 */
2350 SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
2351 SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|
2352 ((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
2353 /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
2354 * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
2355 return retvalue;
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002356}
2357
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002358
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002359/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002360 * IsChild (USER.48)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002361 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002362BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002363{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002364 return IsChild(parent,child);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002365}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002366
2367
Alexandre Julliard01d63461997-01-20 19:43:45 +00002368/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002369 * IsChild (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002370 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002371BOOL WINAPI IsChild( HWND parent, HWND child )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002372{
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002373 WND * wndPtr = WIN_FindWndPtr( child );
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00002374 while (wndPtr && wndPtr->parent)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002375 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002376 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00002377 if (wndPtr->hwndSelf == GetDesktopWindow()) break;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002378 if (wndPtr->hwndSelf == parent)
Andreas Mohr1c20b392000-02-20 19:17:35 +00002379 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002380 WIN_ReleaseWndPtr(wndPtr);
2381 return TRUE;
2382 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002383 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002384 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard0e607781993-11-03 19:23:37 +00002385 return FALSE;
2386}
2387
2388
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002389/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002390 * IsWindowVisible (USER.49)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002391 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002392BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002393{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002394 return IsWindowVisible(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002395}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002396
2397
Alexandre Julliard01d63461997-01-20 19:43:45 +00002398/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002399 * IsWindowVisible (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002400 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002401BOOL WINAPI IsWindowVisible( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002402{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002403 BOOL retval;
Alexandre Julliardded30381995-07-06 17:18:27 +00002404 WND *wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00002405 while (wndPtr && wndPtr->parent)
Alexandre Julliardded30381995-07-06 17:18:27 +00002406 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002407 if (!(wndPtr->dwStyle & WS_VISIBLE))
2408 {
2409 WIN_ReleaseWndPtr(wndPtr);
2410 return FALSE;
2411 }
2412 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
Alexandre Julliardded30381995-07-06 17:18:27 +00002413 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002414 retval = (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
2415 WIN_ReleaseWndPtr(wndPtr);
2416 return retval;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002417}
2418
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002419
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002420/***********************************************************************
2421 * WIN_IsWindowDrawable
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002422 *
2423 * hwnd is drawable when it is visible, all parents are not
2424 * minimized, and it is itself not minimized unless we are
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002425 * trying to draw its default class icon.
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002426 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002427BOOL WIN_IsWindowDrawable( WND* wnd, BOOL icon )
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002428{
Alexandre Julliard98779062000-12-07 23:39:16 +00002429 if (!(wnd->dwStyle & WS_VISIBLE)) return FALSE;
2430 if ((wnd->dwStyle & WS_MINIMIZE) &&
2431 icon && GetClassLongA( wnd->hwndSelf, GCL_HICON )) return FALSE;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002432 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
2433 if( wnd->dwStyle & WS_MINIMIZE ||
2434 !(wnd->dwStyle & WS_VISIBLE) ) break;
2435 return (wnd == NULL);
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002436}
2437
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002438
Alexandre Julliard0e607781993-11-03 19:23:37 +00002439/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002440 * GetTopWindow (USER.229)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002441 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002442HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002443{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002444 return GetTopWindow(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002445}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002446
2447
Alexandre Julliard01d63461997-01-20 19:43:45 +00002448/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002449 * GetTopWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002450 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002451HWND WINAPI GetTopWindow( HWND hwnd )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002452{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002453 HWND retval = 0;
2454 WND * wndPtr = (hwnd) ?
2455 WIN_FindWndPtr( hwnd ) : WIN_GetDesktop();
Francis Beaudetb7e8e801999-05-22 10:46:30 +00002456
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002457 if (wndPtr && wndPtr->child)
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002458 retval = wndPtr->child->hwndSelf;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002459
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002460 WIN_ReleaseWndPtr(wndPtr);
2461 return retval;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002462}
2463
2464
2465/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002466 * GetWindow (USER.262)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002467 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002468HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002469{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002470 return GetWindow( hwnd,rel );
Alexandre Julliard01d63461997-01-20 19:43:45 +00002471}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002472
2473
Alexandre Julliard01d63461997-01-20 19:43:45 +00002474/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002475 * GetWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002476 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002477HWND WINAPI GetWindow( HWND hwnd, WORD rel )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002478{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002479 HWND retval;
2480
Alexandre Julliard0e607781993-11-03 19:23:37 +00002481 WND * wndPtr = WIN_FindWndPtr( hwnd );
2482 if (!wndPtr) return 0;
2483 switch(rel)
2484 {
2485 case GW_HWNDFIRST:
Andreas Mohr1c20b392000-02-20 19:17:35 +00002486 retval = wndPtr->parent ? wndPtr->parent->child->hwndSelf : 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002487 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002488
2489 case GW_HWNDLAST:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002490 if (!wndPtr->parent)
2491 {
2492 retval = 0; /* Desktop window */
2493 goto end;
2494 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002495 while (wndPtr->next)
2496 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002497 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002498 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002499 retval = wndPtr->hwndSelf;
2500 goto end;
2501
2502 case GW_HWNDNEXT:
Andreas Mohr1c20b392000-02-20 19:17:35 +00002503 retval = wndPtr->next ? wndPtr->next->hwndSelf : 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002504 goto end;
2505
2506 case GW_HWNDPREV:
2507 if (!wndPtr->parent)
2508 {
2509 retval = 0; /* Desktop window */
2510 goto end;
2511 }
2512 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent->child); /* First sibling */
2513 if (wndPtr->hwndSelf == hwnd)
2514 {
2515 retval = 0; /* First in list */
2516 goto end;
2517 }
2518 while (wndPtr->next)
2519 {
2520 if (wndPtr->next->hwndSelf == hwnd)
Andreas Mohr1c20b392000-02-20 19:17:35 +00002521 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002522 retval = wndPtr->hwndSelf;
2523 goto end;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002524 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002525 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
2526 }
2527 retval = 0;
2528 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002529
2530 case GW_OWNER:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002531 retval = wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
2532 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002533
2534 case GW_CHILD:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002535 retval = wndPtr->child ? wndPtr->child->hwndSelf : 0;
2536 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002537 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002538 retval = 0;
2539end:
2540 WIN_ReleaseWndPtr(wndPtr);
2541 return retval;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002542}
2543
2544
2545/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002546 * GetNextWindow (USER.230)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002547 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002548HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002549{
2550 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
Alexandre Julliard01d63461997-01-20 19:43:45 +00002551 return GetWindow16( hwnd, flag );
Alexandre Julliard0e607781993-11-03 19:23:37 +00002552}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002553
Louis Philippe Gagnon06057e72000-08-20 03:40:59 +00002554/***********************************************************************
2555 * WIN_InternalShowOwnedPopups
2556 *
2557 * Internal version of ShowOwnedPopups; Wine functions should use this
2558 * to avoid interfering with application calls to ShowOwnedPopups
2559 * and to make sure the application can't prevent showing/hiding.
2560 *
2561 * Set unmanagedOnly to TRUE to show/hide unmanaged windows only.
2562 *
2563 */
2564
2565BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly )
2566{
2567 INT totalChild=0, count=0;
2568
2569 WND **pWnd = WIN_BuildWinArray(WIN_GetDesktop(), 0, &totalChild);
2570
2571 if (!pWnd) return TRUE;
2572
2573 /*
2574 * Show windows Lowest first, Highest last to preserve Z-Order
2575 */
2576 for (count = totalChild-1 ; count >=0; count--)
2577 {
2578 if (pWnd[count]->owner && (pWnd[count]->owner->hwndSelf == owner) && (pWnd[count]->dwStyle & WS_POPUP))
2579 {
2580 if (fShow)
2581 {
2582 /* check in window was flagged for showing in previous WIN_InternalShowOwnedPopups call */
2583 if (pWnd[count]->flags & WIN_NEEDS_INTERNALSOP)
2584 {
2585 /*
2586 * Call ShowWindow directly because an application can intercept WM_SHOWWINDOW messages
2587 */
2588 ShowWindow(pWnd[count]->hwndSelf,SW_SHOW);
2589 pWnd[count]->flags &= ~WIN_NEEDS_INTERNALSOP; /* remove the flag */
2590 }
2591 }
2592 else
2593 {
2594 if ( IsWindowVisible(pWnd[count]->hwndSelf) && /* hide only if window is visible */
2595 !( pWnd[count]->flags & WIN_NEEDS_INTERNALSOP ) && /* don't hide if previous call already did it */
Susan Farley557066d2000-10-13 17:07:08 +00002596 !( unmanagedOnly && (pWnd[count]->dwExStyle & WS_EX_MANAGED) ) ) /* don't hide managed windows if unmanagedOnly is TRUE */
Louis Philippe Gagnon06057e72000-08-20 03:40:59 +00002597 {
2598 /*
2599 * Call ShowWindow directly because an application can intercept WM_SHOWWINDOW messages
2600 */
2601 ShowWindow(pWnd[count]->hwndSelf,SW_HIDE);
2602 /* flag the window for showing on next WIN_InternalShowOwnedPopups call */
2603 pWnd[count]->flags |= WIN_NEEDS_INTERNALSOP;
2604 }
2605 }
2606 }
2607 }
2608 WIN_ReleaseDesktop();
2609 WIN_ReleaseWinArray(pWnd);
2610
2611 return TRUE;
2612}
2613
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002614/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002615 * ShowOwnedPopups (USER.265)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002616 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002617void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002618{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002619 ShowOwnedPopups( owner, fShow );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002620}
2621
2622
2623/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002624 * ShowOwnedPopups (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002625 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002626BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL fShow )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002627{
Noomen Hamzaa018d851999-09-28 16:26:09 +00002628 UINT totalChild=0, count=0;
2629
2630 WND **pWnd = WIN_BuildWinArray(WIN_GetDesktop(), 0, &totalChild);
2631
2632 if (!pWnd) return TRUE;
2633
2634 for (; count < totalChild; count++)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002635 {
Noomen Hamzaa018d851999-09-28 16:26:09 +00002636 if (pWnd[count]->owner && (pWnd[count]->owner->hwndSelf == owner) && (pWnd[count]->dwStyle & WS_POPUP))
Noomen Hamzaff727762000-02-18 19:11:04 +00002637 {
2638 if (fShow)
2639 {
2640 if (pWnd[count]->flags & WIN_NEEDS_SHOW_OWNEDPOPUP)
2641 {
Louis Philippe Gagnon06057e72000-08-20 03:40:59 +00002642 /*
2643 * In Windows, ShowOwnedPopups(TRUE) generates WM_SHOWWINDOW messages with SW_PARENTOPENING,
2644 * regardless of the state of the owner
2645 */
2646 SendMessageA(pWnd[count]->hwndSelf, WM_SHOWWINDOW, SW_SHOW, SW_PARENTOPENING);
Noomen Hamzaff727762000-02-18 19:11:04 +00002647 pWnd[count]->flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
2648 }
2649 }
2650 else
2651 {
2652 if (IsWindowVisible(pWnd[count]->hwndSelf))
2653 {
Louis Philippe Gagnon06057e72000-08-20 03:40:59 +00002654 /*
2655 * In Windows, ShowOwnedPopups(FALSE) generates WM_SHOWWINDOW messages with SW_PARENTCLOSING,
2656 * regardless of the state of the owner
2657 */
2658 SendMessageA(pWnd[count]->hwndSelf, WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING);
Noomen Hamzaff727762000-02-18 19:11:04 +00002659 pWnd[count]->flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
2660 }
2661 }
2662 }
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002663 }
Noomen Hamzaa018d851999-09-28 16:26:09 +00002664
2665 WIN_ReleaseDesktop();
2666 WIN_ReleaseWinArray(pWnd);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002667 return TRUE;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002668}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002669
2670
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002671/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002672 * GetLastActivePopup (USER.287)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002673 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002674HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002675{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002676 return GetLastActivePopup( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002677}
2678
2679/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002680 * GetLastActivePopup (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002681 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002682HWND WINAPI GetLastActivePopup( HWND hwnd )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002683{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002684 HWND retval;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002685 WND *wndPtr =WIN_FindWndPtr(hwnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002686 if (!wndPtr) return hwnd;
2687 retval = wndPtr->hwndLastActive;
2688 WIN_ReleaseWndPtr(wndPtr);
Gerard Patelef456af2000-12-15 21:29:13 +00002689 if ((retval != hwnd) && (!IsWindow(retval)))
2690 retval = hwnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002691 return retval;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002692}
2693
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002694
2695/*******************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002696 * WIN_BuildWinArray
2697 *
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002698 * Build an array of pointers to the children of a given window.
Alexandre Julliard90476d62000-02-16 22:47:24 +00002699 * The array must be freed with WIN_ReleaseWinArray. Return NULL
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002700 * when no windows are found.
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002701 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002702WND **WIN_BuildWinArray( WND *wndPtr, UINT bwaFlags, UINT* pTotal )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002703{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002704 /* Future: this function will lock all windows associated with this array */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002705
Alexandre Julliard3051b641996-07-05 17:14:13 +00002706 WND **list, **ppWnd;
2707 WND *pWnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002708 UINT count = 0, skipOwned, skipHidden;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002709 DWORD skipFlags;
2710
2711 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2712 skipOwned = bwaFlags & BWA_SKIPOWNED;
2713 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2714 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002715
2716 /* First count the windows */
2717
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002718 if (!wndPtr)
2719 wndPtr = WIN_GetDesktop();
2720
2721 pWnd = WIN_LockWndPtr(wndPtr->child);
2722 while (pWnd)
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002723 {
Alex Korobka44a1b591999-04-01 12:03:52 +00002724 if( !(pWnd->dwStyle & skipFlags) && !(skipOwned && pWnd->owner) &&
2725 (!skipHidden || (pWnd->dwStyle & WS_VISIBLE)) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002726 count++;
Alex Korobka44a1b591999-04-01 12:03:52 +00002727 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002728 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002729
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002730 if( count )
2731 {
2732 /* Now build the list of all windows */
Alexandre Julliard3051b641996-07-05 17:14:13 +00002733
Alexandre Julliard90476d62000-02-16 22:47:24 +00002734 if ((list = (WND **)HeapAlloc( GetProcessHeap(), 0, sizeof(WND *) * (count + 1))))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002735 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002736 for (pWnd = WIN_LockWndPtr(wndPtr->child), ppWnd = list, count = 0; pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002737 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002738 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) );
2739 else if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002740 {
2741 *ppWnd++ = pWnd;
2742 count++;
2743 }
2744 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002745 WIN_ReleaseWndPtr(pWnd);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002746 *ppWnd = NULL;
2747 }
2748 else count = 0;
2749 } else list = NULL;
2750
2751 if( pTotal ) *pTotal = count;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002752 return list;
2753}
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002754/*******************************************************************
2755 * WIN_ReleaseWinArray
2756 */
2757void WIN_ReleaseWinArray(WND **wndArray)
2758{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002759 /* Future: this function will also unlock all windows associated with wndArray */
Alexandre Julliard90476d62000-02-16 22:47:24 +00002760 HeapFree( GetProcessHeap(), 0, wndArray );
Alexandre Julliard3051b641996-07-05 17:14:13 +00002761
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002762}
Alexandre Julliard3051b641996-07-05 17:14:13 +00002763
2764/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002765 * EnumWindows (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002766 */
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002767BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002768{
2769 WND **list, **ppWnd;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002770
Alexandre Julliard594997c1995-04-30 10:05:20 +00002771 /* We have to build a list of all windows first, to avoid */
Andreas Mohr1c20b392000-02-20 19:17:35 +00002772 /* unpleasant side-effects, for instance if the callback */
2773 /* function changes the Z-order of the windows. */
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002774
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002775 if (!(list = WIN_BuildWinArray(WIN_GetDesktop(), 0, NULL )))
2776 {
2777 WIN_ReleaseDesktop();
2778 return FALSE;
2779 }
Alexandre Julliard594997c1995-04-30 10:05:20 +00002780
Alexandre Julliard3051b641996-07-05 17:14:13 +00002781 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002782
Alexandre Julliard3051b641996-07-05 17:14:13 +00002783 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002784 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002785 LRESULT lpEnumFuncRetval;
2786 int iWndsLocks = 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002787 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002788 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Francois Boisvertd96bc151999-04-02 10:34:43 +00002789
2790 /* To avoid any deadlocks, all the locks on the windows
2791 structures must be suspended before the control
2792 is passed to the application */
2793 iWndsLocks = WIN_SuspendWndsLock();
2794 lpEnumFuncRetval = lpEnumFunc( (*ppWnd)->hwndSelf, lParam);
2795 WIN_RestoreWndsLock(iWndsLocks);
2796
2797 if (!lpEnumFuncRetval) break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002798 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002799 WIN_ReleaseWinArray(list);
2800 WIN_ReleaseDesktop();
Alexandre Julliard3051b641996-07-05 17:14:13 +00002801 return TRUE;
2802}
2803
2804
Alexandre Julliard594997c1995-04-30 10:05:20 +00002805/**********************************************************************
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002806 * WIN_EnumQueueWindows
2807 *
2808 * Helper for EnumTaskWindows16 and EnumThreadWindows.
Alexandre Julliard594997c1995-04-30 10:05:20 +00002809 */
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002810static BOOL WIN_EnumQueueWindows( HQUEUE16 queue, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliard594997c1995-04-30 10:05:20 +00002811{
Alexandre Julliard3051b641996-07-05 17:14:13 +00002812 WND **list, **ppWnd;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002813
2814 /* This function is the same as EnumWindows(), */
Per Ångströma47bc3a1998-11-14 17:00:37 +00002815 /* except for an added check on the window's task. */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002816
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002817 if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
2818 {
2819 WIN_ReleaseDesktop();
2820 return FALSE;
2821 }
Alexandre Julliard594997c1995-04-30 10:05:20 +00002822
Alexandre Julliard3051b641996-07-05 17:14:13 +00002823 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002824
Alexandre Julliard3051b641996-07-05 17:14:13 +00002825 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002826 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002827 LRESULT funcRetval;
2828 int iWndsLocks = 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002829 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002830 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002831 if ((*ppWnd)->hmemTaskQ != queue) continue;
2832
Francois Boisvertd96bc151999-04-02 10:34:43 +00002833 /* To avoid any deadlocks, all the locks on the windows
2834 structures must be suspended before the control
2835 is passed to the application */
2836 iWndsLocks = WIN_SuspendWndsLock();
2837 funcRetval = func( (*ppWnd)->hwndSelf, lParam );
2838 WIN_RestoreWndsLock(iWndsLocks);
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002839
Francois Boisvertd96bc151999-04-02 10:34:43 +00002840 if (!funcRetval) break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002841 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002842 WIN_ReleaseWinArray(list);
2843 WIN_ReleaseDesktop();
Alexandre Julliard594997c1995-04-30 10:05:20 +00002844 return TRUE;
2845}
2846
2847
Alexandre Julliard3051b641996-07-05 17:14:13 +00002848/**********************************************************************
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002849 * EnumTaskWindows16 (USER.225)
2850 */
2851BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2852 LPARAM lParam )
2853{
2854 HQUEUE16 queue = GetTaskQueue16( hTask );
2855 if (!queue) return FALSE;
2856 return WIN_EnumQueueWindows( queue, (WNDENUMPROC)func, lParam );
2857}
2858
2859
2860/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002861 * EnumThreadWindows (USER32.@)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002862 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002863BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002864{
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002865 HQUEUE16 queue = GetThreadQueue16( id );
2866 if (!queue) return FALSE;
2867 return WIN_EnumQueueWindows( queue, func, lParam );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002868}
2869
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002870
Alexandre Julliard3051b641996-07-05 17:14:13 +00002871/**********************************************************************
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002872 * WIN_EnumChildWindows
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002873 *
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002874 * Helper function for EnumChildWindows().
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002875 */
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002876static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002877{
Alexandre Julliard3051b641996-07-05 17:14:13 +00002878 WND **childList;
2879 BOOL16 ret = FALSE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002880
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002881 for ( ; *ppWnd; ppWnd++)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002882 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002883 int iWndsLocks = 0;
2884
Alexandre Julliard3051b641996-07-05 17:14:13 +00002885 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002886 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002887 /* Build children list first */
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002888 childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
Francois Boisvertd96bc151999-04-02 10:34:43 +00002889
2890 /* To avoid any deadlocks, all the locks on the windows
2891 structures must be suspended before the control
2892 is passed to the application */
2893 iWndsLocks = WIN_SuspendWndsLock();
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002894 ret = func( (*ppWnd)->hwndSelf, lParam );
Francois Boisvertd96bc151999-04-02 10:34:43 +00002895 WIN_RestoreWndsLock(iWndsLocks);
2896
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002897 if (childList)
2898 {
2899 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002900 WIN_ReleaseWinArray(childList);
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002901 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002902 if (!ret) return FALSE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002903 }
2904 return TRUE;
2905}
2906
2907
2908/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002909 * EnumChildWindows (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002910 */
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002911BOOL WINAPI EnumChildWindows( HWND parent, WNDENUMPROC func,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002912 LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002913{
2914 WND **list, *pParent;
2915
2916 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002917 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL )))
2918 {
2919 WIN_ReleaseWndPtr(pParent);
2920 return FALSE;
2921 }
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002922 WIN_EnumChildWindows( list, func, lParam );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002923 WIN_ReleaseWinArray(list);
2924 WIN_ReleaseWndPtr(pParent);
Alexandre Julliard3051b641996-07-05 17:14:13 +00002925 return TRUE;
2926}
2927
2928
Alexandre Julliard58199531994-04-21 01:20:00 +00002929/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002930 * AnyPopup (USER.52)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002931 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002932BOOL16 WINAPI AnyPopup16(void)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002933{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002934 return AnyPopup();
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002935}
2936
2937
2938/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002939 * AnyPopup (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002940 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002941BOOL WINAPI AnyPopup(void)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002942{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002943 WND *wndPtr = WIN_LockWndPtr(pWndDesktop->child);
2944 BOOL retvalue;
2945
2946 while (wndPtr)
2947 {
2948 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE))
2949 {
2950 retvalue = TRUE;
2951 goto end;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002952 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002953 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
2954 }
2955 retvalue = FALSE;
2956end:
2957 WIN_ReleaseWndPtr(wndPtr);
2958 return retvalue;
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002959}
2960
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002961
Alexandre Julliard73450d61994-05-18 18:29:32 +00002962/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002963 * FlashWindow (USER.105)
Alexandre Julliard73450d61994-05-18 18:29:32 +00002964 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002965BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002966{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002967 return FlashWindow( hWnd, bInvert );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002968}
2969
2970
2971/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002972 * FlashWindow (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002973 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002974BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert )
Alexandre Julliard73450d61994-05-18 18:29:32 +00002975{
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002976 WND *wndPtr = WIN_FindWndPtr(hWnd);
2977
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002978 TRACE("%04x\n", hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002979
2980 if (!wndPtr) return FALSE;
2981
2982 if (wndPtr->dwStyle & WS_MINIMIZE)
2983 {
2984 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2985 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002986 HDC hDC = GetDC(hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002987
Alexandre Julliardcb25e252001-08-08 23:28:42 +00002988 if (!SendMessageW( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002989 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2990
Alexandre Julliarda3960291999-02-26 11:11:13 +00002991 ReleaseDC( hWnd, hDC );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002992 wndPtr->flags |= WIN_NCACTIVATED;
2993 }
2994 else
2995 {
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002996 RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_FRAME );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002997 wndPtr->flags &= ~WIN_NCACTIVATED;
2998 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002999 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003000 return TRUE;
3001 }
3002 else
3003 {
Alexandre Julliard530ee841996-10-23 16:59:13 +00003004 WPARAM16 wparam;
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003005 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
Alexandre Julliarda3960291999-02-26 11:11:13 +00003006 else wparam = (hWnd == GetActiveWindow());
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003007
Alexandre Julliardcb25e252001-08-08 23:28:42 +00003008 SendMessageW( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003009 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00003010 return wparam;
3011 }
Alexandre Julliard73450d61994-05-18 18:29:32 +00003012}
3013
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003014
3015/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003016 * SetSysModalWindow (USER.188)
Alexandre Julliard58199531994-04-21 01:20:00 +00003017 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003018HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
Alexandre Julliard58199531994-04-21 01:20:00 +00003019{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003020 HWND hWndOldModal = hwndSysModal;
Alexandre Julliardd4719651995-12-12 18:49:11 +00003021 hwndSysModal = hWnd;
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00003022 FIXME("EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
Alexandre Julliardd4719651995-12-12 18:49:11 +00003023 return hWndOldModal;
Alexandre Julliard58199531994-04-21 01:20:00 +00003024}
3025
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003026
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003027/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003028 * GetSysModalWindow (USER.189)
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003029 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003030HWND16 WINAPI GetSysModalWindow16(void)
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003031{
Alexandre Julliardd4719651995-12-12 18:49:11 +00003032 return hwndSysModal;
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003033}
Alexandre Julliardade697e1995-11-26 13:59:11 +00003034
Alexandre Julliard18f92e71996-07-17 20:02:21 +00003035
Alexandre Julliardade697e1995-11-26 13:59:11 +00003036/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003037 * GetWindowContextHelpId (USER32.@)
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003038 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003039DWORD WINAPI GetWindowContextHelpId( HWND hwnd )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003040{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003041 DWORD retval;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003042 WND *wnd = WIN_FindWndPtr( hwnd );
3043 if (!wnd) return 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003044 retval = wnd->helpContext;
3045 WIN_ReleaseWndPtr(wnd);
3046 return retval;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003047}
3048
3049
3050/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003051 * SetWindowContextHelpId (USER32.@)
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003052 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003053BOOL WINAPI SetWindowContextHelpId( HWND hwnd, DWORD id )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003054{
3055 WND *wnd = WIN_FindWndPtr( hwnd );
3056 if (!wnd) return FALSE;
3057 wnd->helpContext = id;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003058 WIN_ReleaseWndPtr(wnd);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003059 return TRUE;
3060}
3061
3062
3063/*******************************************************************
Alexandre Julliardade697e1995-11-26 13:59:11 +00003064 * DRAG_QueryUpdate
3065 *
3066 * recursively find a child that contains spDragInfo->pt point
3067 * and send WM_QUERYDROPOBJECT
3068 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003069BOOL16 DRAG_QueryUpdate( HWND hQueryWnd, SEGPTR spDragInfo, BOOL bNoSend )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003070{
Andreas Mohr1c20b392000-02-20 19:17:35 +00003071 BOOL16 wParam, bResult = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003072 POINT pt;
Alexandre Julliard982a2232000-12-13 20:20:09 +00003073 LPDRAGINFO16 ptrDragInfo = MapSL(spDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003074 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003075 RECT tempRect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003076
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003077 if( !ptrQueryWnd || !ptrDragInfo )
Andreas Mohr1c20b392000-02-20 19:17:35 +00003078 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003079
Alexandre Julliardd37eb361997-07-20 16:23:21 +00003080 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003081
Alexandre Julliarda3960291999-02-26 11:11:13 +00003082 GetWindowRect(hQueryWnd,&tempRect);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003083
Alexandre Julliarda3960291999-02-26 11:11:13 +00003084 if( !PtInRect(&tempRect,pt) ||
Alexandre Julliardade697e1995-11-26 13:59:11 +00003085 (ptrQueryWnd->dwStyle & WS_DISABLED) )
Andreas Mohr1c20b392000-02-20 19:17:35 +00003086 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003087
3088 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
3089 {
3090 tempRect = ptrQueryWnd->rectClient;
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00003091 if(ptrQueryWnd->parent)
Alexandre Julliarda3960291999-02-26 11:11:13 +00003092 MapWindowPoints( ptrQueryWnd->parent->hwndSelf, 0,
3093 (LPPOINT)&tempRect, 2 );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003094
Alexandre Julliarda3960291999-02-26 11:11:13 +00003095 if (PtInRect( &tempRect, pt))
Alexandre Julliardade697e1995-11-26 13:59:11 +00003096 {
3097 wParam = 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003098
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003099 for (ptrWnd = WIN_LockWndPtr(ptrQueryWnd->child); ptrWnd ;WIN_UpdateWndPtr(&ptrWnd,ptrWnd->next))
3100 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003101 if( ptrWnd->dwStyle & WS_VISIBLE )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003102 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003103 GetWindowRect( ptrWnd->hwndSelf, &tempRect );
3104 if (PtInRect( &tempRect, pt )) break;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003105 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003106 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003107
3108 if(ptrWnd)
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003109 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +00003110 TRACE_(msg)("hwnd = %04x, %d %d - %d %d\n",
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003111 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
3112 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
3113 if( !(ptrWnd->dwStyle & WS_DISABLED) )
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003114 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003115
3116 WIN_ReleaseWndPtr(ptrWnd);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003117 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003118
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003119 if(bResult)
Andreas Mohr1c20b392000-02-20 19:17:35 +00003120 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003121 }
3122 else wParam = 1;
3123 }
3124 else wParam = 1;
3125
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00003126 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003127
3128 ptrDragInfo->hScope = hQueryWnd;
3129
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003130 bResult = ( bNoSend )
3131 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
3132 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
Alexandre Julliard530ee841996-10-23 16:59:13 +00003133 (WPARAM16)wParam ,(LPARAM) spDragInfo );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003134 if( !bResult )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00003135 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003136
Andreas Mohr1c20b392000-02-20 19:17:35 +00003137end:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003138 WIN_ReleaseWndPtr(ptrQueryWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003139 return bResult;
3140}
3141
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003142
Alexandre Julliardade697e1995-11-26 13:59:11 +00003143/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003144 * DragDetect (USER.465)
Alexandre Julliardade697e1995-11-26 13:59:11 +00003145 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003146BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003147{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003148 POINT pt32;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003149 CONV_POINT16TO32( &pt, &pt32 );
Alexandre Julliarda3960291999-02-26 11:11:13 +00003150 return DragDetect( hWnd, pt32 );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003151}
3152
3153/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003154 * DragDetect (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003155 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003156BOOL WINAPI DragDetect( HWND hWnd, POINT pt )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003157{
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003158 MSG msg;
3159 RECT rect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003160
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003161 rect.left = pt.x - wDragWidth;
3162 rect.right = pt.x + wDragWidth;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003163
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003164 rect.top = pt.y - wDragHeight;
3165 rect.bottom = pt.y + wDragHeight;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003166
Alexandre Julliarda3960291999-02-26 11:11:13 +00003167 SetCapture(hWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003168
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003169 while(1)
3170 {
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003171 while(PeekMessageA(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003172 {
3173 if( msg.message == WM_LBUTTONUP )
3174 {
3175 ReleaseCapture();
3176 return 0;
3177 }
3178 if( msg.message == WM_MOUSEMOVE )
3179 {
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003180 POINT tmp;
3181 tmp.x = LOWORD(msg.lParam);
3182 tmp.y = HIWORD(msg.lParam);
3183 if( !PtInRect( &rect, tmp ))
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/******************************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003196 * DragObject (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 Julliard0ff083b2000-09-24 19:51:15 +00003201 MSG msg;
Alexandre Julliard83f52d12000-09-26 22:20:14 +00003202 LPDRAGINFO16 lpDragInfo;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003203 SEGPTR spDragInfo;
3204 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
Alexandre Julliard83f52d12000-09-26 22:20:14 +00003205 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO16));
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003206 WND *wndPtr = WIN_FindWndPtr(hWnd);
3207 HCURSOR16 hCurrentCursor = 0;
3208 HWND16 hCurrentWnd = 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003209
Alexandre Julliard83f52d12000-09-26 22:20:14 +00003210 lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
Alexandre Julliard58017232000-12-22 01:09:26 +00003211 spDragInfo = K32WOWGlobalLock16(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 Julliard8bb7fb92001-01-20 02:48:30 +00003219 hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO));
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(); }
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003256 while( !PeekMessageA(&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 Julliard0ff083b2000-09-24 19:51:15 +00003260 lpDragInfo->pt.x = msg.pt.x;
3261 lpDragInfo->pt.y = msg.pt.y;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003262
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003263 /* update DRAGINFO struct */
Alexandre Julliard06c275a1999-05-02 14:32:27 +00003264 TRACE_(msg)("lpDI->hScope = %04x\n",lpDragInfo->hScope);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003265
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003266 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
3267 hCurrentCursor = hCursor;
3268 else
Alexandre Julliardade697e1995-11-26 13:59:11 +00003269 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003270 hCurrentCursor = hBummer;
3271 lpDragInfo->hScope = 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003272 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003273 if( hCurrentCursor )
Alexandre Julliarda3960291999-02-26 11:11:13 +00003274 SetCursor(hCurrentCursor);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003275
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003276 /* send WM_DRAGLOOP */
3277 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
3278 (LPARAM) spDragInfo );
3279 /* send WM_DRAGSELECT or WM_DRAGMOVE */
3280 if( hCurrentWnd != lpDragInfo->hScope )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003281 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003282 if( hCurrentWnd )
3283 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
Alexandre Julliard83f52d12000-09-26 22:20:14 +00003284 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO16),
Alexandre Julliardade697e1995-11-26 13:59:11 +00003285 HIWORD(spDragInfo)) );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003286 hCurrentWnd = lpDragInfo->hScope;
3287 if( hCurrentWnd )
3288 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003289 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003290 else
3291 if( hCurrentWnd )
3292 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
3293
3294 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
3295
3296 ReleaseCapture();
Alexandre Julliarda3960291999-02-26 11:11:13 +00003297 ShowCursor( FALSE );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003298
3299 if( hCursor )
3300 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003301 SetCursor( hOldCursor );
3302 if (hDragCursor) DestroyCursor( hDragCursor );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003303 }
3304
3305 if( hCurrentCursor != hBummer )
3306 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
3307 (WPARAM16)hWnd, (LPARAM)spDragInfo );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003308 else
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003309 msg.lParam = 0;
3310 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003311 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003312
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003313 return (DWORD)(msg.lParam);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003314}
Eric Kohlca6c9a62001-03-20 01:53:51 +00003315
3316
3317/******************************************************************************
3318 * GetWindowModuleFileNameA (USER32.@)
3319 */
3320UINT WINAPI GetWindowModuleFileNameA( HWND hwnd, LPSTR lpszFileName, UINT cchFileNameMax)
3321{
3322 FIXME("GetWindowModuleFileNameA(hwnd 0x%x, lpszFileName %p, cchFileNameMax %u) stub!\n",
3323 hwnd, lpszFileName, cchFileNameMax);
3324 return 0;
3325}
3326
3327/******************************************************************************
3328 * GetWindowModuleFileNameW (USER32.@)
3329 */
3330UINT WINAPI GetWindowModuleFileNameW( HWND hwnd, LPSTR lpszFileName, UINT cchFileNameMax)
3331{
3332 FIXME("GetWindowModuleFileNameW(hwnd 0x%x, lpszFileName %p, cchFileNameMax %u) stub!\n",
3333 hwnd, lpszFileName, cchFileNameMax);
3334 return 0;
3335}