blob: 7fc2b2556d5061b772b5f3af2d3b7ce2dd061a5e [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>
8#include <stdio.h>
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00009#include <string.h>
Alexandre Julliard401710d1993-09-04 10:09:32 +000010
Alexandre Julliard36ca1361994-06-02 22:38:20 +000011#include "options.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000012#include "class.h"
13#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 Julliardcdd09231994-01-12 11:12:51 +000017#include "sysmetrics.h"
Alexandre Julliardaf0bae51995-10-03 17:06:08 +000018#include "cursoricon.h"
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000019#include "heap.h"
20#include "hook.h"
Alexandre Julliard1285c2f1996-05-06 16:06:24 +000021#include "menu.h"
Alexandre Julliardef702d81996-05-28 18:54:58 +000022#include "message.h"
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000023#include "nonclient.h"
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000024#include "string32.h"
Alexandre Julliardb817f4f1996-03-14 18:08:34 +000025#include "queue.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000026#include "winpos.h"
27#include "color.h"
Alexandre Julliarde2991ea1995-07-29 13:09:43 +000028#include "shm_main_blk.h"
29#include "dde_proc.h"
Alexandre Julliard3a405ba1994-10-30 16:25:19 +000030#include "callback.h"
Alexandre Julliard1e9ac791996-06-06 18:38:27 +000031#include "clipboard.h"
Alexandre Julliard2d93d001996-05-21 15:01:41 +000032#include "winproc.h"
Alexandre Julliardfa68b751995-04-03 16:55:37 +000033#include "stddebug.h"
Alexandre Julliard234bc241994-12-10 13:02:28 +000034/* #define DEBUG_WIN */
35/* #define DEBUG_MENU */
Alexandre Julliardaca05781994-10-17 18:12:41 +000036#include "debug.h"
Alexandre Julliard401710d1993-09-04 10:09:32 +000037
Alexandre Julliard59730ae1996-03-24 16:20:51 +000038/* Desktop window */
39static WND *pWndDesktop = NULL;
40
Alexandre Julliardd4719651995-12-12 18:49:11 +000041static HWND hwndSysModal = 0;
Alexandre Julliard401710d1993-09-04 10:09:32 +000042
Alexandre Julliardd4719651995-12-12 18:49:11 +000043static WORD wDragWidth = 4;
44static WORD wDragHeight= 3;
Alexandre Julliardade697e1995-11-26 13:59:11 +000045
46extern HCURSOR CURSORICON_IconToCursor(HICON);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000047extern HQUEUE QUEUE_GetDoomedQueue();
Alexandre Julliardade697e1995-11-26 13:59:11 +000048
Alexandre Julliard401710d1993-09-04 10:09:32 +000049/***********************************************************************
50 * WIN_FindWndPtr
51 *
52 * Return a pointer to the WND structure corresponding to a HWND.
Alexandre Julliard401710d1993-09-04 10:09:32 +000053 */
54WND * WIN_FindWndPtr( HWND hwnd )
55{
56 WND * ptr;
57
58 if (!hwnd) return NULL;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000059 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
Alexandre Julliardf0b23541993-09-29 12:21:49 +000060 if (ptr->dwMagic != WND_MAGIC) return NULL;
Alexandre Julliard59730ae1996-03-24 16:20:51 +000061 if (ptr->hwndSelf != hwnd)
62 {
63 fprintf( stderr, "Can't happen: hwnd %04x self pointer is %04x\n",
64 hwnd, ptr->hwndSelf );
65 return NULL;
66 }
Alexandre Julliard401710d1993-09-04 10:09:32 +000067 return ptr;
68}
69
70
71/***********************************************************************
Alexandre Julliardb817f4f1996-03-14 18:08:34 +000072 * WIN_DumpWindow
73 *
74 * Dump the content of a window structure to stderr.
75 */
76void WIN_DumpWindow( HWND hwnd )
77{
Alexandre Julliardb817f4f1996-03-14 18:08:34 +000078 WND *ptr;
79 char className[80];
80 int i;
81
82 if (!(ptr = WIN_FindWndPtr( hwnd )))
83 {
84 fprintf( stderr, "%04x is not a window handle\n", hwnd );
85 return;
86 }
87
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000088 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
Alexandre Julliardb817f4f1996-03-14 18:08:34 +000089 strcpy( className, "#NULL#" );
90
Alexandre Julliard59730ae1996-03-24 16:20:51 +000091 fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +000092 fprintf( stderr,
Alexandre Julliard2ace16a1996-04-28 15:09:19 +000093 "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
Alexandre Julliardb817f4f1996-03-14 18:08:34 +000094 "inst=%04x taskQ=%04x updRgn=%04x active=%04x hdce=%04x idmenu=%04x\n"
Alexandre Julliard1e9ac791996-06-06 18:38:27 +000095 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
Alexandre Julliardb817f4f1996-03-14 18:08:34 +000096 "client=%d,%d-%d,%d window=%d,%d-%d,%d iconpos=%d,%d maxpos=%d,%d\n"
97 "sysmenu=%04x flags=%04x props=%04x vscroll=%04x hscroll=%04x\n",
Alexandre Julliard59730ae1996-03-24 16:20:51 +000098 ptr->next, ptr->child, ptr->parent, ptr->owner,
Alexandre Julliard2ace16a1996-04-28 15:09:19 +000099 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000100 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->hdce, ptr->wIDmenu,
Alexandre Julliard3051b641996-07-05 17:14:13 +0000101 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000102 ptr->text ? ptr->text : "",
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000103 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
104 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
105 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x,
106 ptr->ptIconPos.y, ptr->ptMaxPos.x, ptr->ptMaxPos.y, ptr->hSysMenu,
107 ptr->flags, ptr->hProp, ptr->hVScroll, ptr->hHScroll );
108
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000109 if (ptr->class->cbWndExtra)
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000110 {
111 fprintf( stderr, "extra bytes:" );
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000112 for (i = 0; i < ptr->class->cbWndExtra; i++)
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000113 fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
114 fprintf( stderr, "\n" );
115 }
116 fprintf( stderr, "\n" );
117}
118
119
120/***********************************************************************
121 * WIN_WalkWindows
122 *
123 * Walk the windows tree and print each window on stderr.
124 */
125void WIN_WalkWindows( HWND hwnd, int indent )
126{
127 WND *ptr;
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000128 char className[80];
129
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000130 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
131 if (!ptr)
132 {
Alexandre Julliard3051b641996-07-05 17:14:13 +0000133 fprintf( stderr, "*** Invalid window handle %04x\n", hwnd );
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000134 return;
135 }
136
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000137 if (!indent) /* first time around */
138 fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
139 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
140
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000141 while (ptr)
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000142 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000143 fprintf(stderr, "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000144
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000145 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000146
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000147 fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %08x\n",
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000148 (DWORD)ptr, ptr->hmemTaskQ, className,
Alexandre Julliard3051b641996-07-05 17:14:13 +0000149 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000150
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000151 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
152 ptr = ptr->next;
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000153 }
154}
155
156
157/***********************************************************************
Alexandre Julliardaca05781994-10-17 18:12:41 +0000158 * WIN_GetXWindow
159 *
160 * Return the X window associated to a window.
161 */
162Window WIN_GetXWindow( HWND hwnd )
163{
164 WND *wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000165 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000166 return wndPtr ? wndPtr->window : 0;
167}
168
169
170/***********************************************************************
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000171 * WIN_UnlinkWindow
172 *
173 * Remove a window from the siblings linked list.
174 */
175BOOL WIN_UnlinkWindow( HWND hwnd )
176{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000177 WND *wndPtr, **ppWnd;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000178
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000179 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
180 ppWnd = &wndPtr->parent->child;
181 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
182 *ppWnd = wndPtr->next;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000183 return TRUE;
184}
185
186
187/***********************************************************************
188 * WIN_LinkWindow
189 *
190 * Insert a window into the siblings linked list.
191 * The window is inserted after the specified window, which can also
192 * be specified as HWND_TOP or HWND_BOTTOM.
193 */
194BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
195{
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000196 WND *wndPtr, **ppWnd;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000197
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000198 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000199
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000200 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
201 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000202 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000203 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000204 while (*ppWnd) ppWnd = &(*ppWnd)->next;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000205 }
206 else /* Normal case */
207 {
208 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000209 if (!afterPtr) return FALSE;
210 ppWnd = &afterPtr->next;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000211 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000212 wndPtr->next = *ppWnd;
213 *ppWnd = wndPtr;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000214 return TRUE;
215}
216
217
218/***********************************************************************
Alexandre Julliard401710d1993-09-04 10:09:32 +0000219 * WIN_FindWinToRepaint
220 *
221 * Find a window that needs repaint.
222 */
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000223HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE hQueue )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000224{
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000225 HWND hwndRet;
226 WND *pWnd = pWndDesktop;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000227
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000228 /* Note: the desktop window never gets WM_PAINT messages */
229 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
230
231 for ( ; pWnd ; pWnd = pWnd->next )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000232 {
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000233 if (!(pWnd->dwStyle & WS_VISIBLE) || (pWnd->flags & WIN_NO_REDRAW))
234 {
235 dprintf_win( stddeb, "FindWinToRepaint: skipping window %04x\n",
236 pWnd->hwndSelf );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000237 continue;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000238 }
239 if ((pWnd->hmemTaskQ == hQueue) &&
240 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
241
242 if (pWnd->child )
243 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
244 return hwndRet;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000245 }
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000246
247 if (!pWnd) return 0;
248
249 hwndRet = pWnd->hwndSelf;
250
251 /* look among siblings if we got a transparent window */
252 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
253 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
254 {
255 pWnd = pWnd->next;
256 }
257 if (pWnd) hwndRet = pWnd->hwndSelf;
258 dprintf_win(stddeb,"FindWinToRepaint: found %04x\n",hwndRet);
259 return hwndRet;
Alexandre Julliard401710d1993-09-04 10:09:32 +0000260}
261
262
263/***********************************************************************
Alexandre Julliard0e607781993-11-03 19:23:37 +0000264 * WIN_SendParentNotify
265 *
266 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
267 * the window has the WS_EX_NOPARENTNOTIFY style.
268 */
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000269void WIN_SendParentNotify( HWND hwnd, WORD event, WORD idChild, LONG lValue )
Alexandre Julliard0e607781993-11-03 19:23:37 +0000270{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000271 LPPOINT16 lppt = (LPPOINT16)&lValue;
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000272 WND *wndPtr = WIN_FindWndPtr( hwnd );
273 BOOL bMouse = ((event <= WM_MOUSELAST) && (event >= WM_MOUSEFIRST));
274
275 /* if lValue contains cursor coordinates they have to be
276 * mapped to the client area of parent window */
277
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000278 if (bMouse) MapWindowPoints16(0, hwnd, lppt, 1);
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000279#ifndef WINELIB32
280 else lValue = MAKELONG( LOWORD(lValue), idChild );
281#endif
282
283 while (wndPtr)
Alexandre Julliard0e607781993-11-03 19:23:37 +0000284 {
Alexandre Julliardc981d0b1996-03-31 16:40:13 +0000285 if ((wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) ||
286 !(wndPtr->dwStyle & WS_CHILD)) break;
287
288 if (bMouse)
289 {
290 lppt->x += wndPtr->rectClient.left;
291 lppt->y += wndPtr->rectClient.top;
292 }
293
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000294 wndPtr = wndPtr->parent;
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000295#ifdef WINELIB32
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000296 SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY,
297 MAKEWPARAM( event, idChild ), lValue );
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000298#else
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000299 SendMessage16( wndPtr->hwndSelf, WM_PARENTNOTIFY, event, (LPARAM)lValue);
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000300#endif
Alexandre Julliard0e607781993-11-03 19:23:37 +0000301 }
302}
303
304
305/***********************************************************************
Alexandre Julliardaca05781994-10-17 18:12:41 +0000306 * WIN_DestroyWindow
307 *
308 * Destroy storage associated to a window
309 */
310static void WIN_DestroyWindow( HWND hwnd )
311{
312 WND *wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000313
Alexandre Julliardb7258be1995-09-01 15:57:28 +0000314#ifdef CONFIG_IPC
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000315 if (main_block)
316 DDE_DestroyWindow(hwnd);
Alexandre Julliardb7258be1995-09-01 15:57:28 +0000317#endif /* CONFIG_IPC */
Alexandre Julliarde2991ea1995-07-29 13:09:43 +0000318
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000319 if (!wndPtr) return;
Alexandre Julliardecc37121994-11-22 16:31:29 +0000320 WIN_UnlinkWindow( hwnd ); /* Remove the window from the linked list */
Alexandre Julliardef702d81996-05-28 18:54:58 +0000321 TIMER_RemoveWindowTimers( hwnd );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000322 wndPtr->dwMagic = 0; /* Mark it as invalid */
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000323 wndPtr->hwndSelf = 0;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000324 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
325 {
326 if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
Alexandre Julliardb817f4f1996-03-14 18:08:34 +0000327 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000328 }
329 if (!(wndPtr->dwStyle & WS_CHILD))
330 {
Alexandre Julliard902da691995-11-05 14:39:02 +0000331 if (wndPtr->wIDmenu) DestroyMenu( (HMENU)wndPtr->wIDmenu );
Alexandre Julliardaca05781994-10-17 18:12:41 +0000332 }
333 if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
334 if (wndPtr->window) XDestroyWindow( display, wndPtr->window );
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000335 if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->hdce );
Alexandre Julliard3051b641996-07-05 17:14:13 +0000336 WINPROC_FreeProc( wndPtr->winproc );
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000337 wndPtr->class->cWindows--;
Alexandre Julliardaca05781994-10-17 18:12:41 +0000338 USER_HEAP_FREE( hwnd );
339}
340
341
342/***********************************************************************
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000343 * WIN_DestroyQueueWindows
344 */
345void WIN_DestroyQueueWindows( WND* wnd, HQUEUE hQueue )
346{
347 WND* next;
348
349 while (wnd)
350 {
351 next = wnd->next;
352 if (wnd->hmemTaskQ == hQueue) DestroyWindow( wnd->hwndSelf );
353 else WIN_DestroyQueueWindows( wnd->child, hQueue );
354 wnd = next;
355 }
356}
357
358
359/***********************************************************************
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000360 * WIN_CreateDesktopWindow
361 *
362 * Create the desktop window.
363 */
Alexandre Julliarda2f2e011995-06-06 16:40:35 +0000364BOOL WIN_CreateDesktopWindow(void)
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000365{
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000366 CLASS *class;
Alexandre Julliard2787be81995-05-22 18:23:01 +0000367 HDC hdc;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000368 HWND hwndDesktop;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000369
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000370 dprintf_win(stddeb,"Creating desktop window\n");
371
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000372 if (!(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000373 return FALSE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000374
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000375 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000376 if (!hwndDesktop) return FALSE;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000377 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000378
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000379 pWndDesktop->next = NULL;
380 pWndDesktop->child = NULL;
381 pWndDesktop->parent = NULL;
382 pWndDesktop->owner = NULL;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000383 pWndDesktop->class = class;
Alexandre Julliard3051b641996-07-05 17:14:13 +0000384 pWndDesktop->winproc = NULL;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000385 pWndDesktop->dwMagic = WND_MAGIC;
386 pWndDesktop->hwndSelf = hwndDesktop;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000387 pWndDesktop->hInstance = 0;
388 pWndDesktop->rectWindow.left = 0;
389 pWndDesktop->rectWindow.top = 0;
390 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
391 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
392 pWndDesktop->rectClient = pWndDesktop->rectWindow;
393 pWndDesktop->rectNormal = pWndDesktop->rectWindow;
394 pWndDesktop->ptIconPos.x = -1;
395 pWndDesktop->ptIconPos.y = -1;
396 pWndDesktop->ptMaxPos.x = -1;
397 pWndDesktop->ptMaxPos.y = -1;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000398 pWndDesktop->text = NULL;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000399 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
400 pWndDesktop->hrgnUpdate = 0;
401 pWndDesktop->hwndLastActive = hwndDesktop;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000402 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
403 WS_CLIPSIBLINGS;
404 pWndDesktop->dwExStyle = 0;
405 pWndDesktop->hdce = 0;
406 pWndDesktop->hVScroll = 0;
407 pWndDesktop->hHScroll = 0;
408 pWndDesktop->wIDmenu = 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000409 pWndDesktop->flags = 0;
410 pWndDesktop->window = rootWindow;
411 pWndDesktop->hSysMenu = 0;
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000412 pWndDesktop->hProp = 0;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000413 pWndDesktop->userdata = 0;
414
Alexandre Julliard3051b641996-07-05 17:14:13 +0000415 WINPROC_SetProc( &pWndDesktop->winproc, (WNDPROC16)class->winproc, 0 );
Alexandre Julliard8b915631996-06-16 16:16:05 +0000416 EVENT_RegisterWindow( pWndDesktop );
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000417 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
Alexandre Julliard2787be81995-05-22 18:23:01 +0000418 if ((hdc = GetDC( hwndDesktop )) != 0)
419 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000420 SendMessage32A( hwndDesktop, WM_ERASEBKGND, hdc, 0 );
Alexandre Julliard2787be81995-05-22 18:23:01 +0000421 ReleaseDC( hwndDesktop, hdc );
422 }
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000423 return TRUE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000424}
425
426
427/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000428 * WIN_CreateWindowEx
429 *
430 * Implementation of CreateWindowEx().
Alexandre Julliard401710d1993-09-04 10:09:32 +0000431 */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000432static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
433 BOOL unicode )
Alexandre Julliard401710d1993-09-04 10:09:32 +0000434{
Alexandre Julliard401710d1993-09-04 10:09:32 +0000435 CLASS *classPtr;
Alexandre Julliardd2e1c1a1996-03-09 16:12:43 +0000436 WND *wndPtr;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000437 HWND16 hwnd;
438 POINT16 maxSize, maxPos, minTrack, maxTrack;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000439 LRESULT wmcreate;
440
441 dprintf_win( stddeb, "CreateWindowEx: " );
442 if (HIWORD(cs->lpszName)) dprintf_win( stddeb, "'%s' ", cs->lpszName );
443 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszName) );
444 if (HIWORD(cs->lpszClass)) dprintf_win( stddeb, "'%s' ", cs->lpszClass );
445 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszClass) );
446
447 dprintf_win( stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %p\n",
448 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
449 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
Alexandre Julliard401710d1993-09-04 10:09:32 +0000450
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000451 /* Find the parent window */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000452
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000453 if (cs->hwndParent)
Alexandre Julliard401710d1993-09-04 10:09:32 +0000454 {
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000455 /* Make sure parent is valid */
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000456 if (!IsWindow( cs->hwndParent ))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000457 {
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000458 fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000459 return 0;
Alexandre Julliardfa68b751995-04-03 16:55:37 +0000460 }
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000461 }
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000462 else if (cs->style & WS_CHILD)
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000463 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000464 fprintf( stderr, "CreateWindowEx: no parent for child window\n" );
465 return 0; /* WS_CHILD needs a parent */
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000466 }
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000467
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000468 /* Find the window class */
469
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000470 if (!(classPtr = CLASS_FindClassByAtom( classAtom,
471 GetExePtr(cs->hInstance) )))
Alexandre Julliard808cb041995-08-17 17:11:36 +0000472 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000473 char buffer[256];
474 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
475 fprintf( stderr, "CreateWindowEx: bad class '%s'\n", buffer );
Alexandre Julliardff8331e1995-09-18 11:19:54 +0000476 return 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000477 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000478
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000479 /* Fix the coordinates */
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000480
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000481 if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0;
482 if (cs->cx == CW_USEDEFAULT32)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000483 {
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000484/* if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000485 else */
486 {
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000487 cs->cx = 600;
488 cs->cy = 400;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000489 }
490 }
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000491
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000492 /* Create the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000493
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000494 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
495 - sizeof(wndPtr->wExtra) )))
496 {
497 dprintf_win( stddeb, "CreateWindowEx: out of memory\n" );
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000498 return 0;
499 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000500
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000501 /* Fill the window structure */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000502
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000503 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000504 wndPtr->next = NULL;
505 wndPtr->child = NULL;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000506 wndPtr->parent = (cs->style & WS_CHILD) ?
507 WIN_FindWndPtr( cs->hwndParent ) : pWndDesktop;
508 wndPtr->owner = (cs->style & WS_CHILD) ? NULL :
509 WIN_FindWndPtr(WIN_GetTopParent(cs->hwndParent));
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000510 wndPtr->window = 0;
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000511 wndPtr->class = classPtr;
Alexandre Julliard3051b641996-07-05 17:14:13 +0000512 wndPtr->winproc = NULL;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000513 wndPtr->dwMagic = WND_MAGIC;
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000514 wndPtr->hwndSelf = hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000515 wndPtr->hInstance = cs->hInstance;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000516 wndPtr->ptIconPos.x = -1;
517 wndPtr->ptIconPos.y = -1;
518 wndPtr->ptMaxPos.x = -1;
519 wndPtr->ptMaxPos.y = -1;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000520 wndPtr->text = NULL;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000521 wndPtr->hmemTaskQ = GetTaskQueue(0);
522 wndPtr->hrgnUpdate = 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000523 wndPtr->hwndLastActive = hwnd;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000524 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
525 wndPtr->dwExStyle = cs->dwExStyle;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000526 wndPtr->wIDmenu = 0;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000527 wndPtr->flags = 0;
528 wndPtr->hVScroll = 0;
529 wndPtr->hHScroll = 0;
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000530 wndPtr->hSysMenu = MENU_GetDefSysMenu();
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000531 wndPtr->hProp = 0;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000532 wndPtr->userdata = 0;
Alexandre Julliardf0b23541993-09-29 12:21:49 +0000533
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000534 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
Alexandre Julliard401710d1993-09-04 10:09:32 +0000535 classPtr->cWindows++;
536
Alexandre Julliard3051b641996-07-05 17:14:13 +0000537 /* Set the window procedure */
538
539 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)classPtr->winproc, 0 );
540
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000541 /* Correct the window style */
542
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000543 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000544 {
545 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
546 wndPtr->flags |= WIN_NEED_SIZE;
547 }
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000548 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000549
550 /* Get class or window DC if needed */
Alexandre Julliardaca05781994-10-17 18:12:41 +0000551
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000552 if (classPtr->style & CS_OWNDC) wndPtr->hdce = DCE_AllocDCE(hwnd, DCE_WINDOW_DC);
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000553 else if (classPtr->style & CS_CLASSDC) wndPtr->hdce = classPtr->hdce;
554 else wndPtr->hdce = 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000555
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000556 /* Insert the window in the linked list */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000557
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000558 WIN_LinkWindow( hwnd, HWND_TOP );
559
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000560 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
Alexandre Julliard988ca971994-06-21 16:15:21 +0000561
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000562 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000563 {
564 NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000565 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
566 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000567 }
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000568 if (cs->cx <= 0) cs->cx = 1;
569 if (cs->cy <= 0) cs->cy = 1;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000570
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000571 wndPtr->rectWindow.left = cs->x;
572 wndPtr->rectWindow.top = cs->y;
573 wndPtr->rectWindow.right = cs->x + cs->cx;
574 wndPtr->rectWindow.bottom = cs->y + cs->cy;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000575 wndPtr->rectClient = wndPtr->rectWindow;
576 wndPtr->rectNormal = wndPtr->rectWindow;
Alexandre Julliard940d58c1994-09-16 09:24:37 +0000577
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000578 /* Create the X window (only for top-level windows, and then only */
579 /* when there's no desktop window) */
Alexandre Julliard0e607781993-11-03 19:23:37 +0000580
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000581 if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
Alexandre Julliardaca05781994-10-17 18:12:41 +0000582 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000583 XSetWindowAttributes win_attr;
584 Atom XA_WM_DELETE_WINDOW;
585
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000586 if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
587 (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000588 {
Alexandre Julliardd4719651995-12-12 18:49:11 +0000589 win_attr.event_mask = ExposureMask | KeyPressMask |
590 KeyReleaseMask | PointerMotionMask |
591 ButtonPressMask | ButtonReleaseMask |
592 FocusChangeMask | StructureNotifyMask;
593 win_attr.override_redirect = FALSE;
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000594 wndPtr->flags |= WIN_MANAGED;
Alexandre Julliardd4719651995-12-12 18:49:11 +0000595 }
Alexandre Julliard0c126c71996-02-18 18:44:41 +0000596 else
597 {
Alexandre Julliardd4719651995-12-12 18:49:11 +0000598 win_attr.event_mask = ExposureMask | KeyPressMask |
599 KeyReleaseMask | PointerMotionMask |
600 ButtonPressMask | ButtonReleaseMask |
601 FocusChangeMask;
602 win_attr.override_redirect = TRUE;
603 }
Alexandre Julliardaca05781994-10-17 18:12:41 +0000604 win_attr.colormap = COLOR_WinColormap;
605 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
Alexandre Julliard1285c2f1996-05-06 16:06:24 +0000606 win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
Alexandre Julliardaf0bae51995-10-03 17:06:08 +0000607 win_attr.cursor = CURSORICON_XCursor;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000608 wndPtr->window = XCreateWindow( display, rootWindow, cs->x, cs->y,
609 cs->cx, cs->cy, 0, CopyFromParent,
Alexandre Julliardaca05781994-10-17 18:12:41 +0000610 InputOutput, CopyFromParent,
611 CWEventMask | CWOverrideRedirect |
612 CWColormap | CWCursor | CWSaveUnder |
613 CWBackingStore, &win_attr );
Alexandre Julliard02ed4c21996-03-02 19:34:10 +0000614 XA_WM_DELETE_WINDOW = XInternAtom( display, "WM_DELETE_WINDOW",
615 False );
616 XSetWMProtocols( display, wndPtr->window, &XA_WM_DELETE_WINDOW, 1 );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000617 if (cs->hwndParent) /* Get window owner */
Alexandre Julliard02ed4c21996-03-02 19:34:10 +0000618 {
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000619 Window win = WIN_GetXWindow( cs->hwndParent );
Alexandre Julliard02ed4c21996-03-02 19:34:10 +0000620 if (win) XSetTransientForHint( display, wndPtr->window, win );
621 }
Alexandre Julliard8b915631996-06-16 16:16:05 +0000622 EVENT_RegisterWindow( wndPtr );
Alexandre Julliard988ca971994-06-21 16:15:21 +0000623 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000624
625 /* Set the window menu */
626
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000627 if ((cs->style & WS_CAPTION) && !(cs->style & WS_CHILD))
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000628 {
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000629 if (cs->hMenu) SetMenu(hwnd, cs->hMenu);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000630 else
631 {
632#if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
633 if (classPtr->menuNameA)
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000634 cs->hMenu = HIWORD(classPtr->menuNameA) ?
635 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
636 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000637#else
638 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000639 if (menuName) cs->hMenu = LoadMenu( cs->hInstance, menuName );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000640#endif
641 }
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000642 if (cs->hMenu) SetMenu( hwnd, cs->hMenu );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000643 }
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000644 else wndPtr->wIDmenu = (UINT)cs->hMenu;
Alexandre Julliard490a27e1994-06-08 13:57:50 +0000645
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000646 /* Send the WM_CREATE message */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000647
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000648 if (unicode)
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000649 {
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000650 if (!SendMessage32W( hwnd, WM_NCCREATE, 0, (LPARAM)cs)) wmcreate = -1;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000651 else
652 {
653 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
654 NULL, NULL, 0, &wndPtr->rectClient );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000655 wmcreate = SendMessage32W( hwnd, WM_CREATE, 0, (LPARAM)cs );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000656 }
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000657 }
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000658 else
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000659 {
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000660 if (!SendMessage32A( hwnd, WM_NCCREATE, 0, (LPARAM)cs)) wmcreate = -1;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000661 else
662 {
663 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
664 NULL, NULL, 0, &wndPtr->rectClient );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000665 wmcreate = SendMessage32A( hwnd, WM_CREATE, 0, (LPARAM)cs );
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000666 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000667 }
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000668
Alexandre Julliard401710d1993-09-04 10:09:32 +0000669 if (wmcreate == -1)
670 {
671 /* Abort window creation */
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +0000672 dprintf_win(stddeb,"CreateWindowEx: wmcreate==-1, aborting\n");
Alexandre Julliardaca05781994-10-17 18:12:41 +0000673 WIN_DestroyWindow( hwnd );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000674 return 0;
675 }
Alexandre Julliard401710d1993-09-04 10:09:32 +0000676
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000677 /* Send the size messages */
678
679 if (!(wndPtr->flags & WIN_NEED_SIZE))
680 {
681 /* send it anyway */
682 SendMessage16( hwnd, WM_SIZE, SIZE_RESTORED,
683 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
684 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
685 SendMessage16( hwnd, WM_MOVE, 0, MAKELONG( wndPtr->rectClient.left,
686 wndPtr->rectClient.top ));
687 }
688
689 WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LONG)hwnd );
690 if (!IsWindow(hwnd)) return 0;
691
692 /* Show the window, maximizing or minimizing if needed */
693
694 if (wndPtr->dwStyle & WS_MINIMIZE)
695 {
696 wndPtr->dwStyle &= ~WS_MAXIMIZE;
697 WINPOS_FindIconPos( hwnd );
698 SetWindowPos( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
699 SYSMETRICS_CXICON, SYSMETRICS_CYICON, SWP_FRAMECHANGED |
Alexandre Julliard3051b641996-07-05 17:14:13 +0000700 ((cs->style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 ));
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000701 }
702 else if (wndPtr->dwStyle & WS_MAXIMIZE)
703 {
704 POINT16 maxSize, maxPos, minTrack, maxTrack;
705 NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
706 SetWindowPos( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
Alexandre Julliard3051b641996-07-05 17:14:13 +0000707 SWP_FRAMECHANGED | ((cs->style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0) );
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000708 }
709 else if (cs->style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
710
711 /* Call WH_SHELL hook */
712
713 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
714 HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
715
716 dprintf_win(stddeb, "CreateWindowEx: returning %04x\n", hwnd);
717 return hwnd;
718}
719
720
721/***********************************************************************
722 * CreateWindow16 (USER.41)
723 */
724HWND16 CreateWindow16( LPCSTR className, LPCSTR windowName,
725 DWORD style, INT16 x, INT16 y, INT16 width,
726 INT16 height, HWND16 parent, HMENU16 menu,
727 HINSTANCE16 instance, LPVOID data )
728{
729 return CreateWindowEx16( 0, className, windowName, style,
730 x, y, width, height, parent, menu, instance, data );
731}
732
733
734/***********************************************************************
735 * CreateWindowEx16 (USER.452)
736 */
737HWND16 CreateWindowEx16( DWORD exStyle, LPCSTR className, LPCSTR windowName,
738 DWORD style, INT16 x, INT16 y, INT16 width,
739 INT16 height, HWND16 parent, HMENU16 menu,
740 HINSTANCE16 instance, LPVOID data )
741{
742 ATOM classAtom;
743 CREATESTRUCT32A cs;
744
745 /* Find the class atom */
746
747 if (!(classAtom = GlobalFindAtom32A( className )))
748 {
749 fprintf( stderr, "CreateWindowEx16: bad class name " );
750 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
751 else fprintf( stderr, "'%s'\n", className );
752 return 0;
753 }
754
755 /* Fix the coordinates */
756
757 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
758 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
759 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
760 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
761
762 /* Create the window */
763
764 cs.lpCreateParams = data;
765 cs.hInstance = (HINSTANCE32)instance;
766 cs.hMenu = (HMENU32)menu;
767 cs.hwndParent = (HWND32)parent;
768 cs.style = style;
769 cs.lpszName = windowName;
770 cs.lpszClass = className;
771 cs.dwExStyle = exStyle;
772 return WIN_CreateWindowEx( &cs, classAtom, FALSE );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000773}
774
775
776/***********************************************************************
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000777 * CreateWindowEx32A (USER32.82)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000778 */
779HWND32 CreateWindowEx32A( DWORD exStyle, LPCSTR className, LPCSTR windowName,
780 DWORD style, INT32 x, INT32 y, INT32 width,
781 INT32 height, HWND32 parent, HMENU32 menu,
782 HINSTANCE32 instance, LPVOID data )
783{
784 ATOM classAtom;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000785 CREATESTRUCT32A cs;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000786
787 /* Find the class atom */
788
789 if (!(classAtom = GlobalFindAtom32A( className )))
790 {
791 fprintf( stderr, "CreateWindowEx32A: bad class name " );
792 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000793 else fprintf( stderr, "'%s'\n", className );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000794 return 0;
795 }
796
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000797 /* Create the window */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000798
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000799 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000800 cs.hInstance = instance;
801 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000802 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000803 cs.x = x;
804 cs.y = y;
805 cs.cx = width;
806 cs.cy = height;
807 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000808 cs.lpszName = windowName;
809 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000810 cs.dwExStyle = exStyle;
811 return WIN_CreateWindowEx( &cs, classAtom, FALSE );
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000812}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000813
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000814
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000815/***********************************************************************
816 * CreateWindowEx32W (USER32.83)
817 */
818HWND32 CreateWindowEx32W( DWORD exStyle, LPCWSTR className, LPCWSTR windowName,
819 DWORD style, INT32 x, INT32 y, INT32 width,
820 INT32 height, HWND32 parent, HMENU32 menu,
821 HINSTANCE32 instance, LPVOID data )
822{
823 ATOM classAtom;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000824 CREATESTRUCT32W cs;
825
826 /* Find the class atom */
827
828 if (!(classAtom = GlobalFindAtom32W( className )))
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000829 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000830 fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
831 return 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000832 }
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000833
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000834 /* Create the window */
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000835
836 cs.lpCreateParams = data;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000837 cs.hInstance = instance;
838 cs.hMenu = menu;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000839 cs.hwndParent = parent;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000840 cs.x = x;
841 cs.y = y;
842 cs.cx = width;
843 cs.cy = height;
844 cs.style = style;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000845 cs.lpszName = windowName;
846 cs.lpszClass = className;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000847 cs.dwExStyle = exStyle;
848 /* Note: we rely on the fact that CREATESTRUCT32A and */
849 /* CREATESTRUCT32W have the same layout. */
850 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000851}
852
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000853
Alexandre Julliard401710d1993-09-04 10:09:32 +0000854/***********************************************************************
855 * DestroyWindow (USER.53)
856 */
857BOOL DestroyWindow( HWND hwnd )
858{
Alexandre Julliard0e607781993-11-03 19:23:37 +0000859 WND * wndPtr;
Alexandre Julliard3a405ba1994-10-30 16:25:19 +0000860
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000861 dprintf_win(stddeb, "DestroyWindow(%04x)\n", hwnd);
Alexandre Julliard401710d1993-09-04 10:09:32 +0000862
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000863 /* Initialization */
Alexandre Julliard401710d1993-09-04 10:09:32 +0000864
Alexandre Julliard0e607781993-11-03 19:23:37 +0000865 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000866 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
Alexandre Julliard58199531994-04-21 01:20:00 +0000867
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000868 /* Top-level window */
869
870 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
871 {
872 HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
873 /* FIXME: clean up palette - see "Internals" p.352 */
874 }
875
Alexandre Julliard58199531994-04-21 01:20:00 +0000876 /* Hide the window */
877
878 if (wndPtr->dwStyle & WS_VISIBLE)
879 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE |
880 SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
881 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
882 ReleaseCapture();
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000883 if (!QUEUE_GetDoomedQueue())
884 WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LONG)hwnd );
Alexandre Julliard0e607781993-11-03 19:23:37 +0000885
Alexandre Julliard22945d51995-03-02 17:44:29 +0000886 /* Recursively destroy owned windows */
887
888 for (;;)
889 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000890 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
891 while (siblingPtr)
Alexandre Julliard22945d51995-03-02 17:44:29 +0000892 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000893 if (siblingPtr->owner == wndPtr) break;
894 siblingPtr = siblingPtr->next;
Alexandre Julliard22945d51995-03-02 17:44:29 +0000895 }
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000896 if (siblingPtr) DestroyWindow( siblingPtr->hwndSelf );
Alexandre Julliard22945d51995-03-02 17:44:29 +0000897 else break;
898 }
899
Alexandre Julliard1e9ac791996-06-06 18:38:27 +0000900 CLIPBOARD_DisOwn( hwnd );
901
Alexandre Julliardfb9a9191994-03-01 19:48:04 +0000902 /* Send destroy messages and destroy children */
Alexandre Julliard0e607781993-11-03 19:23:37 +0000903
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000904 SendMessage16( hwnd, WM_DESTROY, 0, 0 );
Alexandre Julliard59730ae1996-03-24 16:20:51 +0000905 while (wndPtr->child) /* The child removes itself from the list */
906 DestroyWindow( wndPtr->child->hwndSelf );
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000907 SendMessage16( hwnd, WM_NCDESTROY, 0, 0 );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000908
Alexandre Julliard401710d1993-09-04 10:09:32 +0000909 /* Destroy the window */
910
Alexandre Julliardaca05781994-10-17 18:12:41 +0000911 WIN_DestroyWindow( hwnd );
Alexandre Julliard401710d1993-09-04 10:09:32 +0000912 return TRUE;
913}
914
915
916/***********************************************************************
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000917 * CloseWindow (USER.43)
918 */
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000919BOOL CloseWindow(HWND hWnd)
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000920{
921 WND * wndPtr = WIN_FindWndPtr(hWnd);
Alexandre Julliard3051b641996-07-05 17:14:13 +0000922 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return TRUE;
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000923 ShowWindow(hWnd, SW_MINIMIZE);
Alexandre Julliard7e56f681996-01-31 19:02:28 +0000924 return TRUE;
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000925}
926
927
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000928/***********************************************************************
929 * OpenIcon (USER.44)
930 */
931BOOL OpenIcon(HWND hWnd)
932{
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000933 if (!IsIconic(hWnd)) return FALSE;
934 ShowWindow(hWnd, SW_SHOWNORMAL);
935 return(TRUE);
936}
937
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000938
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000939/***********************************************************************
940 * WIN_FindWindow
941 *
942 * Implementation of FindWindow() and FindWindowEx().
943 */
944static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className,
945 LPCSTR title )
946{
947 WND *pWnd;
948 CLASS *pClass = NULL;
949
950 if (child)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000951 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000952 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
953 if (parent)
954 {
955 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
956 }
957 else if (pWnd->parent != pWndDesktop) return 0;
958 pWnd = pWnd->next;
959 }
960 else
961 {
962 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
963 pWnd = pWnd->child;
964 }
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000965 if (!pWnd) return 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000966
967 /* For a child window, all siblings will have the same hInstance, */
968 /* so we can look for the class once and for all. */
969
970 if (className && (pWnd->dwStyle & WS_CHILD))
971 {
972 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000973 return 0;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000974 }
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000975
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000976 for ( ; pWnd; pWnd = pWnd->next)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000977 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000978 if (className && !(pWnd->dwStyle & WS_CHILD))
979 {
980 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance)))
981 continue; /* Skip this window */
982 }
983 if (pClass && (pWnd->class != pClass))
984 continue; /* Not the right class */
985
986 /* Now check the title */
987
988 if (!title) return pWnd->hwndSelf;
Alexandre Julliard2d93d001996-05-21 15:01:41 +0000989 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000990 }
991 return 0;
Alexandre Julliarde399fc31993-11-24 17:08:56 +0000992}
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000993
994
995
996/***********************************************************************
997 * FindWindow16 (USER.50)
998 */
Alexandre Julliardd90840e1996-06-11 16:02:08 +0000999HWND16 FindWindow16( SEGPTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001000{
1001 return FindWindowEx16( 0, 0, className, title );
1002}
1003
1004
1005/***********************************************************************
1006 * FindWindowEx16 (USER.427)
1007 */
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001008HWND16 FindWindowEx16( HWND16 parent, HWND16 child,
1009 SEGPTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001010{
1011 ATOM atom;
1012
1013 atom = className ? GlobalFindAtom16( className ) : 0;
1014 return WIN_FindWindow( parent, child, atom, title );
1015}
1016
1017
1018/***********************************************************************
1019 * FindWindow32A (USER32.197)
1020 */
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001021HWND32 FindWindow32A( LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001022{
1023 return FindWindowEx32A( 0, 0, className, title );
1024}
1025
1026
1027/***********************************************************************
1028 * FindWindowEx32A (USER32.198)
1029 */
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001030HWND32 FindWindowEx32A( HWND32 parent, HWND32 child,
1031 LPCSTR className, LPCSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001032{
1033 ATOM atom;
1034
1035 atom = className ? GlobalFindAtom32A( className ) : 0;
1036 return WIN_FindWindow( 0, 0, atom, title );
1037}
1038
1039
1040/***********************************************************************
1041 * FindWindowEx32W (USER32.199)
1042 */
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001043HWND32 FindWindowEx32W( HWND32 parent, HWND32 child,
1044 LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001045{
1046 ATOM atom;
1047 char *buffer;
1048 HWND hwnd;
1049
1050 atom = className ? GlobalFindAtom32W( className ) : 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001051 buffer = title ? STRING32_DupUniToAnsi( title ) : NULL;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001052 hwnd = WIN_FindWindow( 0, 0, atom, buffer );
Alexandre Julliard3051b641996-07-05 17:14:13 +00001053 if (buffer) free( buffer );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001054 return hwnd;
1055}
1056
1057
1058/***********************************************************************
1059 * FindWindow32W (USER32.200)
1060 */
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001061HWND32 FindWindow32W( LPCWSTR className, LPCWSTR title )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001062{
1063 return FindWindowEx32W( 0, 0, className, title );
1064}
1065
1066
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001067/**********************************************************************
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001068 * WIN_GetDesktop
1069 */
1070WND *WIN_GetDesktop(void)
1071{
1072 return pWndDesktop;
1073}
1074
1075
1076/**********************************************************************
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001077 * GetDesktopWindow (USER.286)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001078 */
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00001079HWND GetDesktopWindow(void)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001080{
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001081 return pWndDesktop->hwndSelf;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001082}
1083
1084
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001085/**********************************************************************
1086 * GetDesktopHwnd (USER.278)
1087 *
1088 * Exactly the same thing as GetDesktopWindow(), but not documented.
1089 * Don't ask me why...
1090 */
1091HWND GetDesktopHwnd(void)
1092{
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001093 return pWndDesktop->hwndSelf;
Alexandre Julliard02ed4c21996-03-02 19:34:10 +00001094}
1095
1096
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001097/*******************************************************************
1098 * EnableWindow (USER.34)
1099 */
1100BOOL EnableWindow( HWND hwnd, BOOL enable )
1101{
1102 WND *wndPtr;
1103
1104 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1105 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1106 {
1107 /* Enable window */
1108 wndPtr->dwStyle &= ~WS_DISABLED;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001109 SendMessage16( hwnd, WM_ENABLE, TRUE, 0 );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001110 return TRUE;
1111 }
1112 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1113 {
1114 /* Disable window */
1115 wndPtr->dwStyle |= WS_DISABLED;
1116 if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
1117 SetFocus( 0 ); /* A disabled window can't have the focus */
1118 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
1119 ReleaseCapture(); /* A disabled window can't capture the mouse */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001120 SendMessage16( hwnd, WM_ENABLE, FALSE, 0 );
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001121 return FALSE;
1122 }
1123 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1124}
1125
1126
1127/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001128 * IsWindowEnabled (USER.35) (USER32.348)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +00001129 */
1130BOOL IsWindowEnabled(HWND hWnd)
1131{
1132 WND * wndPtr;
1133
1134 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1135 return !(wndPtr->dwStyle & WS_DISABLED);
1136}
1137
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001138
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001139/***********************************************************************
1140 * IsWindowUnicode (USER32.349)
1141 */
1142BOOL IsWindowUnicode( HWND hwnd )
1143{
1144 WND * wndPtr;
1145
1146 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001147 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001148}
1149
1150
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001151/**********************************************************************
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001152 * GetWindowWord (USER.133) (USER32.313)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001153 */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001154WORD GetWindowWord( HWND32 hwnd, INT32 offset )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001155{
1156 WND * wndPtr = WIN_FindWndPtr( hwnd );
1157 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001158 if (offset >= 0)
1159 {
1160 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1161 {
1162 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1163 return 0;
1164 }
1165 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1166 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001167 switch(offset)
1168 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001169 case GWW_ID: return wndPtr->wIDmenu;
1170 case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
1171 case GWW_HINSTANCE: return (WORD)wndPtr->hInstance;
1172 default:
1173 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1174 return 0;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001175 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001176}
1177
1178
1179/**********************************************************************
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00001180 * WIN_GetWindowInstance
1181 */
1182HINSTANCE WIN_GetWindowInstance(HWND hwnd)
1183{
1184 WND * wndPtr = WIN_FindWndPtr( hwnd );
1185 if (!wndPtr) return (HINSTANCE)0;
1186 return wndPtr->hInstance;
1187}
1188
1189
1190/**********************************************************************
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001191 * SetWindowWord (USER.134) (USER32.523)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001192 */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001193WORD SetWindowWord( HWND32 hwnd, INT32 offset, WORD newval )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001194{
1195 WORD *ptr, retval;
1196 WND * wndPtr = WIN_FindWndPtr( hwnd );
1197 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001198 if (offset >= 0)
1199 {
1200 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1201 {
1202 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1203 return 0;
1204 }
1205 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1206 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001207 else switch(offset)
1208 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001209 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1210 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1211 default:
1212 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
Alexandre Julliardaf0bae51995-10-03 17:06:08 +00001213 return 0;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001214 }
1215 retval = *ptr;
1216 *ptr = newval;
1217 return retval;
1218}
1219
1220
1221/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001222 * WIN_GetWindowLong
1223 *
1224 * Helper function for GetWindowLong().
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001225 */
Alexandre Julliard3051b641996-07-05 17:14:13 +00001226static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001227{
Alexandre Julliard3051b641996-07-05 17:14:13 +00001228 LONG retval;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001229 WND * wndPtr = WIN_FindWndPtr( hwnd );
1230 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001231 if (offset >= 0)
1232 {
1233 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1234 {
1235 fprintf( stderr, "GetWindowLong: invalid offset %d\n", offset );
1236 return 0;
1237 }
1238 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1239 /* Special case for dialog window procedure */
1240 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1241 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1242 return retval;
1243 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001244 switch(offset)
1245 {
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001246 case GWL_USERDATA: return wndPtr->userdata;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001247 case GWL_STYLE: return wndPtr->dwStyle;
1248 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1249 case GWL_ID: return wndPtr->wIDmenu;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001250 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1251 type );
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001252 case GWL_HWNDPARENT: return wndPtr->parent ?
1253 (HWND32)wndPtr->parent->hwndSelf : 0;
1254 case GWL_HINSTANCE: return (HINSTANCE32)wndPtr->hInstance;
1255 default:
Alexandre Julliard3051b641996-07-05 17:14:13 +00001256 fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001257 }
1258 return 0;
1259}
1260
1261
1262/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001263 * WIN_SetWindowLong
1264 *
1265 * Helper function for SetWindowLong().
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001266 */
Alexandre Julliard3051b641996-07-05 17:14:13 +00001267static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1268 WINDOWPROCTYPE type )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001269{
1270 LONG *ptr, retval;
1271 WND * wndPtr = WIN_FindWndPtr( hwnd );
1272 if (!wndPtr) return 0;
Alexandre Julliard3051b641996-07-05 17:14:13 +00001273 if (offset >= 0)
1274 {
1275 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1276 {
1277 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1278 return 0;
1279 }
1280 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1281 /* Special case for dialog window procedure */
1282 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1283 {
1284 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1285 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval, type );
1286 return retval;
1287 }
1288 }
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001289 else switch(offset)
1290 {
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001291 case GWL_ID:
1292 case GWL_HINSTANCE:
1293 return SetWindowWord( hwnd, offset, (WORD)newval );
1294 case GWL_WNDPROC:
Alexandre Julliard3051b641996-07-05 17:14:13 +00001295 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1296 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval, type );
1297 return retval;
Alexandre Julliard1e9ac791996-06-06 18:38:27 +00001298 case GWL_USERDATA: ptr = &wndPtr->userdata; break;
1299 case GWL_STYLE: ptr = &wndPtr->dwStyle; break;
1300 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001301 default:
1302 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1303 return 0;
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001304 }
1305 retval = *ptr;
1306 *ptr = newval;
1307 return retval;
1308}
1309
1310
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001311/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001312 * GetWindowLong16 (USER.135)
1313 */
1314LONG GetWindowLong16( HWND16 hwnd, INT16 offset )
1315{
1316 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1317}
1318
1319
1320/**********************************************************************
1321 * GetWindowLong32A (USER32.304)
1322 */
1323LONG GetWindowLong32A( HWND32 hwnd, INT32 offset )
1324{
1325 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1326}
1327
1328
1329/**********************************************************************
1330 * GetWindowLong32W (USER32.305)
1331 */
1332LONG GetWindowLong32W( HWND32 hwnd, INT32 offset )
1333{
1334 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1335}
1336
1337
1338/**********************************************************************
1339 * SetWindowLong16 (USER.136)
1340 */
1341LONG SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1342{
1343 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1344}
1345
1346
1347/**********************************************************************
1348 * SetWindowLong32A (USER32.516)
1349 */
1350LONG SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1351{
1352 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1353}
1354
1355
1356/**********************************************************************
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001357 * SetWindowLong32W (USER32.517)
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001358 */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001359LONG SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001360{
Alexandre Julliard3051b641996-07-05 17:14:13 +00001361 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001362}
1363
1364
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001365/*******************************************************************
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001366 * GetWindowText16 (USER.36)
Alexandre Julliard0e607781993-11-03 19:23:37 +00001367 */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001368INT16 GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
Alexandre Julliard0e607781993-11-03 19:23:37 +00001369{
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001370 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
Alexandre Julliard0e607781993-11-03 19:23:37 +00001371}
1372
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001373
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001374/*******************************************************************
1375 * GetWindowText32A (USER32.308)
1376 */
1377INT32 GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1378{
1379 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1380 (LPARAM)lpString );
1381}
1382
1383
1384/*******************************************************************
1385 * GetWindowText32W (USER32.311)
1386 */
1387INT32 GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1388{
1389 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1390 (LPARAM)lpString );
1391}
1392
1393
1394/*******************************************************************
1395 * SetWindowText16 (USER.37)
1396 */
1397void SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1398{
1399 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1400}
1401
1402
1403/*******************************************************************
1404 * SetWindowText32A (USER32.)
1405 */
1406void SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1407{
1408 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1409}
1410
1411
1412/*******************************************************************
1413 * SetWindowText32W (USER32.)
1414 */
1415void SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1416{
1417 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00001418}
1419
1420
Alexandre Julliard0e607781993-11-03 19:23:37 +00001421/*******************************************************************
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001422 * GetWindowTextLength (USER.38)
1423 */
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001424int GetWindowTextLength(HWND hwnd)
1425{
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001426 return (int)SendMessage16(hwnd, WM_GETTEXTLENGTH, 0, 0 );
Alexandre Julliardf0b23541993-09-29 12:21:49 +00001427}
1428
1429
Alexandre Julliard0e607781993-11-03 19:23:37 +00001430/*******************************************************************
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001431 * IsWindow (USER.47)
1432 */
1433BOOL IsWindow( HWND hwnd )
1434{
1435 WND * wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001436 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001437}
1438
1439
1440/*****************************************************************
1441 * GetParent (USER.46)
1442 */
1443HWND GetParent(HWND hwnd)
1444{
1445 WND *wndPtr = WIN_FindWndPtr(hwnd);
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001446 if (!wndPtr) return 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001447 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1448 return wndPtr ? wndPtr->hwndSelf : 0;
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001449}
1450
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001451
1452/*****************************************************************
1453 * WIN_GetTopParent
1454 *
1455 * Get the top-level parent for a child window.
1456 */
1457HWND WIN_GetTopParent( HWND hwnd )
1458{
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001459 WND *wndPtr = WIN_FindWndPtr( hwnd );
1460 while (wndPtr && (wndPtr->dwStyle & WS_CHILD)) wndPtr = wndPtr->parent;
1461 return wndPtr ? wndPtr->hwndSelf : 0;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001462}
1463
1464
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001465/*****************************************************************
1466 * SetParent (USER.233)
1467 */
1468HWND SetParent(HWND hwndChild, HWND hwndNewParent)
1469{
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001470 HWND oldParent;
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001471
1472 WND *wndPtr = WIN_FindWndPtr(hwndChild);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001473 WND *pWndParent = WIN_FindWndPtr( hwndNewParent );
1474 if (!wndPtr || !pWndParent || !(wndPtr->dwStyle & WS_CHILD)) return 0;
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001475
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001476 oldParent = wndPtr->parent->hwndSelf;
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001477
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +00001478 WIN_UnlinkWindow(hwndChild);
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001479 if (hwndNewParent) wndPtr->parent = pWndParent;
Alexandre Julliardbd34d4f1995-06-20 19:08:12 +00001480 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
1481
1482 if (IsWindowVisible(hwndChild)) UpdateWindow(hwndChild);
1483
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001484 return oldParent;
Alexandre Julliard940d58c1994-09-16 09:24:37 +00001485}
1486
1487
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001488
1489/*******************************************************************
Alexandre Julliard0e607781993-11-03 19:23:37 +00001490 * IsChild (USER.48)
1491 */
1492BOOL IsChild( HWND parent, HWND child )
1493{
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001494 WND * wndPtr = WIN_FindWndPtr( child );
1495 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
Alexandre Julliard0e607781993-11-03 19:23:37 +00001496 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001497 wndPtr = wndPtr->parent;
1498 if (wndPtr->hwndSelf == parent) return TRUE;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001499 }
Alexandre Julliard0e607781993-11-03 19:23:37 +00001500 return FALSE;
1501}
1502
1503
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001504/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001505 * IsWindowVisible (USER.49) (USER32.350)
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001506 */
Alexandre Julliardded30381995-07-06 17:18:27 +00001507BOOL IsWindowVisible( HWND hwnd )
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001508{
Alexandre Julliardded30381995-07-06 17:18:27 +00001509 WND *wndPtr = WIN_FindWndPtr( hwnd );
1510 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1511 {
1512 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001513 wndPtr = wndPtr->parent;
Alexandre Julliardded30381995-07-06 17:18:27 +00001514 }
1515 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
Alexandre Julliarde399fc31993-11-24 17:08:56 +00001516}
1517
1518
1519
Alexandre Julliard0e607781993-11-03 19:23:37 +00001520/*******************************************************************
1521 * GetTopWindow (USER.229)
1522 */
1523HWND GetTopWindow( HWND hwnd )
1524{
1525 WND * wndPtr = WIN_FindWndPtr( hwnd );
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001526 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
Alexandre Julliard0e607781993-11-03 19:23:37 +00001527 else return 0;
1528}
1529
1530
1531/*******************************************************************
1532 * GetWindow (USER.262)
1533 */
1534HWND GetWindow( HWND hwnd, WORD rel )
1535{
1536 WND * wndPtr = WIN_FindWndPtr( hwnd );
1537 if (!wndPtr) return 0;
1538 switch(rel)
1539 {
1540 case GW_HWNDFIRST:
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001541 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
Alexandre Julliardfb9a9191994-03-01 19:48:04 +00001542 else return 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +00001543
1544 case GW_HWNDLAST:
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001545 if (!wndPtr->parent) return 0; /* Desktop window */
1546 while (wndPtr->next) wndPtr = wndPtr->next;
1547 return wndPtr->hwndSelf;
Alexandre Julliard0e607781993-11-03 19:23:37 +00001548
1549 case GW_HWNDNEXT:
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001550 if (!wndPtr->next) return 0;
1551 return wndPtr->next->hwndSelf;
Alexandre Julliard0e607781993-11-03 19:23:37 +00001552
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001553 case GW_HWNDPREV:
1554 if (!wndPtr->parent) return 0; /* Desktop window */
1555 wndPtr = wndPtr->parent->child; /* First sibling */
1556 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
1557 while (wndPtr->next)
1558 {
1559 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
1560 wndPtr = wndPtr->next;
1561 }
1562 return 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +00001563
1564 case GW_OWNER:
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001565 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +00001566
1567 case GW_CHILD:
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001568 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
Alexandre Julliard0e607781993-11-03 19:23:37 +00001569 }
1570 return 0;
1571}
1572
1573
1574/*******************************************************************
1575 * GetNextWindow (USER.230)
1576 */
1577HWND GetNextWindow( HWND hwnd, WORD flag )
1578{
1579 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1580 return GetWindow( hwnd, flag );
1581}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001582
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001583/*******************************************************************
1584 * ShowOwnedPopups (USER.265)
1585 */
1586void ShowOwnedPopups( HWND owner, BOOL fShow )
1587{
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001588 WND *pWnd = pWndDesktop->child;
1589 while (pWnd)
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001590 {
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001591 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
1592 (pWnd->dwStyle & WS_POPUP))
1593 ShowWindow( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
1594 pWnd = pWnd->next;
Alexandre Julliarde2991ea1995-07-29 13:09:43 +00001595 }
1596}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001597
1598
Alexandre Julliard3a405ba1994-10-30 16:25:19 +00001599/*******************************************************************
1600 * GetLastActivePopup (USER.287)
1601 */
1602HWND GetLastActivePopup(HWND hwnd)
1603{
1604 WND *wndPtr;
1605 wndPtr = WIN_FindWndPtr(hwnd);
1606 if (wndPtr == NULL) return hwnd;
1607 return wndPtr->hwndLastActive;
1608}
1609
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001610
1611/*******************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001612 * WIN_BuildWinArray
1613 *
1614 * Build an array of pointers to all children of a given window.
1615 * The array must be freed with HeapFree(SystemHeap).
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001616 */
Alexandre Julliard3051b641996-07-05 17:14:13 +00001617WND **WIN_BuildWinArray( WND *wndPtr )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001618{
Alexandre Julliard3051b641996-07-05 17:14:13 +00001619 WND **list, **ppWnd;
1620 WND *pWnd;
1621 INT32 count;
1622
1623 /* First count the windows */
1624
1625 if (!wndPtr) wndPtr = pWndDesktop;
1626 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next) count++;
1627 count++; /* For the terminating NULL */
1628
1629 /* Now build the list of all windows */
1630
1631 if (!(list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * count )))
1632 return NULL;
1633 for (pWnd = wndPtr->child, ppWnd = list; pWnd; pWnd = pWnd->next)
1634 *ppWnd++ = pWnd;
1635 *ppWnd = NULL;
1636 return list;
1637}
1638
1639
1640/*******************************************************************
1641 * EnumWindows16 (USER.54)
1642 */
1643BOOL16 EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
1644{
1645 WND **list, **ppWnd;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001646
Alexandre Julliard594997c1995-04-30 10:05:20 +00001647 /* We have to build a list of all windows first, to avoid */
1648 /* unpleasant side-effects, for instance if the callback */
1649 /* function changes the Z-order of the windows. */
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001650
Alexandre Julliard3051b641996-07-05 17:14:13 +00001651 if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
Alexandre Julliard594997c1995-04-30 10:05:20 +00001652
Alexandre Julliard3051b641996-07-05 17:14:13 +00001653 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00001654
Alexandre Julliard3051b641996-07-05 17:14:13 +00001655 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00001656 {
Alexandre Julliard3051b641996-07-05 17:14:13 +00001657 /* Make sure that the window still exists */
1658 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
1659 if (!CallEnumWindowsProc16( lpEnumFunc, (*ppWnd)->hwndSelf, lParam ))
1660 break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00001661 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00001662 HeapFree( SystemHeap, 0, list );
1663 return TRUE;
1664}
1665
1666
1667/*******************************************************************
1668 * EnumWindows32 (USER32.192)
1669 */
1670BOOL32 EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
1671{
1672 WND **list, **ppWnd;
1673
1674 /* We have to build a list of all windows first, to avoid */
1675 /* unpleasant side-effects, for instance if the callback */
1676 /* function changes the Z-order of the windows. */
1677
1678 if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
1679
1680 /* Now call the callback function for every window */
1681
1682 for (ppWnd = list; *ppWnd; ppWnd++)
1683 {
1684 /* Make sure that the window still exists */
1685 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
1686 if (!CallEnumWindowsProc32( lpEnumFunc, (*ppWnd)->hwndSelf, lParam ))
1687 break;
1688 }
1689 HeapFree( SystemHeap, 0, list );
Alexandre Julliard594997c1995-04-30 10:05:20 +00001690 return TRUE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001691}
1692
Alexandre Julliard594997c1995-04-30 10:05:20 +00001693
1694/**********************************************************************
Alexandre Julliard3051b641996-07-05 17:14:13 +00001695 * EnumTaskWindows16 (USER.225)
Alexandre Julliard594997c1995-04-30 10:05:20 +00001696 */
Alexandre Julliard3051b641996-07-05 17:14:13 +00001697BOOL16 EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func, LPARAM lParam )
Alexandre Julliard594997c1995-04-30 10:05:20 +00001698{
Alexandre Julliard3051b641996-07-05 17:14:13 +00001699 WND **list, **ppWnd;
Alexandre Julliard594997c1995-04-30 10:05:20 +00001700 HANDLE hQueue = GetTaskQueue( hTask );
Alexandre Julliard594997c1995-04-30 10:05:20 +00001701
1702 /* This function is the same as EnumWindows(), */
1703 /* except for an added check on the window queue. */
1704
Alexandre Julliard3051b641996-07-05 17:14:13 +00001705 if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
Alexandre Julliard594997c1995-04-30 10:05:20 +00001706
Alexandre Julliard3051b641996-07-05 17:14:13 +00001707 /* Now call the callback function for every window */
Alexandre Julliard594997c1995-04-30 10:05:20 +00001708
Alexandre Julliard3051b641996-07-05 17:14:13 +00001709 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliard594997c1995-04-30 10:05:20 +00001710 {
Alexandre Julliard3051b641996-07-05 17:14:13 +00001711 /* Make sure that the window still exists */
1712 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
1713 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
1714 if (!CallEnumWindowsProc16( func, (*ppWnd)->hwndSelf, lParam ))
1715 break;
Alexandre Julliard594997c1995-04-30 10:05:20 +00001716 }
Alexandre Julliard3051b641996-07-05 17:14:13 +00001717 HeapFree( SystemHeap, 0, list );
Alexandre Julliard594997c1995-04-30 10:05:20 +00001718 return TRUE;
1719}
1720
1721
Alexandre Julliard3051b641996-07-05 17:14:13 +00001722/**********************************************************************
1723 * EnumThreadWindows (USER32.189)
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001724 */
Alexandre Julliard3051b641996-07-05 17:14:13 +00001725BOOL32 EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001726{
Alexandre Julliard3051b641996-07-05 17:14:13 +00001727 WND **list, **ppWnd;
1728 HANDLE hQueue = GetTaskQueue( (DWORD)id );
1729
1730 if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
1731
1732 /* Now call the callback function for every window */
1733
1734 for (ppWnd = list; *ppWnd; ppWnd++)
Alexandre Julliardfa68b751995-04-03 16:55:37 +00001735 {
Alexandre Julliard3051b641996-07-05 17:14:13 +00001736 /* Make sure that the window still exists */
1737 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
1738 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
1739 if (!CallEnumWindowsProc32( func, (*ppWnd)->hwndSelf, lParam ))
1740 break;
1741 }
1742 HeapFree( SystemHeap, 0, list );
1743 return TRUE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001744}
1745
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001746
Alexandre Julliard3051b641996-07-05 17:14:13 +00001747/**********************************************************************
1748 * WIN_EnumChildWindows16
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001749 *
Alexandre Julliard3051b641996-07-05 17:14:13 +00001750 * Helper function for EnumChildWindows16().
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001751 */
Alexandre Julliard3051b641996-07-05 17:14:13 +00001752static BOOL16 WIN_EnumChildWindows16( WND **ppWnd, WNDENUMPROC16 func,
1753 LPARAM lParam )
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001754{
Alexandre Julliard3051b641996-07-05 17:14:13 +00001755 WND **childList;
1756 BOOL16 ret = FALSE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001757
Alexandre Julliard3051b641996-07-05 17:14:13 +00001758 while (*ppWnd)
1759 {
1760 /* Make sure that the window still exists */
1761 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
1762 /* Build children list first */
1763 if (!(childList = WIN_BuildWinArray( *ppWnd ))) return FALSE;
1764 if (!CallEnumWindowsProc16( func, (*ppWnd)->hwndSelf, lParam ))
1765 return FALSE;
1766 ret = WIN_EnumChildWindows16( childList, func, lParam );
1767 HeapFree( SystemHeap, 0, childList );
1768 if (!ret) return FALSE;
1769 ppWnd++;
1770 }
1771 return TRUE;
1772}
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001773
Alexandre Julliard3051b641996-07-05 17:14:13 +00001774
1775/**********************************************************************
1776 * WIN_EnumChildWindows32
1777 *
1778 * Helper function for EnumChildWindows32().
1779 */
1780static BOOL32 WIN_EnumChildWindows32( WND **ppWnd, WNDENUMPROC32 func,
1781 LPARAM lParam )
1782{
1783 WND **childList;
1784 BOOL32 ret = FALSE;
1785
1786 while (*ppWnd)
1787 {
1788 /* Make sure that the window still exists */
1789 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
1790 /* Build children list first */
1791 if (!(childList = WIN_BuildWinArray( *ppWnd ))) return FALSE;
1792 if (!CallEnumWindowsProc32( func, (*ppWnd)->hwndSelf, lParam ))
1793 return FALSE;
1794 ret = WIN_EnumChildWindows32( childList, func, lParam );
1795 HeapFree( SystemHeap, 0, childList );
1796 if (!ret) return FALSE;
1797 ppWnd++;
1798 }
1799 return TRUE;
1800}
1801
1802
1803/**********************************************************************
1804 * EnumChildWindows16 (USER.55)
1805 */
1806BOOL16 EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func, LPARAM lParam )
1807{
1808 WND **list, *pParent;
1809
1810 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
1811 if (!(list = WIN_BuildWinArray( pParent ))) return FALSE;
1812 WIN_EnumChildWindows16( list, func, lParam );
1813 HeapFree( SystemHeap, 0, list );
1814 return TRUE;
1815}
1816
1817
1818/**********************************************************************
1819 * EnumChildWindows32 (USER32.177)
1820 */
1821BOOL32 EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func, LPARAM lParam )
1822{
1823 WND **list, *pParent;
1824
1825 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
1826 if (!(list = WIN_BuildWinArray( pParent ))) return FALSE;
1827 WIN_EnumChildWindows32( list, func, lParam );
1828 HeapFree( SystemHeap, 0, list );
1829 return TRUE;
Alexandre Julliarddba420a1994-02-02 06:48:31 +00001830}
1831
Alexandre Julliard594997c1995-04-30 10:05:20 +00001832
Alexandre Julliard58199531994-04-21 01:20:00 +00001833/*******************************************************************
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001834 * AnyPopup (USER.52)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00001835 */
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001836BOOL AnyPopup(void)
Alexandre Julliardd18872d1994-05-11 12:18:19 +00001837{
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001838 WND *wndPtr;
1839 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
1840 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
1841 return FALSE;
Alexandre Julliardd18872d1994-05-11 12:18:19 +00001842}
1843
Alexandre Julliard73450d61994-05-18 18:29:32 +00001844/*******************************************************************
1845 * FlashWindow [USER.105]
1846 */
1847BOOL FlashWindow(HWND hWnd, BOOL bInvert)
1848{
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00001849 WND *wndPtr = WIN_FindWndPtr(hWnd);
1850
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001851 dprintf_win(stddeb,"FlashWindow: %04x\n", hWnd);
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00001852
1853 if (!wndPtr) return FALSE;
1854
1855 if (wndPtr->dwStyle & WS_MINIMIZE)
1856 {
1857 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
1858 {
1859 HDC hDC = GetDC(hWnd);
1860
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001861 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM)hDC, (LPARAM)0 ))
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00001862 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
1863
1864 ReleaseDC( hWnd, hDC );
1865 wndPtr->flags |= WIN_NCACTIVATED;
1866 }
1867 else
1868 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001869 RedrawWindow32( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
1870 RDW_UPDATENOW | RDW_FRAME );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00001871 wndPtr->flags &= ~WIN_NCACTIVATED;
1872 }
1873 return TRUE;
1874 }
1875 else
1876 {
1877 WPARAM wparam;
1878 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
1879 else wparam = (hWnd == GetActiveWindow());
1880
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001881 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
Alexandre Julliard7d654eb1996-02-25 11:36:22 +00001882 return wparam;
1883 }
Alexandre Julliard73450d61994-05-18 18:29:32 +00001884}
1885
Alexandre Julliardd18872d1994-05-11 12:18:19 +00001886
1887/*******************************************************************
Alexandre Julliard58199531994-04-21 01:20:00 +00001888 * SetSysModalWindow [USER.188]
1889 */
1890HWND SetSysModalWindow(HWND hWnd)
1891{
Alexandre Julliardd4719651995-12-12 18:49:11 +00001892 HWND hWndOldModal = hwndSysModal;
1893 hwndSysModal = hWnd;
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001894 dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
Alexandre Julliardd4719651995-12-12 18:49:11 +00001895 return hWndOldModal;
Alexandre Julliard58199531994-04-21 01:20:00 +00001896}
1897
Alexandre Julliardd18872d1994-05-11 12:18:19 +00001898
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00001899/*******************************************************************
1900 * GetSysModalWindow [USER.189]
1901 */
1902HWND GetSysModalWindow(void)
1903{
Alexandre Julliardd4719651995-12-12 18:49:11 +00001904 return hwndSysModal;
Alexandre Julliard1d62f6b1994-05-04 19:15:00 +00001905}
Alexandre Julliardade697e1995-11-26 13:59:11 +00001906
1907/*******************************************************************
1908 * DRAG_QueryUpdate
1909 *
1910 * recursively find a child that contains spDragInfo->pt point
1911 * and send WM_QUERYDROPOBJECT
1912 */
1913BOOL DRAG_QueryUpdate( HWND hQueryWnd, SEGPTR spDragInfo )
1914{
Alexandre Julliardade697e1995-11-26 13:59:11 +00001915 BOOL wParam,bResult = 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001916 POINT16 pt;
Alexandre Julliardade697e1995-11-26 13:59:11 +00001917 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
1918 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001919 RECT16 tempRect; /* this sucks */
Alexandre Julliardade697e1995-11-26 13:59:11 +00001920
1921 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
1922
1923 pt = ptrDragInfo->pt;
1924
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001925 GetWindowRect16(hQueryWnd,&tempRect);
Alexandre Julliardade697e1995-11-26 13:59:11 +00001926
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001927 if( !PtInRect16(&tempRect,pt) ||
Alexandre Julliardade697e1995-11-26 13:59:11 +00001928 (ptrQueryWnd->dwStyle & WS_DISABLED) )
1929 return 0;
1930
1931 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
1932 {
1933 tempRect = ptrQueryWnd->rectClient;
1934 if(ptrQueryWnd->dwStyle & WS_CHILD)
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001935 MapWindowPoints16(ptrQueryWnd->parent->hwndSelf,0,(LPPOINT16)&tempRect,2);
Alexandre Julliardade697e1995-11-26 13:59:11 +00001936
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001937 if( PtInRect16(&tempRect,pt) )
Alexandre Julliardade697e1995-11-26 13:59:11 +00001938 {
1939 wParam = 0;
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001940
1941 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
1942 if( ptrWnd->dwStyle & WS_VISIBLE )
Alexandre Julliardade697e1995-11-26 13:59:11 +00001943 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001944 GetWindowRect16(ptrWnd->hwndSelf,&tempRect);
Alexandre Julliardade697e1995-11-26 13:59:11 +00001945
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001946 if( PtInRect16(&tempRect,pt) )
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001947 break;
Alexandre Julliardade697e1995-11-26 13:59:11 +00001948 }
1949
1950 if(ptrWnd)
Alexandre Julliard59730ae1996-03-24 16:20:51 +00001951 {
1952 dprintf_msg(stddeb,"DragQueryUpdate: hwnd = %04x, %d %d - %d %d\n",
1953 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
1954 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
1955 if( !(ptrWnd->dwStyle & WS_DISABLED) )
1956 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo);
1957 }
Alexandre Julliardade697e1995-11-26 13:59:11 +00001958
1959 if(bResult) return bResult;
1960 }
1961 else wParam = 1;
1962 }
1963 else wParam = 1;
1964
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001965 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
Alexandre Julliardade697e1995-11-26 13:59:11 +00001966
1967 ptrDragInfo->hScope = hQueryWnd;
1968
Alexandre Julliard2d93d001996-05-21 15:01:41 +00001969 bResult = SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
Alexandre Julliardade697e1995-11-26 13:59:11 +00001970 (WPARAM)wParam ,(LPARAM) spDragInfo );
1971 if( !bResult )
1972 ptrDragInfo->pt = pt;
1973
1974 return bResult;
1975}
1976
1977/*******************************************************************
1978 * DragDetect ( USER.465 )
1979 *
1980 */
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001981BOOL16 DragDetect(HWND16 hWnd, POINT16 pt)
Alexandre Julliardade697e1995-11-26 13:59:11 +00001982{
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001983 MSG16 msg;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00001984 RECT16 rect;
Alexandre Julliardade697e1995-11-26 13:59:11 +00001985
1986 rect.left = pt.x - wDragWidth;
1987 rect.right = pt.x + wDragWidth;
1988
1989 rect.top = pt.y - wDragHeight;
1990 rect.bottom = pt.y + wDragHeight;
1991
1992 SetCapture(hWnd);
1993
1994 while(1)
1995 {
Alexandre Julliardd90840e1996-06-11 16:02:08 +00001996 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
Alexandre Julliardade697e1995-11-26 13:59:11 +00001997 {
1998 if( msg.message == WM_LBUTTONUP )
1999 {
2000 ReleaseCapture();
2001 return 0;
2002 }
2003 if( msg.message == WM_MOUSEMOVE )
2004 {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +00002005 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
Alexandre Julliardade697e1995-11-26 13:59:11 +00002006 {
2007 ReleaseCapture();
2008 return 1;
2009 }
2010 }
2011 }
2012 WaitMessage();
2013 }
2014
2015 return 0;
2016}
2017
2018/******************************************************************************
2019 * DragObject ( USER.464 )
2020 *
2021 */
2022DWORD DragObject(HWND hwndScope, HWND hWnd, WORD wObj, HANDLE hOfStruct,
2023 WORD szList , HCURSOR hCursor)
2024{
Alexandre Julliardd90840e1996-06-11 16:02:08 +00002025 MSG16 msg;
Alexandre Julliardade697e1995-11-26 13:59:11 +00002026 LPDRAGINFO lpDragInfo;
2027 SEGPTR spDragInfo;
2028 HCURSOR hDragCursor=0, hOldCursor=0, hBummer=0;
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00002029 HANDLE hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
Alexandre Julliardade697e1995-11-26 13:59:11 +00002030 WND *wndPtr = WIN_FindWndPtr(hWnd);
2031 DWORD dwRet = 0;
2032 short dragDone = 0;
2033 HCURSOR hCurrentCursor = 0;
2034 HWND hCurrentWnd = 0;
2035 WORD btemp;
2036
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00002037 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2038 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00002039
2040 if( !lpDragInfo || !spDragInfo ) return 0L;
2041
2042 hBummer = LoadCursor(0,IDC_BUMMER);
2043
2044 if( !hBummer || !wndPtr )
2045 {
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00002046 GlobalFree16(hDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00002047 return 0L;
2048 }
2049
2050 if(hCursor)
2051 {
2052 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor)) )
2053 {
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00002054 GlobalFree16(hDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00002055 return 0L;
2056 }
2057
2058 if( hDragCursor == hCursor ) hDragCursor = 0;
2059 else hCursor = hDragCursor;
2060
2061 hOldCursor = SetCursor(hDragCursor);
2062 }
2063
2064 lpDragInfo->hWnd = hWnd;
2065 lpDragInfo->hScope = 0;
2066 lpDragInfo->wFlags = wObj;
2067 lpDragInfo->hList = szList; /* near pointer! */
2068 lpDragInfo->hOfStruct = hOfStruct;
2069 lpDragInfo->l = 0L;
2070
2071 SetCapture(hWnd);
2072 ShowCursor(1);
2073
2074 while( !dragDone )
2075 {
2076 WaitMessage();
2077
Alexandre Julliardd90840e1996-06-11 16:02:08 +00002078 if( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) )
Alexandre Julliardade697e1995-11-26 13:59:11 +00002079 continue;
2080
2081 *(lpDragInfo+1) = *lpDragInfo;
2082
2083 lpDragInfo->pt = msg.pt;
2084
2085 /* update DRAGINFO struct */
Alexandre Julliard59730ae1996-03-24 16:20:51 +00002086 dprintf_msg(stddeb,"drag: lpDI->hScope = %04x\n",lpDragInfo->hScope);
Alexandre Julliardade697e1995-11-26 13:59:11 +00002087
2088 if( (btemp = (WORD)DRAG_QueryUpdate(hwndScope, spDragInfo)) > 0 )
2089 hCurrentCursor = hCursor;
2090 else
2091 {
2092 hCurrentCursor = hBummer;
2093 lpDragInfo->hScope = 0;
2094 }
2095 if( hCurrentCursor )
2096 SetCursor(hCurrentCursor);
2097
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +00002098 dprintf_msg(stddeb,"drag: got %04x\n",btemp);
Alexandre Julliardade697e1995-11-26 13:59:11 +00002099
2100 /* send WM_DRAGLOOP */
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002101 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM)(hCurrentCursor != hBummer) ,
Alexandre Julliardade697e1995-11-26 13:59:11 +00002102 (LPARAM) spDragInfo );
2103 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2104 if( hCurrentWnd != lpDragInfo->hScope )
2105 {
2106 if( hCurrentWnd )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002107 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
Alexandre Julliardade697e1995-11-26 13:59:11 +00002108 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2109 HIWORD(spDragInfo)) );
2110 hCurrentWnd = lpDragInfo->hScope;
2111 if( hCurrentWnd )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002112 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00002113 }
2114 else
2115 if( hCurrentWnd )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002116 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00002117
2118
2119 /* check if we're done */
2120 if( msg.message == WM_LBUTTONUP || msg.message == WM_NCLBUTTONUP )
2121 dragDone = TRUE;
2122 }
2123
2124 ReleaseCapture();
2125 ShowCursor(0);
2126
2127 if( hCursor )
2128 {
2129 SetCursor(hOldCursor);
2130 if( hDragCursor )
2131 DestroyCursor(hDragCursor);
2132 }
2133
2134 if( hCurrentCursor != hBummer )
Alexandre Julliard2d93d001996-05-21 15:01:41 +00002135 dwRet = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
Alexandre Julliardd7d4fdf1995-12-26 15:05:24 +00002136 (WPARAM)hWnd, (LPARAM)spDragInfo );
Alexandre Julliard1285c2f1996-05-06 16:06:24 +00002137 GlobalFree16(hDragInfo);
Alexandre Julliardade697e1995-11-26 13:59:11 +00002138
2139 return dwRet;
2140}
2141