blob: ed9d7a7f5604d5e66180000ffd5638a058ed9317 [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
Noel Borthwickb4278561999-02-05 10:37:53 +0000441 WINPOS_CheckInternalPos( wndPtr );
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
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000712 /* Create the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000713
Alexandre Julliard98779062000-12-07 23:39:16 +0000714 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + wndExtra - sizeof(wndPtr->wExtra) )))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000715 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000716 TRACE("out of memory\n" );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000717 return 0;
718 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000719
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000720 /* Fill the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000721
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000722 wndPtr = WIN_LockWndPtr((WND *) USER_HEAP_LIN_ADDR( hwnd ));
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000723 wndPtr->next = NULL;
724 wndPtr->child = NULL;
725
Alexandre Julliard3db94ef1997-09-28 17:43:24 +0000726 if ((cs->style & WS_CHILD) && cs->hwndParent)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000727 {
728 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
729 wndPtr->owner = NULL;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000730 WIN_ReleaseWndPtr(wndPtr->parent);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000731 }
732 else
733 {
734 wndPtr->parent = pWndDesktop;
735 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
736 wndPtr->owner = NULL;
737 else
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000738 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000739 WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
740 wndPtr->owner = WIN_GetTopParentPtr(tmpWnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000741 WIN_ReleaseWndPtr(wndPtr->owner);
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000742 WIN_ReleaseWndPtr(tmpWnd);
Slava Monicha27807d1999-06-05 11:46:35 +0000743 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000744 }
Slava Monicha27807d1999-06-05 11:46:35 +0000745
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000746
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000747 wndPtr->class = classPtr;
Alexandre Julliard98779062000-12-07 23:39:16 +0000748 wndPtr->winproc = winproc;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000749 wndPtr->dwMagic = WND_MAGIC;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000750 wndPtr->hwndSelf = hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000751 wndPtr->hInstance = cs->hInstance;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000752 wndPtr->text = NULL;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000753 wndPtr->hmemTaskQ = GetFastQueue16();
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000754 wndPtr->hrgnUpdate = 0;
Huw D M Daviesa14ca862000-07-29 11:31:29 +0000755 wndPtr->hrgnWnd = 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000756 wndPtr->hwndLastActive = hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000757 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
758 wndPtr->dwExStyle = cs->dwExStyle;
Alexandre Julliard98779062000-12-07 23:39:16 +0000759 wndPtr->clsStyle = clsStyle;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000760 wndPtr->wIDmenu = 0;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +0000761 wndPtr->helpContext = 0;
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000762 wndPtr->flags = (type == WIN_PROC_16) ? 0 : WIN_ISWIN32;
Alexandre Julliardca22b331996-07-12 19:02:39 +0000763 wndPtr->pVScroll = NULL;
764 wndPtr->pHScroll = NULL;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000765 wndPtr->pProp = NULL;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000766 wndPtr->userdata = 0;
Alexandre Julliard7ff1c411997-05-25 13:58:18 +0000767 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
768 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
Alexandre Julliard98779062000-12-07 23:39:16 +0000769 wndPtr->cbWndExtra = wndExtra;
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +0000770 wndPtr->irefCount = 1;
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000771
Alexandre Julliard98779062000-12-07 23:39:16 +0000772 if (wndExtra) memset( wndPtr->wExtra, 0, wndExtra);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000773
774 /* Call the WH_CBT hook */
775
NF Stevens181fa7c1998-12-14 14:37:06 +0000776 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
777 ? HWND_BOTTOM : HWND_TOP;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000778
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000779 if (HOOK_IsHooked( WH_CBT ))
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000780 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000781 CBT_CREATEWNDA cbtc;
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000782 LRESULT ret;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000783
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000784 cbtc.lpcs = cs;
785 cbtc.hwndInsertAfter = hwndLinkAfter;
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000786 ret = (type == WIN_PROC_32W) ? HOOK_CallHooksW(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc)
Alexandre Julliarda3960291999-02-26 11:11:13 +0000787 : HOOK_CallHooksA(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc);
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000788 if (ret)
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000789 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +0000790 TRACE("CBT-hook returned 0\n");
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000791 USER_HEAP_FREE( hwnd );
Alexandre Julliard98779062000-12-07 23:39:16 +0000792 CLASS_RemoveWindow( classPtr );
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000793 hwnd = 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000794 goto end;
Alexandre Julliard7e6ae4b1996-12-08 19:25:27 +0000795 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000796 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000797
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000798 /* Correct the window style */
799
Alex Korobka44a1b591999-04-01 12:03:52 +0000800 if (!(cs->style & WS_CHILD))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000801 {
Alex Korobka44a1b591999-04-01 12:03:52 +0000802 wndPtr->dwStyle |= WS_CLIPSIBLINGS;
803 if (!(cs->style & WS_POPUP))
804 {
805 wndPtr->dwStyle |= WS_CAPTION;
806 wndPtr->flags |= WIN_NEED_SIZE;
807 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000808 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000809
810 /* Get class or window DC if needed */
Alexandre Julliardaca05781994-10-17 18:12:41 +0000811
Alexandre Julliard98779062000-12-07 23:39:16 +0000812 if (clsStyle & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
813 else if (clsStyle & CS_CLASSDC) wndPtr->dce = dce;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +0000814 else wndPtr->dce = NULL;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000815
Alexandre Julliard5e9dab52000-06-07 02:03:19 +0000816 /* Initialize the dimensions before sending WM_GETMINMAXINFO */
817
818 wndPtr->rectWindow.left = cs->x;
819 wndPtr->rectWindow.top = cs->y;
820 wndPtr->rectWindow.right = cs->x + cs->cx;
821 wndPtr->rectWindow.bottom = cs->y + cs->cy;
822 wndPtr->rectClient = wndPtr->rectWindow;
823
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000824 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
Alexandre Julliard988ca971994-06-21 16:15:21 +0000825
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000826 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000827 {
Alexandre Julliardd37eb361997-07-20 16:23:21 +0000828 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000829 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
830 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
Alexandre Julliardac9c9b01996-07-28 18:50:11 +0000831 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
832 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000833 }
Alexandre Julliard44ed71f1997-12-21 19:17:50 +0000834
Lawson Whitney68dd6792000-06-25 12:53:27 +0000835 if (cs->cx < 0) cs->cx = 0;
836 if (cs->cy < 0) cs->cy = 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000837
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000838 wndPtr->rectWindow.left = cs->x;
839 wndPtr->rectWindow.top = cs->y;
840 wndPtr->rectWindow.right = cs->x + cs->cx;
841 wndPtr->rectWindow.bottom = cs->y + cs->cy;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000842 wndPtr->rectClient = wndPtr->rectWindow;
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000843
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000844 /* Set the window menu */
845
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000846 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000847 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000848 if (cs->hMenu) SetMenu(hwnd, cs->hMenu);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000849 else
850 {
Alexandre Julliardac7efef2000-11-27 21:54:01 +0000851 LPCSTR menuName = (LPCSTR)GetClassLongA( hwnd, GCL_MENUNAME );
Alexandre Julliard54c27111998-03-29 19:44:57 +0000852 if (menuName)
853 {
Ulrich Weigand7df1fbb1998-11-01 18:01:53 +0000854 if (HIWORD(cs->hInstance))
Alexandre Julliardac7efef2000-11-27 21:54:01 +0000855 cs->hMenu = LoadMenuA(cs->hInstance,menuName);
Alexandre Julliard54c27111998-03-29 19:44:57 +0000856 else
Alexandre Julliard54c27111998-03-29 19:44:57 +0000857 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
858
Alexandre Julliarda3960291999-02-26 11:11:13 +0000859 if (cs->hMenu) SetMenu( hwnd, cs->hMenu );
Alexandre Julliard54c27111998-03-29 19:44:57 +0000860 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000861 }
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000862 }
Alexandre Julliarda3960291999-02-26 11:11:13 +0000863 else wndPtr->wIDmenu = (UINT)cs->hMenu;
Alexandre Julliard490a27e1994-06-08 13:57:50 +0000864
Gerard Patelad363032001-06-06 21:26:50 +0000865 if (!USER_Driver.pCreateWindow( wndPtr->hwndSelf, cs, unicode))
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000866 {
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000867 WARN("aborted by WM_xxCREATE!\n");
868 WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
869 CLASS_RemoveWindow( classPtr );
870 WIN_ReleaseWndPtr(wndPtr);
871 return 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000872 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000873
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000874 if( (wndPtr->dwStyle & WS_CHILD) && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
875 {
876 /* Notify the parent window only */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000877
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000878 SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
879 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
880 if( !IsWindow(hwnd) )
881 {
882 hwnd = 0;
883 goto end;
884 }
885 }
886
887 if (cs->style & WS_VISIBLE)
888 {
889 /* in case WS_VISIBLE got set in the meantime */
890 wndPtr->dwStyle &= ~WS_VISIBLE;
891 ShowWindow( hwnd, sw );
892 }
893
894 /* Call WH_SHELL hook */
895
896 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
897 HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
898
899 TRACE("created window %04x\n", hwnd);
900 end:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000901 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliarddc4fe772001-06-04 21:55:17 +0000902 return hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000903}
904
905
906/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000907 * CreateWindow (USER.41)
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000908 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000909HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
910 DWORD style, INT16 x, INT16 y, INT16 width,
911 INT16 height, HWND16 parent, HMENU16 menu,
912 HINSTANCE16 instance, LPVOID data )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000913{
914 return CreateWindowEx16( 0, className, windowName, style,
915 x, y, width, height, parent, menu, instance, data );
916}
917
918
919/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000920 * CreateWindowEx (USER.452)
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000921 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000922HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
923 LPCSTR windowName, DWORD style, INT16 x,
924 INT16 y, INT16 width, INT16 height,
925 HWND16 parent, HMENU16 menu,
926 HINSTANCE16 instance, LPVOID data )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000927{
928 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000929 CREATESTRUCTA cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +0000930 char buffer[256];
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000931
932 /* Find the class atom */
933
Gerard Patel6fdb5dd2000-02-16 21:23:24 +0000934 if (HIWORD(className))
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000935 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +0000936 if (!(classAtom = GlobalFindAtomA( className )))
937 {
938 ERR( "bad class name %s\n", debugres_a(className) );
939 return 0;
940 }
941 }
942 else
943 {
944 classAtom = LOWORD(className);
945 if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
946 {
947 ERR( "bad atom %x\n", classAtom);
948 return 0;
949 }
950 className = buffer;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000951 }
952
953 /* Fix the coordinates */
954
Alexandre Julliarda3960291999-02-26 11:11:13 +0000955 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)x;
956 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)y;
957 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)width;
958 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT : (INT)height;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000959
960 /* Create the window */
961
962 cs.lpCreateParams = data;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000963 cs.hInstance = (HINSTANCE)instance;
964 cs.hMenu = (HMENU)menu;
965 cs.hwndParent = (HWND)parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000966 cs.style = style;
967 cs.lpszName = windowName;
968 cs.lpszClass = className;
969 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +0000970
Dmitry Timoshkov5956b982000-11-28 23:53:08 +0000971 return WIN_CreateWindowEx( &cs, classAtom, WIN_PROC_16 );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000972}
973
974
975/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +0000976 * CreateWindowExA (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000977 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000978HWND WINAPI CreateWindowExA( DWORD exStyle, LPCSTR className,
979 LPCSTR windowName, DWORD style, INT x,
980 INT y, INT width, INT height,
981 HWND parent, HMENU menu,
982 HINSTANCE instance, LPVOID data )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000983{
984 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000985 CREATESTRUCTA cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +0000986 char buffer[256];
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000987
Rein Klazesd4a2cee1999-10-23 13:57:36 +0000988 if(!instance)
989 instance=GetModuleHandleA(NULL);
990
Rein Klazes5c6fc1b1998-11-01 14:50:06 +0000991 if(exStyle & WS_EX_MDICHILD)
Dmitry Timoshkov91adf0a2001-02-12 03:40:41 +0000992 return CreateMDIWindowA(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
Gerard Patel6fdb5dd2000-02-16 21:23:24 +0000993
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000994 /* Find the class atom */
995
Gerard Patel6fdb5dd2000-02-16 21:23:24 +0000996 if (HIWORD(className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000997 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +0000998 if (!(classAtom = GlobalFindAtomA( className )))
999 {
1000 ERR( "bad class name %s\n", debugres_a(className) );
1001 return 0;
1002 }
1003 }
1004 else
1005 {
1006 classAtom = LOWORD(className);
1007 if (!GlobalGetAtomNameA( classAtom, buffer, sizeof(buffer) ))
1008 {
1009 ERR( "bad atom %x\n", classAtom);
1010 return 0;
1011 }
1012 className = buffer;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001013 }
1014
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001015 /* Create the window */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001016
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001017 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001018 cs.hInstance = instance;
1019 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001020 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001021 cs.x = x;
1022 cs.y = y;
1023 cs.cx = width;
1024 cs.cy = height;
1025 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001026 cs.lpszName = windowName;
1027 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001028 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001029
Dmitry Timoshkov5956b982000-11-28 23:53:08 +00001030 return WIN_CreateWindowEx( &cs, classAtom, WIN_PROC_32A );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001031}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001032
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001033
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001034/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001035 * CreateWindowExW (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001036 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001037HWND WINAPI CreateWindowExW( DWORD exStyle, LPCWSTR className,
1038 LPCWSTR windowName, DWORD style, INT x,
1039 INT y, INT width, INT height,
1040 HWND parent, HMENU menu,
1041 HINSTANCE instance, LPVOID data )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001042{
1043 ATOM classAtom;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001044 CREATESTRUCTW cs;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001045 WCHAR buffer[256];
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001046
Rein Klazesd4a2cee1999-10-23 13:57:36 +00001047 if(!instance)
1048 instance=GetModuleHandleA(NULL);
1049
Rein Klazes5c6fc1b1998-11-01 14:50:06 +00001050 if(exStyle & WS_EX_MDICHILD)
Dmitry Timoshkov91adf0a2001-02-12 03:40:41 +00001051 return CreateMDIWindowW(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
Rein Klazes5c6fc1b1998-11-01 14:50:06 +00001052
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001053 /* Find the class atom */
1054
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001055 if (HIWORD(className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001056 {
Gerard Patel6fdb5dd2000-02-16 21:23:24 +00001057 if (!(classAtom = GlobalFindAtomW( className )))
1058 {
1059 ERR( "bad class name %s\n", debugres_w(className) );
1060 return 0;
1061 }
1062 }
1063 else
1064 {
1065 classAtom = LOWORD(className);
1066 if (!GlobalGetAtomNameW( classAtom, buffer, sizeof(buffer)/sizeof(WCHAR) ))
1067 {
1068 ERR( "bad atom %x\n", classAtom);
1069 return 0;
1070 }
1071 className = buffer;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001072 }
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001073
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001074 /* Create the window */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001075
1076 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001077 cs.hInstance = instance;
1078 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001079 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001080 cs.x = x;
1081 cs.y = y;
1082 cs.cx = width;
1083 cs.cy = height;
1084 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001085 cs.lpszName = windowName;
1086 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001087 cs.dwExStyle = exStyle;
Alexandre Julliardf1f68312000-01-01 22:22:21 +00001088
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001089 /* Note: we rely on the fact that CREATESTRUCTA and */
1090 /* CREATESTRUCTW have the same layout. */
Dmitry Timoshkov5956b982000-11-28 23:53:08 +00001091 return WIN_CreateWindowEx( (CREATESTRUCTA *)&cs, classAtom, WIN_PROC_32W );
Alexandre Julliard401710d1993-09-04 10:09:32 +00001092}
1093
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001094/***********************************************************************
1095 * WIN_SendDestroyMsg
1096 */
1097static void WIN_SendDestroyMsg( WND* pWnd )
1098{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001099 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret();
Alexandre Julliard42d20f92000-08-10 01:16:19 +00001100 USER_Driver.pResetSelectionOwner( pWnd, TRUE );
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001101
1102 /*
1103 * Send the WM_DESTROY to the window.
1104 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001105 SendMessageA( pWnd->hwndSelf, WM_DESTROY, 0, 0);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001106
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001107 /*
1108 * This WM_DESTROY message can trigger re-entrant calls to DestroyWindow
1109 * make sure that the window still exists when we come back.
1110 */
1111 if (IsWindow(pWnd->hwndSelf))
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001112 {
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001113 HWND* pWndArray = NULL;
1114 WND* pChild = NULL;
1115 int nKidCount = 0;
1116
1117 /*
1118 * Now, if the window has kids, we have to send WM_DESTROY messages
1119 * recursively to it's kids. It seems that those calls can also
1120 * trigger re-entrant calls to DestroyWindow for the kids so we must
1121 * protect against corruption of the list of siblings. We first build
1122 * a list of HWNDs representing all the kids.
1123 */
1124 pChild = WIN_LockWndPtr(pWnd->child);
1125 while( pChild )
1126 {
1127 nKidCount++;
1128 WIN_UpdateWndPtr(&pChild,pChild->next);
1129 }
1130
1131 /*
1132 * If there are no kids, we're done.
1133 */
1134 if (nKidCount==0)
1135 return;
1136
1137 pWndArray = HeapAlloc(GetProcessHeap(), 0, nKidCount*sizeof(HWND));
1138
1139 /*
1140 * Sanity check
1141 */
1142 if (pWndArray==NULL)
1143 return;
1144
1145 /*
1146 * Now, enumerate all the kids in a list, since we wait to make the SendMessage
1147 * call, our linked list of siblings should be safe.
1148 */
1149 nKidCount = 0;
1150 pChild = WIN_LockWndPtr(pWnd->child);
1151 while( pChild )
1152 {
1153 pWndArray[nKidCount] = pChild->hwndSelf;
1154 nKidCount++;
1155 WIN_UpdateWndPtr(&pChild,pChild->next);
1156 }
1157
1158 /*
1159 * Now that we have a list, go through that list again and send the destroy
1160 * message to those windows. We are using the HWND to retrieve the
1161 * WND pointer so we are effectively checking that all the kid windows are
1162 * still valid before sending the message.
1163 */
1164 while (nKidCount>0)
1165 {
Pavel Roskinc5012071999-03-19 16:59:18 +00001166 pChild = WIN_FindWndPtr(pWndArray[--nKidCount]);
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001167
1168 if (pChild!=NULL)
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001169 {
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001170 WIN_SendDestroyMsg( pChild );
1171 WIN_ReleaseWndPtr(pChild);
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001172 }
Francis Beaudeteb6a9f01999-03-17 15:17:48 +00001173 }
1174
1175 /*
1176 * Cleanup
1177 */
1178 HeapFree(GetProcessHeap(), 0, pWndArray);
Alexandre Julliarda0b2b1d1997-11-16 17:38:29 +00001179 }
1180 else
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001181 WARN("\tdestroyed itself while in WM_DESTROY!\n");
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001182}
1183
1184
1185/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001186 * DestroyWindow (USER.53)
Alexandre Julliard401710d1993-09-04 10:09:32 +00001187 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001188BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00001189{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001190 return DestroyWindow(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00001191}
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001192
1193
Alexandre Julliard01d63461997-01-20 19:43:45 +00001194/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001195 * DestroyWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001196 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001197BOOL WINAPI DestroyWindow( HWND hwnd )
Alexandre Julliard401710d1993-09-04 10:09:32 +00001198{
Alexandre Julliard0e607781993-11-03 19:23:37 +00001199 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001200 BOOL retvalue;
Alexandre Julliard1f029ea2000-11-02 20:08:59 +00001201 HWND h;
1202 BOOL bFocusSet = FALSE;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00001203
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001204 TRACE("(%04x)\n", hwnd);
Alexandre Julliard1f029ea2000-11-02 20:08:59 +00001205
1206 /* Initialization */
Alexandre Julliard401710d1993-09-04 10:09:32 +00001207
Alexandre Julliard0e607781993-11-03 19:23:37 +00001208 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001209 if (wndPtr == pWndDesktop)
1210 {
Andreas Mohr1c20b392000-02-20 19:17:35 +00001211 retvalue = FALSE; /* Can't destroy desktop */
1212 goto end;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001213 }
Alexandre Julliard58199531994-04-21 01:20:00 +00001214
Alexandre Julliard1f029ea2000-11-02 20:08:59 +00001215 /* Look whether the focus is within the tree of windows we will
1216 * be destroying.
1217 */
1218 h = GetFocus16();
1219 while (h && (GetWindowLongA(h,GWL_STYLE) & WS_CHILD))
1220 {
1221 if (h == hwnd)
1222 {
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00001223 SetFocus(GetParent(h));
Alexandre Julliard1f029ea2000-11-02 20:08:59 +00001224 bFocusSet = TRUE;
1225 break;
1226 }
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00001227 h = GetParent(h);
Alexandre Julliard1f029ea2000-11-02 20:08:59 +00001228 }
1229 /* If the focus is on the window we will destroy and it has no parent,
1230 * set the focus to 0.
1231 */
1232 if (! bFocusSet && (h == hwnd))
1233 {
1234 if (!(GetWindowLongA(h,GWL_STYLE) & WS_CHILD))
1235 SetFocus(0);
1236 }
1237
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001238 /* Call hooks */
1239
Alexandre Julliard32ee1682001-05-09 17:33:00 +00001240 if( HOOK_CallHooksA( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001241 {
1242 retvalue = FALSE;
1243 goto end;
1244 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001245
1246 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1247 {
Alexandre Julliard32ee1682001-05-09 17:33:00 +00001248 HOOK_CallHooksA( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001249 /* FIXME: clean up palette - see "Internals" p.352 */
1250 }
1251
Alexandre Julliard7ff1c411997-05-25 13:58:18 +00001252 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
Alexandre Julliard77b99181997-09-14 17:17:23 +00001253 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
1254 {
1255 /* Notify the parent window only */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001256 SendMessageA( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
Alexandre Julliard77b99181997-09-14 17:17:23 +00001257 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001258 if( !IsWindow(hwnd) )
1259 {
1260 retvalue = TRUE;
1261 goto end;
1262 }
Alexandre Julliard77b99181997-09-14 17:17:23 +00001263 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001264
Alexandre Julliard42d20f92000-08-10 01:16:19 +00001265 USER_Driver.pResetSelectionOwner( wndPtr, FALSE ); /* before the window is unmapped */
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001266
Alexandre Julliard58199531994-04-21 01:20:00 +00001267 /* Hide the window */
1268
1269 if (wndPtr->dwStyle & WS_VISIBLE)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001270 {
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001271 ShowWindow( hwnd, SW_HIDE );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001272 if (!IsWindow(hwnd))
1273 {
1274 retvalue = TRUE;
1275 goto end;
1276 }
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001277 }
Alexandre Julliard0e607781993-11-03 19:23:37 +00001278
Alexandre Julliard22945d51995-03-02 17:44:29 +00001279 /* Recursively destroy owned windows */
1280
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001281 if( !(wndPtr->dwStyle & WS_CHILD) )
Alexandre Julliard22945d51995-03-02 17:44:29 +00001282 {
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001283 for (;;)
1284 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001285 WND *siblingPtr = WIN_LockWndPtr(wndPtr->parent->child); /* First sibling */
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001286 while (siblingPtr)
Alexandre Julliard22945d51995-03-02 17:44:29 +00001287 {
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001288 if (siblingPtr->owner == wndPtr)
Patrik Stridvallea584721998-11-01 16:22:07 +00001289 {
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001290 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1291 break;
1292 else
1293 siblingPtr->owner = NULL;
Patrik Stridvallea584721998-11-01 16:22:07 +00001294 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001295 WIN_UpdateWndPtr(&siblingPtr,siblingPtr->next);
Alexandre Julliard22945d51995-03-02 17:44:29 +00001296 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001297 if (siblingPtr)
1298 {
1299 DestroyWindow( siblingPtr->hwndSelf );
1300 WIN_ReleaseWndPtr(siblingPtr);
1301 }
Alexandre Julliard22945d51995-03-02 17:44:29 +00001302 else break;
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001303 }
1304
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001305 WINPOS_ActivateOtherWindow(wndPtr);
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001306
1307 if( wndPtr->owner &&
1308 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1309 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
Alexandre Julliard22945d51995-03-02 17:44:29 +00001310 }
1311
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001312 /* Send destroy messages */
Alexandre Julliard0e607781993-11-03 19:23:37 +00001313
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001314 WIN_SendDestroyMsg( wndPtr );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001315 if (!IsWindow(hwnd))
1316 {
1317 retvalue = TRUE;
1318 goto end;
1319 }
Alexandre Julliard401710d1993-09-04 10:09:32 +00001320
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001321 /* Unlink now so we won't bother with the children later on */
Alexandre Julliard401710d1993-09-04 10:09:32 +00001322
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001323 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1324
1325 /* Destroy the window storage */
1326
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00001327 WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001328 retvalue = TRUE;
1329end:
1330 WIN_ReleaseWndPtr(wndPtr);
1331 return retvalue;
Alexandre Julliard401710d1993-09-04 10:09:32 +00001332}
1333
1334
1335/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001336 * CloseWindow (USER.43)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001337 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001338BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001339{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001340 return CloseWindow( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001341}
1342
1343
1344/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001345 * CloseWindow (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001346 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001347BOOL WINAPI CloseWindow( HWND hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001348{
1349 WND * wndPtr = WIN_FindWndPtr( hwnd );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001350 BOOL retvalue;
1351
1352 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD))
1353 {
1354 retvalue = FALSE;
1355 goto end;
1356 }
Alexandre Julliarda3960291999-02-26 11:11:13 +00001357 ShowWindow( hwnd, SW_MINIMIZE );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001358 retvalue = TRUE;
1359end:
1360 WIN_ReleaseWndPtr(wndPtr);
1361 return retvalue;
1362
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001363}
1364
1365
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001366/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001367 * OpenIcon (USER.44)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001368 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001369BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001370{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001371 return OpenIcon( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001372}
1373
1374
1375/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001376 * OpenIcon (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001377 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001378BOOL WINAPI OpenIcon( HWND hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001379{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001380 if (!IsIconic( hwnd )) return FALSE;
1381 ShowWindow( hwnd, SW_SHOWNORMAL );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00001382 return TRUE;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001383}
1384
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001385
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001386/***********************************************************************
1387 * WIN_FindWindow
1388 *
1389 * Implementation of FindWindow() and FindWindowEx().
1390 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001391static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className,
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001392 LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001393{
1394 WND *pWnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001395 HWND retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001396
1397 if (child)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001398 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001399 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1400 if (parent)
1401 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001402 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent))
1403 {
1404 retvalue = 0;
1405 goto end;
1406 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001407 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001408 else if (pWnd->parent != pWndDesktop)
1409 {
1410 retvalue = 0;
1411 goto end;
1412 }
1413 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001414 }
1415 else
1416 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001417 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : WIN_LockWndPtr(pWndDesktop)))
1418 {
1419 retvalue = 0;
1420 goto end;
1421 }
1422 WIN_UpdateWndPtr(&pWnd,pWnd->child);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001423 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001424 if (!pWnd)
1425 {
1426 retvalue = 0;
1427 goto end;
1428 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001429
Pavel Roskin598993f1999-03-16 09:53:10 +00001430 for ( ; pWnd ; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001431 {
Alexandre Julliard98779062000-12-07 23:39:16 +00001432 if (className && (GetClassWord(pWnd->hwndSelf, GCW_ATOM) != className))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001433 continue; /* Not the right class */
1434
1435 /* Now check the title */
1436
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001437 if (!title)
1438 {
1439 retvalue = pWnd->hwndSelf;
1440 goto end;
Pavel Roskin598993f1999-03-16 09:53:10 +00001441 }
Alexandre Julliardcb10fda2000-08-06 02:41:16 +00001442 if (pWnd->text && !strcmpW( pWnd->text, title ))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001443 {
1444 retvalue = pWnd->hwndSelf;
1445 goto end;
Pavel Roskin598993f1999-03-16 09:53:10 +00001446 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001447 }
1448 retvalue = 0;
Joerg Mayer2563b1b2000-12-22 20:29:41 +00001449 /* In this case we need to check whether other processes
1450 own a window with the given paramters on the Desktop,
1451 but we don't, so let's at least warn about it */
1452 FIXME("Returning 0 without checking other processes\n");
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001453end:
1454 WIN_ReleaseWndPtr(pWnd);
1455 return retvalue;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001456}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001457
1458
1459
1460/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001461 * FindWindow (USER.50)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001462 */
Alexandre Julliardb849d792000-02-13 13:56:13 +00001463HWND16 WINAPI FindWindow16( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001464{
Alexandre Julliardb849d792000-02-13 13:56:13 +00001465 return FindWindowA( className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001466}
1467
1468
1469/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001470 * FindWindowEx (USER.427)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001471 */
Alexandre Julliardb849d792000-02-13 13:56:13 +00001472HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child, LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001473{
Alexandre Julliardb849d792000-02-13 13:56:13 +00001474 return FindWindowExA( parent, child, className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001475}
1476
1477
1478/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001479 * FindWindowA (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001480 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001481HWND WINAPI FindWindowA( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001482{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001483 HWND ret = FindWindowExA( 0, 0, className, title );
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001484 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1485 return ret;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001486}
1487
1488
1489/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001490 * FindWindowExA (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001491 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001492HWND WINAPI FindWindowExA( HWND parent, HWND child,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001493 LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001494{
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001495 ATOM atom = 0;
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001496 LPWSTR buffer;
1497 HWND hwnd;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001498
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001499 if (className)
1500 {
1501 /* If the atom doesn't exist, then no class */
1502 /* with this name exists either. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001503 if (!(atom = GlobalFindAtomA( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001504 {
1505 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1506 return 0;
1507 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001508 }
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001509
1510 buffer = HEAP_strdupAtoW( GetProcessHeap(), 0, title );
1511 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1512 HeapFree( GetProcessHeap(), 0, buffer );
1513 return hwnd;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001514}
1515
1516
1517/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001518 * FindWindowExW (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001519 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001520HWND WINAPI FindWindowExW( HWND parent, HWND child,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001521 LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001522{
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001523 ATOM atom = 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001524
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001525 if (className)
1526 {
1527 /* If the atom doesn't exist, then no class */
1528 /* with this name exists either. */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001529 if (!(atom = GlobalFindAtomW( className )))
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001530 {
1531 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1532 return 0;
1533 }
Alexandre Julliard0e270f41996-08-24 18:26:35 +00001534 }
Dmitry Timoshkov04da8b82000-07-10 12:09:31 +00001535 return WIN_FindWindow( parent, child, atom, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001536}
1537
1538
1539/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001540 * FindWindowW (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001541 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001542HWND WINAPI FindWindowW( LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001543{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001544 return FindWindowExW( 0, 0, className, title );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001545}
1546
1547
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001548/**********************************************************************
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001549 * WIN_GetDesktop
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001550 * returns a locked pointer
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001551 */
1552WND *WIN_GetDesktop(void)
1553{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001554 return WIN_LockWndPtr(pWndDesktop);
1555}
1556/**********************************************************************
1557 * WIN_ReleaseDesktop
1558 * unlock the desktop pointer
1559 */
1560void WIN_ReleaseDesktop(void)
1561{
1562 WIN_ReleaseWndPtr(pWndDesktop);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001563}
1564
1565
1566/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001567 * GetDesktopWindow (USER.286)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001568 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001569HWND16 WINAPI GetDesktopWindow16(void)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001570{
1571 return (HWND16)pWndDesktop->hwndSelf;
1572}
1573
1574
1575/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001576 * GetDesktopWindow (USER32.@)
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001577 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001578HWND WINAPI GetDesktopWindow(void)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001579{
Uwe Bonnes73619161999-10-24 20:42:39 +00001580 if (pWndDesktop) return pWndDesktop->hwndSelf;
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001581 ERR( "You need the -desktop option when running with native USER\n" );
Uwe Bonnes73619161999-10-24 20:42:39 +00001582 ExitProcess(1);
Huw D M Davies238b6d71999-10-31 01:56:51 +00001583 return 0;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001584}
1585
1586
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001587/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001588 * GetDesktopHwnd (USER.278)
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001589 *
1590 * Exactly the same thing as GetDesktopWindow(), but not documented.
1591 * Don't ask me why...
1592 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001593HWND16 WINAPI GetDesktopHwnd16(void)
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001594{
Alexandre Julliard2c69f6d1996-09-28 18:11:01 +00001595 return (HWND16)pWndDesktop->hwndSelf;
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001596}
1597
1598
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001599/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001600 * EnableWindow (USER.34)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001601 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001602BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
Alexandre Julliard01d63461997-01-20 19:43:45 +00001603{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001604 return EnableWindow( hwnd, enable );
Alexandre Julliard01d63461997-01-20 19:43:45 +00001605}
1606
1607
1608/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001609 * EnableWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001610 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001611BOOL WINAPI EnableWindow( HWND hwnd, BOOL enable )
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001612{
1613 WND *wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001614 BOOL retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001615
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001616 TRACE("( %x, %d )\n", hwnd, enable);
1617
1618 if (USER_Driver.pEnableWindow)
1619 return USER_Driver.pEnableWindow( hwnd, enable );
1620
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001621 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001622
1623 retvalue = ((wndPtr->dwStyle & WS_DISABLED) != 0);
1624
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001625 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1626 {
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001627 wndPtr->dwStyle &= ~WS_DISABLED; /* Enable window */
1628 SendMessageA( hwnd, WM_ENABLE, TRUE, 0 );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001629 }
1630 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1631 {
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001632 SendMessageA( wndPtr->hwndSelf, WM_CANCELMODE, 0, 0);
Alex Korobka4f1ac051999-03-28 09:37:57 +00001633
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001634 wndPtr->dwStyle |= WS_DISABLED; /* Disable window */
Alex Korobka4f1ac051999-03-28 09:37:57 +00001635
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001636 if (hwnd == GetFocus())
1637 SetFocus( 0 ); /* A disabled window can't have the focus */
Alex Korobka4f1ac051999-03-28 09:37:57 +00001638
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00001639 if (hwnd == GetCapture())
1640 ReleaseCapture(); /* A disabled window can't capture the mouse */
1641
1642 SendMessageA( hwnd, WM_ENABLE, FALSE, 0 );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001643 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001644 WIN_ReleaseWndPtr(wndPtr);
1645 return retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001646}
1647
1648
1649/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001650 * IsWindowEnabled (USER.35)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001651 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001652BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001653{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001654 return IsWindowEnabled(hWnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00001655}
1656
1657
1658/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001659 * IsWindowEnabled (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00001660 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001661BOOL WINAPI IsWindowEnabled(HWND hWnd)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001662{
1663 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001664 BOOL retvalue;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001665
1666 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001667 retvalue = !(wndPtr->dwStyle & WS_DISABLED);
1668 WIN_ReleaseWndPtr(wndPtr);
1669 return retvalue;
1670
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001671}
1672
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001673
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001674/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001675 * IsWindowUnicode (USER32.@)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001676 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001677BOOL WINAPI IsWindowUnicode( HWND hwnd )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001678{
1679 WND * wndPtr;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001680 BOOL retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001681
1682 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001683 retvalue = (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1684 WIN_ReleaseWndPtr(wndPtr);
1685 return retvalue;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001686}
1687
1688
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001689/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001690 * GetWindowWord (USER.133)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001691 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001692WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
Alexandre Julliard21979011997-03-05 08:22:35 +00001693{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001694 return GetWindowWord( hwnd, offset );
Alexandre Julliard21979011997-03-05 08:22:35 +00001695}
1696
1697
1698/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001699 * GetWindowWord (USER32.@)
Alexandre Julliard21979011997-03-05 08:22:35 +00001700 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001701WORD WINAPI GetWindowWord( HWND hwnd, INT offset )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001702{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001703 WORD retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001704 WND * wndPtr = WIN_FindWndPtr( hwnd );
1705 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001706 if (offset >= 0)
1707 {
Alexandre Julliard98779062000-12-07 23:39:16 +00001708 if (offset + sizeof(WORD) > wndPtr->cbWndExtra)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001709 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001710 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001711 retvalue = 0;
1712 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001713 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001714 retvalue = *(WORD *)(((char *)wndPtr->wExtra) + offset);
1715 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001716 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001717 switch(offset)
1718 {
Alexandre Julliard77b99181997-09-14 17:17:23 +00001719 case GWW_ID:
1720 if (HIWORD(wndPtr->wIDmenu))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001721 WARN("GWW_ID: discards high bits of 0x%08x!\n",
Alexandre Julliarda845b881998-06-01 10:44:35 +00001722 wndPtr->wIDmenu);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001723 retvalue = (WORD)wndPtr->wIDmenu;
1724 goto end;
Alexandre Julliardebfc0fe1998-06-28 18:40:26 +00001725 case GWW_HWNDPARENT:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001726 retvalue = GetParent(hwnd);
1727 goto end;
Alexandre Julliard77b99181997-09-14 17:17:23 +00001728 case GWW_HINSTANCE:
1729 if (HIWORD(wndPtr->hInstance))
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001730 WARN("GWW_HINSTANCE: discards high bits of 0x%08x!\n",
Alexandre Julliarda845b881998-06-01 10:44:35 +00001731 wndPtr->hInstance);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001732 retvalue = (WORD)wndPtr->hInstance;
1733 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001734 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001735 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001736 retvalue = 0;
1737 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001738 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001739end:
1740 WIN_ReleaseWndPtr(wndPtr);
1741 return retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001742}
1743
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00001744/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001745 * SetWindowWord (USER.134)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001746 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001747WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
Alexandre Julliard21979011997-03-05 08:22:35 +00001748{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001749 return SetWindowWord( hwnd, offset, newval );
Alexandre Julliard21979011997-03-05 08:22:35 +00001750}
1751
1752
1753/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001754 * SetWindowWord (USER32.@)
Alexandre Julliard21979011997-03-05 08:22:35 +00001755 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001756WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001757{
1758 WORD *ptr, retval;
1759 WND * wndPtr = WIN_FindWndPtr( hwnd );
1760 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001761 if (offset >= 0)
1762 {
Alexandre Julliard98779062000-12-07 23:39:16 +00001763 if (offset + sizeof(WORD) > wndPtr->cbWndExtra)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001764 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001765 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001766 retval = 0;
1767 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001768 }
1769 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1770 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001771 else switch(offset)
1772 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001773 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1774 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001775 case GWW_HWNDPARENT: retval = SetParent( hwnd, newval );
1776 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001777 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001778 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001779 retval = 0;
1780 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001781 }
1782 retval = *ptr;
1783 *ptr = newval;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001784end:
1785 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001786 return retval;
1787}
1788
1789
1790/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001791 * WIN_GetWindowLong
1792 *
1793 * Helper function for GetWindowLong().
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001794 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001795static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001796{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001797 LONG retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001798 WND * wndPtr = WIN_FindWndPtr( hwnd );
1799 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001800 if (offset >= 0)
1801 {
Alexandre Julliard98779062000-12-07 23:39:16 +00001802 if (offset + sizeof(LONG) > wndPtr->cbWndExtra)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001803 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001804 WARN("Invalid offset %d\n", offset );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001805 retvalue = 0;
1806 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001807 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001808 retvalue = *(LONG *)(((char *)wndPtr->wExtra) + offset);
Alexandre Julliard3051b641996-07-05 17:14:13 +00001809 /* Special case for dialog window procedure */
1810 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001811 {
1812 retvalue = (LONG)WINPROC_GetProc( (HWINDOWPROC)retvalue, type );
1813 goto end;
1814 }
1815 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001816 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001817 switch(offset)
1818 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001819 case GWL_USERDATA: retvalue = wndPtr->userdata;
1820 goto end;
1821 case GWL_STYLE: retvalue = wndPtr->dwStyle;
1822 goto end;
1823 case GWL_EXSTYLE: retvalue = wndPtr->dwExStyle;
1824 goto end;
1825 case GWL_ID: retvalue = (LONG)wndPtr->wIDmenu;
1826 goto end;
1827 case GWL_WNDPROC: retvalue = (LONG)WINPROC_GetProc( wndPtr->winproc,
Alexandre Julliard3051b641996-07-05 17:14:13 +00001828 type );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001829 goto end;
1830 case GWL_HWNDPARENT: retvalue = GetParent(hwnd);
1831 goto end;
1832 case GWL_HINSTANCE: retvalue = wndPtr->hInstance;
1833 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001834 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001835 WARN("Unknown offset %d\n", offset );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001836 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001837 retvalue = 0;
1838end:
1839 WIN_ReleaseWndPtr(wndPtr);
1840 return retvalue;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001841}
1842
1843
1844/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001845 * WIN_SetWindowLong
1846 *
1847 * Helper function for SetWindowLong().
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001848 *
1849 * 0 is the failure code. However, in the case of failure SetLastError
1850 * must be set to distinguish between a 0 return value and a failure.
1851 *
1852 * FIXME: The error values for SetLastError may not be right. Can
1853 * someone check with the real thing?
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001854 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001855static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval,
Alexandre Julliard3051b641996-07-05 17:14:13 +00001856 WINDOWPROCTYPE type )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001857{
1858 LONG *ptr, retval;
1859 WND * wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001860 STYLESTRUCT style;
1861
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001862 TRACE("%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001863
1864 if (!wndPtr)
1865 {
1866 /* Is this the right error? */
1867 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1868 return 0;
1869 }
1870
Alexandre Julliard3051b641996-07-05 17:14:13 +00001871 if (offset >= 0)
1872 {
Alexandre Julliard98779062000-12-07 23:39:16 +00001873 if (offset + sizeof(LONG) > wndPtr->cbWndExtra)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001874 {
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001875 WARN("Invalid offset %d\n", offset );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001876
1877 /* Is this the right error? */
1878 SetLastError( ERROR_OUTOFMEMORY );
1879
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001880 retval = 0;
1881 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001882 }
1883 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1884 /* Special case for dialog window procedure */
1885 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1886 {
1887 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00001888 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1889 type, WIN_PROC_WINDOW );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001890 goto end;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001891 }
1892 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001893 else switch(offset)
1894 {
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001895 case GWL_ID:
1896 ptr = (DWORD*)&wndPtr->wIDmenu;
1897 break;
1898 case GWL_HINSTANCE:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001899 retval = SetWindowWord( hwnd, offset, newval );
1900 goto end;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001901 case GWL_WNDPROC:
Dmitry Timoshkov5956b982000-11-28 23:53:08 +00001902 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001903 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00001904 type, WIN_PROC_WINDOW );
Andreas Mohr1c20b392000-02-20 19:17:35 +00001905 goto end;
Alexandre Julliardca22b331996-07-12 19:02:39 +00001906 case GWL_STYLE:
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001907 style.styleOld = wndPtr->dwStyle;
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00001908 style.styleNew = newval;
Alexandre Julliard4b0343d2001-06-20 22:55:31 +00001909 SendMessageA(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001910 wndPtr->dwStyle = style.styleNew;
Alexandre Julliard4b0343d2001-06-20 22:55:31 +00001911 SendMessageA(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001912 retval = style.styleOld;
1913 goto end;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001914
Alexandre Julliarda0d77311998-09-13 16:32:00 +00001915 case GWL_USERDATA:
1916 ptr = &wndPtr->userdata;
1917 break;
1918 case GWL_EXSTYLE:
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001919 style.styleOld = wndPtr->dwExStyle;
1920 style.styleNew = newval;
Alexandre Julliard4b0343d2001-06-20 22:55:31 +00001921 SendMessageA(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001922 wndPtr->dwExStyle = newval;
Alexandre Julliard4b0343d2001-06-20 22:55:31 +00001923 SendMessageA(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001924 retval = style.styleOld;
1925 goto end;
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001926
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001927 default:
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00001928 WARN("Invalid offset %d\n", offset );
Alexandre Julliardd30dfd21998-09-27 18:28:36 +00001929
1930 /* Don't think this is right error but it should do */
1931 SetLastError( ERROR_OUTOFMEMORY );
1932
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001933 retval = 0;
1934 goto end;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001935 }
1936 retval = *ptr;
1937 *ptr = newval;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00001938end:
1939 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001940 return retval;
1941}
1942
1943
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001944/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001945 * GetWindowLong (USER.135)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001946 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001947LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00001948{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001949 return WIN_GetWindowLong( (HWND)hwnd, offset, WIN_PROC_16 );
Alexandre Julliard3051b641996-07-05 17:14:13 +00001950}
1951
1952
1953/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001954 * GetWindowLongA (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001955 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001956LONG WINAPI GetWindowLongA( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00001957{
1958 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1959}
1960
1961
1962/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001963 * GetWindowLongW (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001964 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001965LONG WINAPI GetWindowLongW( HWND hwnd, INT offset )
Alexandre Julliard3051b641996-07-05 17:14:13 +00001966{
1967 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1968}
1969
1970
1971/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001972 * SetWindowLong (USER.136)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001973 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00001974LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00001975{
1976 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1977}
1978
1979
1980/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001981 * SetWindowLongA (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00001982 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001983LONG WINAPI SetWindowLongA( HWND hwnd, INT offset, LONG newval )
Alexandre Julliard3051b641996-07-05 17:14:13 +00001984{
1985 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1986}
1987
1988
1989/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00001990 * SetWindowLongW (USER32.@) Set window attribute
Alexandre Julliard767e6f61998-08-09 12:47:43 +00001991 *
1992 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
1993 * value in a window's extra memory.
1994 *
1995 * The _hwnd_ parameter specifies the window. is the handle to a
1996 * window that has extra memory. The _newval_ parameter contains the
1997 * new attribute or extra memory value. If positive, the _offset_
1998 * parameter is the byte-addressed location in the window's extra
1999 * memory to set. If negative, _offset_ specifies the window
2000 * attribute to set, and should be one of the following values:
2001 *
2002 * GWL_EXSTYLE The window's extended window style
2003 *
2004 * GWL_STYLE The window's window style.
2005 *
2006 * GWL_WNDPROC Pointer to the window's window procedure.
2007 *
2008 * GWL_HINSTANCE The window's pplication instance handle.
2009 *
2010 * GWL_ID The window's identifier.
2011 *
2012 * GWL_USERDATA The window's user-specified data.
2013 *
2014 * If the window is a dialog box, the _offset_ parameter can be one of
2015 * the following values:
2016 *
2017 * DWL_DLGPROC The address of the window's dialog box procedure.
2018 *
2019 * DWL_MSGRESULT The return value of a message
2020 * that the dialog box procedure processed.
2021 *
2022 * DWL_USER Application specific information.
2023 *
2024 * RETURNS
2025 *
2026 * If successful, returns the previous value located at _offset_. Otherwise,
2027 * returns 0.
2028 *
2029 * NOTES
2030 *
2031 * Extra memory for a window class is specified by a nonzero cbWndExtra
2032 * parameter of the WNDCLASS structure passed to RegisterClass() at the
2033 * time of class creation.
2034 *
2035 * Using GWL_WNDPROC to set a new window procedure effectively creates
2036 * a window subclass. Use CallWindowProc() in the new windows procedure
2037 * to pass messages to the superclass's window procedure.
2038 *
2039 * The user data is reserved for use by the application which created
2040 * the window.
2041 *
2042 * Do not use GWL_STYLE to change the window's WS_DISABLE style;
2043 * instead, call the EnableWindow() function to change the window's
2044 * disabled state.
2045 *
2046 * Do not use GWL_HWNDPARENT to reset the window's parent, use
2047 * SetParent() instead.
2048 *
Alexandre Julliard638f1691999-01-17 16:32:32 +00002049 * Win95:
2050 * When offset is GWL_STYLE and the calling app's ver is 4.0,
2051 * it sends WM_STYLECHANGING before changing the settings
2052 * and WM_STYLECHANGED afterwards.
2053 * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
2054 *
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002055 * BUGS
2056 *
Alexandre Julliard638f1691999-01-17 16:32:32 +00002057 * GWL_STYLE does not dispatch WM_STYLE... messages.
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002058 *
2059 * CONFORMANCE
2060 *
2061 * ECMA-234, Win32
2062 *
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002063 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002064LONG WINAPI SetWindowLongW(
Patrik Stridvall2b3aa612000-12-01 23:58:28 +00002065 HWND hwnd, /* [in] window to alter */
2066 INT offset, /* [in] offset, in bytes, of location to alter */
2067 LONG newval /* [in] new value of location */
Alexandre Julliard767e6f61998-08-09 12:47:43 +00002068) {
Alexandre Julliard3051b641996-07-05 17:14:13 +00002069 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002070}
2071
2072
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002073/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002074 * GetWindowText (USER.36)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002075 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002076INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002077{
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002078 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
Alexandre Julliard0e607781993-11-03 19:23:37 +00002079}
2080
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002081
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002082/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002083 * GetWindowTextA (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002084 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002085INT WINAPI GetWindowTextA( HWND hwnd, LPSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002086{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002087 return (INT)SendMessageA( hwnd, WM_GETTEXT, nMaxCount,
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002088 (LPARAM)lpString );
2089}
2090
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002091/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002092 * InternalGetWindowText (USER32.@)
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002093 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002094INT WINAPI InternalGetWindowText(HWND hwnd,LPWSTR lpString,INT nMaxCount )
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002095{
Alexandre Julliarddc4fe772001-06-04 21:55:17 +00002096 WND *win = WIN_FindWndPtr( hwnd );
2097 if (!win) return 0;
2098 if (win->text) lstrcpynW( lpString, win->text, nMaxCount );
2099 else lpString[0] = 0;
2100 WIN_ReleaseWndPtr( win );
2101 return strlenW(lpString);
Alexandre Julliardf90efa91998-06-14 15:24:15 +00002102}
2103
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002104
2105/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002106 * GetWindowTextW (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002107 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002108INT WINAPI GetWindowTextW( HWND hwnd, LPWSTR lpString, INT nMaxCount )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002109{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002110 return (INT)SendMessageW( hwnd, WM_GETTEXT, nMaxCount,
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002111 (LPARAM)lpString );
2112}
2113
2114
2115/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002116 * SetWindowText (USER.37)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002117 */
Paul Quinn1beaae51998-12-15 15:38:36 +00002118BOOL16 WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002119{
Paul Quinn1beaae51998-12-15 15:38:36 +00002120 return (BOOL16)SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002121}
2122
2123
2124/*******************************************************************
Patrik Stridvall17fd4e32001-06-28 18:04:41 +00002125 * SetWindowText (USER32.@)
2126 * SetWindowTextA (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002127 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002128BOOL WINAPI SetWindowTextA( HWND hwnd, LPCSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002129{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002130 return (BOOL)SendMessageA( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002131}
2132
2133
2134/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002135 * SetWindowTextW (USER32.@)
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002136 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002137BOOL WINAPI SetWindowTextW( HWND hwnd, LPCWSTR lpString )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002138{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002139 return (BOOL)SendMessageW( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00002140}
2141
2142
Alexandre Julliard0e607781993-11-03 19:23:37 +00002143/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002144 * GetWindowTextLength (USER.38)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002145 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002146INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002147{
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002148 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00002149}
2150
2151
Alexandre Julliard0e607781993-11-03 19:23:37 +00002152/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002153 * GetWindowTextLengthA (USER32.@)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002154 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002155INT WINAPI GetWindowTextLengthA( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002156{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002157 return SendMessageA( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002158}
2159
2160/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002161 * GetWindowTextLengthW (USER32.@)
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002162 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002163INT WINAPI GetWindowTextLengthW( HWND hwnd )
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002164{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002165 return SendMessageW( hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002166}
2167
Alexandre Julliard21979011997-03-05 08:22:35 +00002168
Alexandre Julliardb1bac321996-12-15 19:45:59 +00002169/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002170 * IsWindow (USER.47)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002171 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002172BOOL16 WINAPI IsWindow16( HWND16 hwnd )
Alexandre Julliard21979011997-03-05 08:22:35 +00002173{
Alexandre Julliard4220b291999-07-11 17:20:01 +00002174 CURRENT_STACK16->es = USER_HeapSel;
Alexandre Julliarda3960291999-02-26 11:11:13 +00002175 return IsWindow( hwnd );
Alexandre Julliard21979011997-03-05 08:22:35 +00002176}
2177
2178
2179/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002180 * IsWindow (USER32.@)
Alexandre Julliard21979011997-03-05 08:22:35 +00002181 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002182BOOL WINAPI IsWindow( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002183{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002184 WND * wndPtr;
2185 BOOL retvalue;
2186
2187 if(!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
2188 retvalue = (wndPtr->dwMagic == WND_MAGIC);
2189 WIN_ReleaseWndPtr(wndPtr);
2190 return retvalue;
2191
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002192}
2193
2194
2195/*****************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002196 * GetParent (USER.46)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002197 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002198HWND16 WINAPI GetParent16( HWND16 hwnd )
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002199{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002200 return (HWND16)GetParent( hwnd );
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002201}
2202
2203
2204/*****************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002205 * GetParent (USER32.@)
Alexandre Julliardd1ce8b21996-09-02 16:46:30 +00002206 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002207HWND WINAPI GetParent( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002208{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002209 WND *wndPtr;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002210 HWND retvalue = 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002211
2212 if(!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
2213 if ((!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD))))
Andreas Mohr1c20b392000-02-20 19:17:35 +00002214 goto end;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002215
Andreas Mohr1c20b392000-02-20 19:17:35 +00002216 WIN_UpdateWndPtr(&wndPtr,((wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner));
2217 if (wndPtr)
2218 retvalue = wndPtr->hwndSelf;
2219
2220end:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002221 WIN_ReleaseWndPtr(wndPtr);
2222 return retvalue;
2223
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002224}
2225
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002226/*****************************************************************
2227 * WIN_GetTopParent
2228 *
2229 * Get the top-level parent for a child window.
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002230 * returns a locked pointer
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002231 */
2232WND* WIN_GetTopParentPtr( WND* pWnd )
2233{
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002234 WND *tmpWnd = WIN_LockWndPtr(pWnd);
2235
2236 while( tmpWnd && (tmpWnd->dwStyle & WS_CHILD))
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002237 {
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002238 WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002239 }
Francois Boisvert3a3cd9f1999-03-28 12:42:52 +00002240 return tmpWnd;
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002241}
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002242
2243/*****************************************************************
2244 * WIN_GetTopParent
2245 *
2246 * Get the top-level parent for a child window.
2247 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002248HWND WIN_GetTopParent( HWND hwnd )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002249{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002250 HWND retvalue;
2251 WND *tmpPtr = WIN_FindWndPtr(hwnd);
2252 WND *wndPtr = WIN_GetTopParentPtr (tmpPtr );
2253
2254 retvalue = wndPtr ? wndPtr->hwndSelf : 0;
2255 WIN_ReleaseWndPtr(tmpPtr);
2256 WIN_ReleaseWndPtr(wndPtr);
2257 return retvalue;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002258}
2259
2260
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002261/*****************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002262 * SetParent (USER.233)
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002263 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002264HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002265{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002266 return SetParent( hwndChild, hwndNewParent );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002267}
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002268
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002269
2270/*****************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002271 * SetParent (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002272 */
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002273HWND WINAPI SetParent( HWND hwnd, HWND parent )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002274{
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002275 WND *wndPtr;
2276 WND *pWndParent;
2277 DWORD dwStyle;
2278 HWND retvalue;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002279
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002280 if (hwnd == GetDesktopWindow()) /* sanity check */
2281 {
2282 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
2283 return 0;
2284 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002285
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002286 if (USER_Driver.pSetParent)
2287 return USER_Driver.pSetParent( hwnd, parent );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002288
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002289 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002290
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002291 dwStyle = wndPtr->dwStyle;
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002292
Alexandre Julliardb19c57c2001-05-10 21:06:56 +00002293 if (!parent) parent = GetDesktopWindow();
2294
2295 if (!(pWndParent = WIN_FindWndPtr(parent)))
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002296 {
2297 WIN_ReleaseWndPtr( wndPtr );
2298 return 0;
2299 }
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002300
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002301 /* Windows hides the window first, then shows it again
2302 * including the WM_SHOWWINDOW messages and all */
2303 if (dwStyle & WS_VISIBLE) ShowWindow( hwnd, SW_HIDE );
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002304
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002305 retvalue = wndPtr->parent->hwndSelf; /* old parent */
2306 if (pWndParent != wndPtr->parent)
2307 {
2308 WIN_UnlinkWindow(wndPtr->hwndSelf);
2309 wndPtr->parent = pWndParent;
Ove Kaaven72d8dbe1999-02-13 09:02:17 +00002310
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002311 if (parent != GetDesktopWindow()) /* a child window */
2312 {
2313 if( !( wndPtr->dwStyle & WS_CHILD ) )
2314 {
2315 if( wndPtr->wIDmenu != 0)
2316 {
2317 DestroyMenu( (HMENU) wndPtr->wIDmenu );
2318 wndPtr->wIDmenu = 0;
2319 }
2320 }
2321 }
2322 WIN_LinkWindow(wndPtr->hwndSelf, HWND_TOP);
2323 }
2324 WIN_ReleaseWndPtr( pWndParent );
2325 WIN_ReleaseWndPtr( wndPtr );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002326
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002327 /* SetParent additionally needs to make hwnd the topmost window
2328 in the x-order and send the expected WM_WINDOWPOSCHANGING and
2329 WM_WINDOWPOSCHANGED notification messages.
2330 */
2331 SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0,
2332 SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|
2333 ((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
2334 /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
2335 * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
2336 return retvalue;
Alexandre Julliard940d58c1994-09-16 09:24:37 +00002337}
2338
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002339
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002340/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002341 * IsChild (USER.48)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002342 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002343BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002344{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002345 return IsChild(parent,child);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002346}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002347
2348
Alexandre Julliard01d63461997-01-20 19:43:45 +00002349/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002350 * IsChild (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002351 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002352BOOL WINAPI IsChild( HWND parent, HWND child )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002353{
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002354 WND * wndPtr = WIN_FindWndPtr( child );
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00002355 while (wndPtr && wndPtr->parent)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002356 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002357 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00002358 if (wndPtr->hwndSelf == GetDesktopWindow()) break;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002359 if (wndPtr->hwndSelf == parent)
Andreas Mohr1c20b392000-02-20 19:17:35 +00002360 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002361 WIN_ReleaseWndPtr(wndPtr);
2362 return TRUE;
2363 }
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00002364 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002365 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard0e607781993-11-03 19:23:37 +00002366 return FALSE;
2367}
2368
2369
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002370/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002371 * IsWindowVisible (USER.49)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002372 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002373BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002374{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002375 return IsWindowVisible(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002376}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002377
2378
Alexandre Julliard01d63461997-01-20 19:43:45 +00002379/***********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002380 * IsWindowVisible (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002381 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002382BOOL WINAPI IsWindowVisible( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002383{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002384 BOOL retval;
Alexandre Julliardded30381995-07-06 17:18:27 +00002385 WND *wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00002386 while (wndPtr && wndPtr->parent)
Alexandre Julliardded30381995-07-06 17:18:27 +00002387 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002388 if (!(wndPtr->dwStyle & WS_VISIBLE))
2389 {
2390 WIN_ReleaseWndPtr(wndPtr);
2391 return FALSE;
2392 }
2393 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent);
Alexandre Julliardded30381995-07-06 17:18:27 +00002394 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002395 retval = (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
2396 WIN_ReleaseWndPtr(wndPtr);
2397 return retval;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00002398}
2399
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002400
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002401/***********************************************************************
2402 * WIN_IsWindowDrawable
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002403 *
2404 * hwnd is drawable when it is visible, all parents are not
2405 * minimized, and it is itself not minimized unless we are
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002406 * trying to draw its default class icon.
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002407 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002408BOOL WIN_IsWindowDrawable( WND* wnd, BOOL icon )
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002409{
Alexandre Julliard98779062000-12-07 23:39:16 +00002410 if (!(wnd->dwStyle & WS_VISIBLE)) return FALSE;
2411 if ((wnd->dwStyle & WS_MINIMIZE) &&
2412 icon && GetClassLongA( wnd->hwndSelf, GCL_HICON )) return FALSE;
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002413 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
2414 if( wnd->dwStyle & WS_MINIMIZE ||
2415 !(wnd->dwStyle & WS_VISIBLE) ) break;
2416 return (wnd == NULL);
Alexandre Julliard1e37a181996-08-18 16:21:52 +00002417}
2418
Alexandre Julliarddf2673b1997-03-29 17:20:20 +00002419
Alexandre Julliard0e607781993-11-03 19:23:37 +00002420/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002421 * GetTopWindow (USER.229)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002422 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002423HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002424{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002425 return GetTopWindow(hwnd);
Alexandre Julliard01d63461997-01-20 19:43:45 +00002426}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002427
2428
Alexandre Julliard01d63461997-01-20 19:43:45 +00002429/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002430 * GetTopWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002431 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002432HWND WINAPI GetTopWindow( HWND hwnd )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002433{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002434 HWND retval = 0;
2435 WND * wndPtr = (hwnd) ?
2436 WIN_FindWndPtr( hwnd ) : WIN_GetDesktop();
Francis Beaudetb7e8e801999-05-22 10:46:30 +00002437
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002438 if (wndPtr && wndPtr->child)
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002439 retval = wndPtr->child->hwndSelf;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002440
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002441 WIN_ReleaseWndPtr(wndPtr);
2442 return retval;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002443}
2444
2445
2446/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002447 * GetWindow (USER.262)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002448 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002449HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
Alexandre Julliard01d63461997-01-20 19:43:45 +00002450{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002451 return GetWindow( hwnd,rel );
Alexandre Julliard01d63461997-01-20 19:43:45 +00002452}
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002453
2454
Alexandre Julliard01d63461997-01-20 19:43:45 +00002455/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002456 * GetWindow (USER32.@)
Alexandre Julliard01d63461997-01-20 19:43:45 +00002457 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002458HWND WINAPI GetWindow( HWND hwnd, WORD rel )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002459{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002460 HWND retval;
2461
Alexandre Julliard0e607781993-11-03 19:23:37 +00002462 WND * wndPtr = WIN_FindWndPtr( hwnd );
2463 if (!wndPtr) return 0;
2464 switch(rel)
2465 {
2466 case GW_HWNDFIRST:
Andreas Mohr1c20b392000-02-20 19:17:35 +00002467 retval = wndPtr->parent ? wndPtr->parent->child->hwndSelf : 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002468 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002469
2470 case GW_HWNDLAST:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002471 if (!wndPtr->parent)
2472 {
2473 retval = 0; /* Desktop window */
2474 goto end;
2475 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002476 while (wndPtr->next)
2477 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002478 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002479 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002480 retval = wndPtr->hwndSelf;
2481 goto end;
2482
2483 case GW_HWNDNEXT:
Andreas Mohr1c20b392000-02-20 19:17:35 +00002484 retval = wndPtr->next ? wndPtr->next->hwndSelf : 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002485 goto end;
2486
2487 case GW_HWNDPREV:
2488 if (!wndPtr->parent)
2489 {
2490 retval = 0; /* Desktop window */
2491 goto end;
2492 }
2493 WIN_UpdateWndPtr(&wndPtr,wndPtr->parent->child); /* First sibling */
2494 if (wndPtr->hwndSelf == hwnd)
2495 {
2496 retval = 0; /* First in list */
2497 goto end;
2498 }
2499 while (wndPtr->next)
2500 {
2501 if (wndPtr->next->hwndSelf == hwnd)
Andreas Mohr1c20b392000-02-20 19:17:35 +00002502 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002503 retval = wndPtr->hwndSelf;
2504 goto end;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002505 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002506 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
2507 }
2508 retval = 0;
2509 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002510
2511 case GW_OWNER:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002512 retval = wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
2513 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002514
2515 case GW_CHILD:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002516 retval = wndPtr->child ? wndPtr->child->hwndSelf : 0;
2517 goto end;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002518 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002519 retval = 0;
2520end:
2521 WIN_ReleaseWndPtr(wndPtr);
2522 return retval;
Alexandre Julliard0e607781993-11-03 19:23:37 +00002523}
2524
2525
2526/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002527 * GetNextWindow (USER.230)
Alexandre Julliard0e607781993-11-03 19:23:37 +00002528 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002529HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
Alexandre Julliard0e607781993-11-03 19:23:37 +00002530{
2531 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
Alexandre Julliard01d63461997-01-20 19:43:45 +00002532 return GetWindow16( hwnd, flag );
Alexandre Julliard0e607781993-11-03 19:23:37 +00002533}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002534
Louis Philippe Gagnon06057e72000-08-20 03:40:59 +00002535/***********************************************************************
2536 * WIN_InternalShowOwnedPopups
2537 *
2538 * Internal version of ShowOwnedPopups; Wine functions should use this
2539 * to avoid interfering with application calls to ShowOwnedPopups
2540 * and to make sure the application can't prevent showing/hiding.
2541 *
2542 * Set unmanagedOnly to TRUE to show/hide unmanaged windows only.
2543 *
2544 */
2545
2546BOOL WIN_InternalShowOwnedPopups( HWND owner, BOOL fShow, BOOL unmanagedOnly )
2547{
2548 INT totalChild=0, count=0;
2549
2550 WND **pWnd = WIN_BuildWinArray(WIN_GetDesktop(), 0, &totalChild);
2551
2552 if (!pWnd) return TRUE;
2553
2554 /*
2555 * Show windows Lowest first, Highest last to preserve Z-Order
2556 */
2557 for (count = totalChild-1 ; count >=0; count--)
2558 {
2559 if (pWnd[count]->owner && (pWnd[count]->owner->hwndSelf == owner) && (pWnd[count]->dwStyle & WS_POPUP))
2560 {
2561 if (fShow)
2562 {
2563 /* check in window was flagged for showing in previous WIN_InternalShowOwnedPopups call */
2564 if (pWnd[count]->flags & WIN_NEEDS_INTERNALSOP)
2565 {
2566 /*
2567 * Call ShowWindow directly because an application can intercept WM_SHOWWINDOW messages
2568 */
2569 ShowWindow(pWnd[count]->hwndSelf,SW_SHOW);
2570 pWnd[count]->flags &= ~WIN_NEEDS_INTERNALSOP; /* remove the flag */
2571 }
2572 }
2573 else
2574 {
2575 if ( IsWindowVisible(pWnd[count]->hwndSelf) && /* hide only if window is visible */
2576 !( pWnd[count]->flags & WIN_NEEDS_INTERNALSOP ) && /* don't hide if previous call already did it */
Susan Farley557066d2000-10-13 17:07:08 +00002577 !( unmanagedOnly && (pWnd[count]->dwExStyle & WS_EX_MANAGED) ) ) /* don't hide managed windows if unmanagedOnly is TRUE */
Louis Philippe Gagnon06057e72000-08-20 03:40:59 +00002578 {
2579 /*
2580 * Call ShowWindow directly because an application can intercept WM_SHOWWINDOW messages
2581 */
2582 ShowWindow(pWnd[count]->hwndSelf,SW_HIDE);
2583 /* flag the window for showing on next WIN_InternalShowOwnedPopups call */
2584 pWnd[count]->flags |= WIN_NEEDS_INTERNALSOP;
2585 }
2586 }
2587 }
2588 }
2589 WIN_ReleaseDesktop();
2590 WIN_ReleaseWinArray(pWnd);
2591
2592 return TRUE;
2593}
2594
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002595/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002596 * ShowOwnedPopups (USER.265)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002597 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002598void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002599{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002600 ShowOwnedPopups( owner, fShow );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002601}
2602
2603
2604/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002605 * ShowOwnedPopups (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002606 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002607BOOL WINAPI ShowOwnedPopups( HWND owner, BOOL fShow )
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002608{
Noomen Hamzaa018d851999-09-28 16:26:09 +00002609 UINT totalChild=0, count=0;
2610
2611 WND **pWnd = WIN_BuildWinArray(WIN_GetDesktop(), 0, &totalChild);
2612
2613 if (!pWnd) return TRUE;
2614
2615 for (; count < totalChild; count++)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002616 {
Noomen Hamzaa018d851999-09-28 16:26:09 +00002617 if (pWnd[count]->owner && (pWnd[count]->owner->hwndSelf == owner) && (pWnd[count]->dwStyle & WS_POPUP))
Noomen Hamzaff727762000-02-18 19:11:04 +00002618 {
2619 if (fShow)
2620 {
2621 if (pWnd[count]->flags & WIN_NEEDS_SHOW_OWNEDPOPUP)
2622 {
Louis Philippe Gagnon06057e72000-08-20 03:40:59 +00002623 /*
2624 * In Windows, ShowOwnedPopups(TRUE) generates WM_SHOWWINDOW messages with SW_PARENTOPENING,
2625 * regardless of the state of the owner
2626 */
2627 SendMessageA(pWnd[count]->hwndSelf, WM_SHOWWINDOW, SW_SHOW, SW_PARENTOPENING);
Noomen Hamzaff727762000-02-18 19:11:04 +00002628 pWnd[count]->flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
2629 }
2630 }
2631 else
2632 {
2633 if (IsWindowVisible(pWnd[count]->hwndSelf))
2634 {
Louis Philippe Gagnon06057e72000-08-20 03:40:59 +00002635 /*
2636 * In Windows, ShowOwnedPopups(FALSE) generates WM_SHOWWINDOW messages with SW_PARENTCLOSING,
2637 * regardless of the state of the owner
2638 */
2639 SendMessageA(pWnd[count]->hwndSelf, WM_SHOWWINDOW, SW_HIDE, SW_PARENTCLOSING);
Noomen Hamzaff727762000-02-18 19:11:04 +00002640 pWnd[count]->flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
2641 }
2642 }
2643 }
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002644 }
Noomen Hamzaa018d851999-09-28 16:26:09 +00002645
2646 WIN_ReleaseDesktop();
2647 WIN_ReleaseWinArray(pWnd);
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002648 return TRUE;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00002649}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002650
2651
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002652/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002653 * GetLastActivePopup (USER.287)
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002654 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002655HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002656{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002657 return GetLastActivePopup( hwnd );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002658}
2659
2660/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002661 * GetLastActivePopup (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002662 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002663HWND WINAPI GetLastActivePopup( HWND hwnd )
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002664{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002665 HWND retval;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002666 WND *wndPtr =WIN_FindWndPtr(hwnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002667 if (!wndPtr) return hwnd;
2668 retval = wndPtr->hwndLastActive;
2669 WIN_ReleaseWndPtr(wndPtr);
Gerard Patelef456af2000-12-15 21:29:13 +00002670 if ((retval != hwnd) && (!IsWindow(retval)))
2671 retval = hwnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002672 return retval;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00002673}
2674
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002675
2676/*******************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00002677 * WIN_BuildWinArray
2678 *
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002679 * Build an array of pointers to the children of a given window.
Alexandre Julliard90476d62000-02-16 22:47:24 +00002680 * The array must be freed with WIN_ReleaseWinArray. Return NULL
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002681 * when no windows are found.
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002682 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002683WND **WIN_BuildWinArray( WND *wndPtr, UINT bwaFlags, UINT* pTotal )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002684{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002685 /* Future: this function will lock all windows associated with this array */
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002686
Alexandre Julliard3051b641996-07-05 17:14:13 +00002687 WND **list, **ppWnd;
2688 WND *pWnd;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002689 UINT count = 0, skipOwned, skipHidden;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002690 DWORD skipFlags;
2691
2692 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2693 skipOwned = bwaFlags & BWA_SKIPOWNED;
2694 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2695 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002696
2697 /* First count the windows */
2698
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002699 if (!wndPtr)
2700 wndPtr = WIN_GetDesktop();
2701
2702 pWnd = WIN_LockWndPtr(wndPtr->child);
2703 while (pWnd)
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002704 {
Alex Korobka44a1b591999-04-01 12:03:52 +00002705 if( !(pWnd->dwStyle & skipFlags) && !(skipOwned && pWnd->owner) &&
2706 (!skipHidden || (pWnd->dwStyle & WS_VISIBLE)) )
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002707 count++;
Alex Korobka44a1b591999-04-01 12:03:52 +00002708 WIN_UpdateWndPtr(&pWnd,pWnd->next);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002709 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002710
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002711 if( count )
2712 {
2713 /* Now build the list of all windows */
Alexandre Julliard3051b641996-07-05 17:14:13 +00002714
Alexandre Julliard90476d62000-02-16 22:47:24 +00002715 if ((list = (WND **)HeapAlloc( GetProcessHeap(), 0, sizeof(WND *) * (count + 1))))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002716 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002717 for (pWnd = WIN_LockWndPtr(wndPtr->child), ppWnd = list, count = 0; pWnd; WIN_UpdateWndPtr(&pWnd,pWnd->next))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002718 {
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002719 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) );
2720 else if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002721 {
2722 *ppWnd++ = pWnd;
2723 count++;
2724 }
2725 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002726 WIN_ReleaseWndPtr(pWnd);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002727 *ppWnd = NULL;
2728 }
2729 else count = 0;
2730 } else list = NULL;
2731
2732 if( pTotal ) *pTotal = count;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002733 return list;
2734}
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002735/*******************************************************************
2736 * WIN_ReleaseWinArray
2737 */
2738void WIN_ReleaseWinArray(WND **wndArray)
2739{
Andreas Mohr1c20b392000-02-20 19:17:35 +00002740 /* Future: this function will also unlock all windows associated with wndArray */
Alexandre Julliard90476d62000-02-16 22:47:24 +00002741 HeapFree( GetProcessHeap(), 0, wndArray );
Alexandre Julliard3051b641996-07-05 17:14:13 +00002742
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002743}
Alexandre Julliard3051b641996-07-05 17:14:13 +00002744
2745/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002746 * EnumWindows (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002747 */
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002748BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002749{
2750 WND **list, **ppWnd;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002751
Alexandre Julliard594997c1995-04-30 10:05:20 +00002752 /* We have to build a list of all windows first, to avoid */
Andreas Mohr1c20b392000-02-20 19:17:35 +00002753 /* unpleasant side-effects, for instance if the callback */
2754 /* function changes the Z-order of the windows. */
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002755
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002756 if (!(list = WIN_BuildWinArray(WIN_GetDesktop(), 0, NULL )))
2757 {
2758 WIN_ReleaseDesktop();
2759 return FALSE;
2760 }
Alexandre Julliard594997c1995-04-30 10:05:20 +00002761
Alexandre Julliard3051b641996-07-05 17:14:13 +00002762 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002763
Alexandre Julliard3051b641996-07-05 17:14:13 +00002764 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002765 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002766 LRESULT lpEnumFuncRetval;
2767 int iWndsLocks = 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002768 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002769 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Francois Boisvertd96bc151999-04-02 10:34:43 +00002770
2771 /* To avoid any deadlocks, all the locks on the windows
2772 structures must be suspended before the control
2773 is passed to the application */
2774 iWndsLocks = WIN_SuspendWndsLock();
2775 lpEnumFuncRetval = lpEnumFunc( (*ppWnd)->hwndSelf, lParam);
2776 WIN_RestoreWndsLock(iWndsLocks);
2777
2778 if (!lpEnumFuncRetval) break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002779 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002780 WIN_ReleaseWinArray(list);
2781 WIN_ReleaseDesktop();
Alexandre Julliard3051b641996-07-05 17:14:13 +00002782 return TRUE;
2783}
2784
2785
Alexandre Julliard594997c1995-04-30 10:05:20 +00002786/**********************************************************************
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002787 * WIN_EnumQueueWindows
2788 *
2789 * Helper for EnumTaskWindows16 and EnumThreadWindows.
Alexandre Julliard594997c1995-04-30 10:05:20 +00002790 */
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002791static BOOL WIN_EnumQueueWindows( HQUEUE16 queue, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliard594997c1995-04-30 10:05:20 +00002792{
Alexandre Julliard3051b641996-07-05 17:14:13 +00002793 WND **list, **ppWnd;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002794
2795 /* This function is the same as EnumWindows(), */
Per Ångströma47bc3a1998-11-14 17:00:37 +00002796 /* except for an added check on the window's task. */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002797
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002798 if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
2799 {
2800 WIN_ReleaseDesktop();
2801 return FALSE;
2802 }
Alexandre Julliard594997c1995-04-30 10:05:20 +00002803
Alexandre Julliard3051b641996-07-05 17:14:13 +00002804 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00002805
Alexandre Julliard3051b641996-07-05 17:14:13 +00002806 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00002807 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002808 LRESULT funcRetval;
2809 int iWndsLocks = 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002810 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002811 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002812 if ((*ppWnd)->hmemTaskQ != queue) continue;
2813
Francois Boisvertd96bc151999-04-02 10:34:43 +00002814 /* To avoid any deadlocks, all the locks on the windows
2815 structures must be suspended before the control
2816 is passed to the application */
2817 iWndsLocks = WIN_SuspendWndsLock();
2818 funcRetval = func( (*ppWnd)->hwndSelf, lParam );
2819 WIN_RestoreWndsLock(iWndsLocks);
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002820
Francois Boisvertd96bc151999-04-02 10:34:43 +00002821 if (!funcRetval) break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00002822 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002823 WIN_ReleaseWinArray(list);
2824 WIN_ReleaseDesktop();
Alexandre Julliard594997c1995-04-30 10:05:20 +00002825 return TRUE;
2826}
2827
2828
Alexandre Julliard3051b641996-07-05 17:14:13 +00002829/**********************************************************************
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002830 * EnumTaskWindows16 (USER.225)
2831 */
2832BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2833 LPARAM lParam )
2834{
2835 HQUEUE16 queue = GetTaskQueue16( hTask );
2836 if (!queue) return FALSE;
2837 return WIN_EnumQueueWindows( queue, (WNDENUMPROC)func, lParam );
2838}
2839
2840
2841/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002842 * EnumThreadWindows (USER32.@)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002843 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002844BOOL WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002845{
Alexandre Julliard66ffa172001-04-04 18:32:14 +00002846 HQUEUE16 queue = GetThreadQueue16( id );
2847 if (!queue) return FALSE;
2848 return WIN_EnumQueueWindows( queue, func, lParam );
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002849}
2850
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002851
Alexandre Julliard3051b641996-07-05 17:14:13 +00002852/**********************************************************************
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002853 * WIN_EnumChildWindows
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002854 *
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002855 * Helper function for EnumChildWindows().
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002856 */
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002857static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC func, LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002858{
Alexandre Julliard3051b641996-07-05 17:14:13 +00002859 WND **childList;
2860 BOOL16 ret = FALSE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00002861
Alexandre Julliard23946ad1997-06-16 17:43:53 +00002862 for ( ; *ppWnd; ppWnd++)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002863 {
Francois Boisvertd96bc151999-04-02 10:34:43 +00002864 int iWndsLocks = 0;
2865
Alexandre Julliard3051b641996-07-05 17:14:13 +00002866 /* Make sure that the window still exists */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002867 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002868 /* Build children list first */
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002869 childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
Francois Boisvertd96bc151999-04-02 10:34:43 +00002870
2871 /* To avoid any deadlocks, all the locks on the windows
2872 structures must be suspended before the control
2873 is passed to the application */
2874 iWndsLocks = WIN_SuspendWndsLock();
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002875 ret = func( (*ppWnd)->hwndSelf, lParam );
Francois Boisvertd96bc151999-04-02 10:34:43 +00002876 WIN_RestoreWndsLock(iWndsLocks);
2877
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002878 if (childList)
2879 {
2880 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002881 WIN_ReleaseWinArray(childList);
Alexandre Julliard85ed45e1998-08-22 19:03:56 +00002882 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00002883 if (!ret) return FALSE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00002884 }
2885 return TRUE;
2886}
2887
2888
2889/**********************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002890 * EnumChildWindows (USER32.@)
Alexandre Julliard3051b641996-07-05 17:14:13 +00002891 */
Alexandre Julliardd6c0d862000-03-24 21:38:30 +00002892BOOL WINAPI EnumChildWindows( HWND parent, WNDENUMPROC func,
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002893 LPARAM lParam )
Alexandre Julliard3051b641996-07-05 17:14:13 +00002894{
2895 WND **list, *pParent;
2896
2897 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002898 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL )))
2899 {
2900 WIN_ReleaseWndPtr(pParent);
2901 return FALSE;
2902 }
Alexandre Julliardf1aa3031996-08-05 17:42:43 +00002903 WIN_EnumChildWindows( list, func, lParam );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002904 WIN_ReleaseWinArray(list);
2905 WIN_ReleaseWndPtr(pParent);
Alexandre Julliard3051b641996-07-05 17:14:13 +00002906 return TRUE;
2907}
2908
2909
Alexandre Julliard58199531994-04-21 01:20:00 +00002910/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002911 * AnyPopup (USER.52)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002912 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002913BOOL16 WINAPI AnyPopup16(void)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002914{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002915 return AnyPopup();
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002916}
2917
2918
2919/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002920 * AnyPopup (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002921 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002922BOOL WINAPI AnyPopup(void)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002923{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002924 WND *wndPtr = WIN_LockWndPtr(pWndDesktop->child);
2925 BOOL retvalue;
2926
2927 while (wndPtr)
2928 {
2929 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE))
2930 {
2931 retvalue = TRUE;
2932 goto end;
Andreas Mohr1c20b392000-02-20 19:17:35 +00002933 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002934 WIN_UpdateWndPtr(&wndPtr,wndPtr->next);
2935 }
2936 retvalue = FALSE;
2937end:
2938 WIN_ReleaseWndPtr(wndPtr);
2939 return retvalue;
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002940}
2941
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002942
Alexandre Julliard73450d61994-05-18 18:29:32 +00002943/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002944 * FlashWindow (USER.105)
Alexandre Julliard73450d61994-05-18 18:29:32 +00002945 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002946BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002947{
Alexandre Julliarda3960291999-02-26 11:11:13 +00002948 return FlashWindow( hWnd, bInvert );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002949}
2950
2951
2952/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002953 * FlashWindow (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00002954 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002955BOOL WINAPI FlashWindow( HWND hWnd, BOOL bInvert )
Alexandre Julliard73450d61994-05-18 18:29:32 +00002956{
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002957 WND *wndPtr = WIN_FindWndPtr(hWnd);
2958
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00002959 TRACE("%04x\n", hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002960
2961 if (!wndPtr) return FALSE;
2962
2963 if (wndPtr->dwStyle & WS_MINIMIZE)
2964 {
2965 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2966 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00002967 HDC hDC = GetDC(hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002968
Alexandre Julliard530ee841996-10-23 16:59:13 +00002969 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002970 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2971
Alexandre Julliarda3960291999-02-26 11:11:13 +00002972 ReleaseDC( hWnd, hDC );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002973 wndPtr->flags |= WIN_NCACTIVATED;
2974 }
2975 else
2976 {
Alexandre Julliard9ae0fe52001-04-24 23:28:52 +00002977 RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_FRAME );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002978 wndPtr->flags &= ~WIN_NCACTIVATED;
2979 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002980 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002981 return TRUE;
2982 }
2983 else
2984 {
Alexandre Julliard530ee841996-10-23 16:59:13 +00002985 WPARAM16 wparam;
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002986 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
Alexandre Julliarda3960291999-02-26 11:11:13 +00002987 else wparam = (hWnd == GetActiveWindow());
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002988
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002989 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00002990 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00002991 return wparam;
2992 }
Alexandre Julliard73450d61994-05-18 18:29:32 +00002993}
2994
Alexandre Julliardd18872d1994-05-11 12:18:19 +00002995
2996/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00002997 * SetSysModalWindow (USER.188)
Alexandre Julliard58199531994-04-21 01:20:00 +00002998 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00002999HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
Alexandre Julliard58199531994-04-21 01:20:00 +00003000{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003001 HWND hWndOldModal = hwndSysModal;
Alexandre Julliardd4719651995-12-12 18:49:11 +00003002 hwndSysModal = hWnd;
Dimitrie O. Paundd03cc11999-12-08 03:56:23 +00003003 FIXME("EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
Alexandre Julliardd4719651995-12-12 18:49:11 +00003004 return hWndOldModal;
Alexandre Julliard58199531994-04-21 01:20:00 +00003005}
3006
Alexandre Julliardd18872d1994-05-11 12:18:19 +00003007
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003008/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003009 * GetSysModalWindow (USER.189)
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003010 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003011HWND16 WINAPI GetSysModalWindow16(void)
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003012{
Alexandre Julliardd4719651995-12-12 18:49:11 +00003013 return hwndSysModal;
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00003014}
Alexandre Julliardade697e1995-11-26 13:59:11 +00003015
Alexandre Julliard18f92e71996-07-17 20:02:21 +00003016
Alexandre Julliardade697e1995-11-26 13:59:11 +00003017/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003018 * GetWindowContextHelpId (USER32.@)
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003019 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003020DWORD WINAPI GetWindowContextHelpId( HWND hwnd )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003021{
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003022 DWORD retval;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003023 WND *wnd = WIN_FindWndPtr( hwnd );
3024 if (!wnd) return 0;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003025 retval = wnd->helpContext;
3026 WIN_ReleaseWndPtr(wnd);
3027 return retval;
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003028}
3029
3030
3031/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003032 * SetWindowContextHelpId (USER32.@)
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003033 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003034BOOL WINAPI SetWindowContextHelpId( HWND hwnd, DWORD id )
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003035{
3036 WND *wnd = WIN_FindWndPtr( hwnd );
3037 if (!wnd) return FALSE;
3038 wnd->helpContext = id;
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003039 WIN_ReleaseWndPtr(wnd);
Alexandre Julliardc7c217b1998-04-13 12:21:30 +00003040 return TRUE;
3041}
3042
3043
3044/*******************************************************************
Alexandre Julliardade697e1995-11-26 13:59:11 +00003045 * DRAG_QueryUpdate
3046 *
3047 * recursively find a child that contains spDragInfo->pt point
3048 * and send WM_QUERYDROPOBJECT
3049 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003050BOOL16 DRAG_QueryUpdate( HWND hQueryWnd, SEGPTR spDragInfo, BOOL bNoSend )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003051{
Andreas Mohr1c20b392000-02-20 19:17:35 +00003052 BOOL16 wParam, bResult = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003053 POINT pt;
Alexandre Julliard982a2232000-12-13 20:20:09 +00003054 LPDRAGINFO16 ptrDragInfo = MapSL(spDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003055 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003056 RECT tempRect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003057
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003058 if( !ptrQueryWnd || !ptrDragInfo )
Andreas Mohr1c20b392000-02-20 19:17:35 +00003059 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003060
Alexandre Julliardd37eb361997-07-20 16:23:21 +00003061 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003062
Alexandre Julliarda3960291999-02-26 11:11:13 +00003063 GetWindowRect(hQueryWnd,&tempRect);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003064
Alexandre Julliarda3960291999-02-26 11:11:13 +00003065 if( !PtInRect(&tempRect,pt) ||
Alexandre Julliardade697e1995-11-26 13:59:11 +00003066 (ptrQueryWnd->dwStyle & WS_DISABLED) )
Andreas Mohr1c20b392000-02-20 19:17:35 +00003067 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003068
3069 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
3070 {
3071 tempRect = ptrQueryWnd->rectClient;
Alexandre Julliardf88e5aa2001-03-21 23:55:36 +00003072 if(ptrQueryWnd->parent)
Alexandre Julliarda3960291999-02-26 11:11:13 +00003073 MapWindowPoints( ptrQueryWnd->parent->hwndSelf, 0,
3074 (LPPOINT)&tempRect, 2 );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003075
Alexandre Julliarda3960291999-02-26 11:11:13 +00003076 if (PtInRect( &tempRect, pt))
Alexandre Julliardade697e1995-11-26 13:59:11 +00003077 {
3078 wParam = 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003079
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003080 for (ptrWnd = WIN_LockWndPtr(ptrQueryWnd->child); ptrWnd ;WIN_UpdateWndPtr(&ptrWnd,ptrWnd->next))
3081 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003082 if( ptrWnd->dwStyle & WS_VISIBLE )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003083 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003084 GetWindowRect( ptrWnd->hwndSelf, &tempRect );
3085 if (PtInRect( &tempRect, pt )) break;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003086 }
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003087 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003088
3089 if(ptrWnd)
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003090 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +00003091 TRACE_(msg)("hwnd = %04x, %d %d - %d %d\n",
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003092 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
3093 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
3094 if( !(ptrWnd->dwStyle & WS_DISABLED) )
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003095 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003096
3097 WIN_ReleaseWndPtr(ptrWnd);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00003098 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003099
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003100 if(bResult)
Andreas Mohr1c20b392000-02-20 19:17:35 +00003101 goto end;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003102 }
3103 else wParam = 1;
3104 }
3105 else wParam = 1;
3106
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00003107 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003108
3109 ptrDragInfo->hScope = hQueryWnd;
3110
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003111 bResult = ( bNoSend )
3112 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
3113 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
Alexandre Julliard530ee841996-10-23 16:59:13 +00003114 (WPARAM16)wParam ,(LPARAM) spDragInfo );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003115 if( !bResult )
Alexandre Julliardd37eb361997-07-20 16:23:21 +00003116 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003117
Andreas Mohr1c20b392000-02-20 19:17:35 +00003118end:
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003119 WIN_ReleaseWndPtr(ptrQueryWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003120 return bResult;
3121}
3122
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003123
Alexandre Julliardade697e1995-11-26 13:59:11 +00003124/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003125 * DragDetect (USER.465)
Alexandre Julliardade697e1995-11-26 13:59:11 +00003126 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003127BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003128{
Alexandre Julliarda3960291999-02-26 11:11:13 +00003129 POINT pt32;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003130 CONV_POINT16TO32( &pt, &pt32 );
Alexandre Julliarda3960291999-02-26 11:11:13 +00003131 return DragDetect( hWnd, pt32 );
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003132}
3133
3134/*******************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003135 * DragDetect (USER32.@)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +00003136 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003137BOOL WINAPI DragDetect( HWND hWnd, POINT pt )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003138{
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003139 MSG msg;
3140 RECT rect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003141
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003142 rect.left = pt.x - wDragWidth;
3143 rect.right = pt.x + wDragWidth;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003144
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003145 rect.top = pt.y - wDragHeight;
3146 rect.bottom = pt.y + wDragHeight;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003147
Alexandre Julliarda3960291999-02-26 11:11:13 +00003148 SetCapture(hWnd);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003149
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003150 while(1)
3151 {
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003152 while(PeekMessageA(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003153 {
3154 if( msg.message == WM_LBUTTONUP )
3155 {
3156 ReleaseCapture();
3157 return 0;
3158 }
3159 if( msg.message == WM_MOUSEMOVE )
3160 {
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003161 POINT tmp;
3162 tmp.x = LOWORD(msg.lParam);
3163 tmp.y = HIWORD(msg.lParam);
3164 if( !PtInRect( &rect, tmp ))
Alexandre Julliardade697e1995-11-26 13:59:11 +00003165 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003166 ReleaseCapture();
3167 return 1;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003168 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003169 }
3170 }
3171 WaitMessage();
3172 }
3173 return 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003174}
3175
3176/******************************************************************************
Patrik Stridvall2ece70e2000-12-22 01:38:01 +00003177 * DragObject (USER.464)
Alexandre Julliardade697e1995-11-26 13:59:11 +00003178 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +00003179DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
3180 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003181{
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003182 MSG msg;
Alexandre Julliard83f52d12000-09-26 22:20:14 +00003183 LPDRAGINFO16 lpDragInfo;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003184 SEGPTR spDragInfo;
3185 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
Alexandre Julliard83f52d12000-09-26 22:20:14 +00003186 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO16));
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003187 WND *wndPtr = WIN_FindWndPtr(hWnd);
3188 HCURSOR16 hCurrentCursor = 0;
3189 HWND16 hCurrentWnd = 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003190
Alexandre Julliard83f52d12000-09-26 22:20:14 +00003191 lpDragInfo = (LPDRAGINFO16) GlobalLock16(hDragInfo);
Alexandre Julliard58017232000-12-22 01:09:26 +00003192 spDragInfo = K32WOWGlobalLock16(hDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003193
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003194 if( !lpDragInfo || !spDragInfo )
3195 {
3196 WIN_ReleaseWndPtr(wndPtr);
3197 return 0L;
3198 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003199
Alexandre Julliard8bb7fb92001-01-20 02:48:30 +00003200 hBummer = LoadCursorA(0, MAKEINTRESOURCEA(OCR_NO));
Alexandre Julliardade697e1995-11-26 13:59:11 +00003201
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003202 if( !hBummer || !wndPtr )
3203 {
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00003204 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003205 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003206 return 0L;
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003207 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003208
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003209 if(hCursor)
3210 {
Alexandre Julliard75d86e11996-11-17 18:59:11 +00003211 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003212 {
3213 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003214 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003215 return 0L;
3216 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003217
3218 if( hDragCursor == hCursor ) hDragCursor = 0;
3219 else hCursor = hDragCursor;
3220
Alexandre Julliarda3960291999-02-26 11:11:13 +00003221 hOldCursor = SetCursor(hDragCursor);
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003222 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00003223
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003224 lpDragInfo->hWnd = hWnd;
3225 lpDragInfo->hScope = 0;
3226 lpDragInfo->wFlags = wObj;
3227 lpDragInfo->hList = szList; /* near pointer! */
3228 lpDragInfo->hOfStruct = hOfStruct;
3229 lpDragInfo->l = 0L;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003230
Alexandre Julliarda3960291999-02-26 11:11:13 +00003231 SetCapture(hWnd);
3232 ShowCursor( TRUE );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003233
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003234 do
3235 {
3236 do{ WaitMessage(); }
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003237 while( !PeekMessageA(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003238
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003239 *(lpDragInfo+1) = *lpDragInfo;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003240
Alexandre Julliard0ff083b2000-09-24 19:51:15 +00003241 lpDragInfo->pt.x = msg.pt.x;
3242 lpDragInfo->pt.y = msg.pt.y;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003243
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003244 /* update DRAGINFO struct */
Alexandre Julliard06c275a1999-05-02 14:32:27 +00003245 TRACE_(msg)("lpDI->hScope = %04x\n",lpDragInfo->hScope);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003246
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003247 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
3248 hCurrentCursor = hCursor;
3249 else
Alexandre Julliardade697e1995-11-26 13:59:11 +00003250 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003251 hCurrentCursor = hBummer;
3252 lpDragInfo->hScope = 0;
Alexandre Julliardade697e1995-11-26 13:59:11 +00003253 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003254 if( hCurrentCursor )
Alexandre Julliarda3960291999-02-26 11:11:13 +00003255 SetCursor(hCurrentCursor);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003256
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003257 /* send WM_DRAGLOOP */
3258 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
3259 (LPARAM) spDragInfo );
3260 /* send WM_DRAGSELECT or WM_DRAGMOVE */
3261 if( hCurrentWnd != lpDragInfo->hScope )
Alexandre Julliardade697e1995-11-26 13:59:11 +00003262 {
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003263 if( hCurrentWnd )
3264 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
Alexandre Julliard83f52d12000-09-26 22:20:14 +00003265 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO16),
Alexandre Julliardade697e1995-11-26 13:59:11 +00003266 HIWORD(spDragInfo)) );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003267 hCurrentWnd = lpDragInfo->hScope;
3268 if( hCurrentWnd )
3269 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003270 }
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003271 else
3272 if( hCurrentWnd )
3273 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
3274
3275 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
3276
3277 ReleaseCapture();
Alexandre Julliarda3960291999-02-26 11:11:13 +00003278 ShowCursor( FALSE );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003279
3280 if( hCursor )
3281 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00003282 SetCursor( hOldCursor );
3283 if (hDragCursor) DestroyCursor( hDragCursor );
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003284 }
3285
3286 if( hCurrentCursor != hBummer )
3287 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
3288 (WPARAM16)hWnd, (LPARAM)spDragInfo );
Alexandre Julliardade697e1995-11-26 13:59:11 +00003289 else
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003290 msg.lParam = 0;
3291 GlobalFree16(hDragInfo);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +00003292 WIN_ReleaseWndPtr(wndPtr);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003293
Alexandre Julliard23946ad1997-06-16 17:43:53 +00003294 return (DWORD)(msg.lParam);
Alexandre Julliardade697e1995-11-26 13:59:11 +00003295}
Eric Kohlca6c9a62001-03-20 01:53:51 +00003296
3297
3298/******************************************************************************
3299 * GetWindowModuleFileNameA (USER32.@)
3300 */
3301UINT WINAPI GetWindowModuleFileNameA( HWND hwnd, LPSTR lpszFileName, UINT cchFileNameMax)
3302{
3303 FIXME("GetWindowModuleFileNameA(hwnd 0x%x, lpszFileName %p, cchFileNameMax %u) stub!\n",
3304 hwnd, lpszFileName, cchFileNameMax);
3305 return 0;
3306}
3307
3308/******************************************************************************
3309 * GetWindowModuleFileNameW (USER32.@)
3310 */
3311UINT WINAPI GetWindowModuleFileNameW( HWND hwnd, LPSTR lpszFileName, UINT cchFileNameMax)
3312{
3313 FIXME("GetWindowModuleFileNameW(hwnd 0x%x, lpszFileName %p, cchFileNameMax %u) stub!\n",
3314 hwnd, lpszFileName, cchFileNameMax);
3315 return 0;
3316}