Release 980315
[wine/multimedia.git] / windows / win.c
blobe0412db37f816a45ccea59ce53c4c5d863d416d4
1 /*
2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <X11/Xatom.h>
12 #include "options.h"
13 #include "class.h"
14 #include "win.h"
15 #include "heap.h"
16 #include "user.h"
17 #include "dce.h"
18 #include "sysmetrics.h"
19 #include "cursoricon.h"
20 #include "heap.h"
21 #include "hook.h"
22 #include "menu.h"
23 #include "message.h"
24 #include "nonclient.h"
25 #include "queue.h"
26 #include "winpos.h"
27 #include "color.h"
28 #include "shm_main_blk.h"
29 #include "dde_proc.h"
30 #include "clipboard.h"
31 #include "winproc.h"
32 #include "thread.h"
33 #include "debug.h"
34 #include "debugstr.h"
36 /* Desktop window */
37 static WND *pWndDesktop = NULL;
39 static HWND32 hwndSysModal = 0;
41 static WORD wDragWidth = 4;
42 static WORD wDragHeight= 3;
44 extern BOOL32 ICONTITLE_Init(void);
45 extern BOOL32 MENU_PatchResidentPopup( HQUEUE16, WND* );
46 extern HWND32 CARET_GetHwnd(void);
47 extern BOOL32 EVENT_CheckFocus(void);
49 /***********************************************************************
50 * WIN_FindWndPtr
52 * Return a pointer to the WND structure corresponding to a HWND.
54 WND * WIN_FindWndPtr( HWND32 hwnd )
56 WND * ptr;
58 if (!hwnd || HIWORD(hwnd)) return NULL;
59 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
60 if (ptr->dwMagic != WND_MAGIC) return NULL;
61 if (ptr->hwndSelf != hwnd)
63 fprintf( stderr, "Can't happen: hwnd %04x self pointer is %04x\n",
64 hwnd, ptr->hwndSelf );
65 return NULL;
67 return ptr;
71 /***********************************************************************
72 * WIN_DumpWindow
74 * Dump the content of a window structure to stderr.
76 void WIN_DumpWindow( HWND32 hwnd )
78 WND *ptr;
79 char className[80];
80 int i;
82 if (!(ptr = WIN_FindWndPtr( hwnd )))
84 fprintf( stderr, "%04x is not a window handle\n", hwnd );
85 return;
88 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
89 strcpy( className, "#NULL#" );
91 fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
92 fprintf( stderr,
93 "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
94 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
95 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
96 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
97 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
98 ptr->next, ptr->child, ptr->parent, ptr->owner,
99 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
100 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
101 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
102 ptr->text ? ptr->text : "",
103 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->hSysMenu,
106 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
108 if (ptr->class->cbWndExtra)
110 fprintf( stderr, "extra bytes:" );
111 for (i = 0; i < ptr->class->cbWndExtra; i++)
112 fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
113 fprintf( stderr, "\n" );
115 fprintf( stderr, "\n" );
119 /***********************************************************************
120 * WIN_WalkWindows
122 * Walk the windows tree and print each window on stderr.
124 void WIN_WalkWindows( HWND32 hwnd, int indent )
126 WND *ptr;
127 char className[80];
129 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
130 if (!ptr)
132 fprintf( stderr, "*** Invalid window handle %04x\n", hwnd );
133 return;
136 if (!indent) /* first time around */
137 fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
138 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
140 while (ptr)
142 fprintf(stderr, "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
144 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
146 fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %08x\n",
147 (DWORD)ptr, ptr->hmemTaskQ, className,
148 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc );
150 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
151 ptr = ptr->next;
156 /***********************************************************************
157 * WIN_GetXWindow
159 * Return the X window associated to a window.
161 Window WIN_GetXWindow( HWND32 hwnd )
163 WND *wndPtr = WIN_FindWndPtr( hwnd );
164 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
165 return wndPtr ? wndPtr->window : 0;
169 /***********************************************************************
170 * WIN_UnlinkWindow
172 * Remove a window from the siblings linked list.
174 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
176 WND *wndPtr, **ppWnd;
178 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
179 ppWnd = &wndPtr->parent->child;
180 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
181 *ppWnd = wndPtr->next;
182 return TRUE;
186 /***********************************************************************
187 * WIN_LinkWindow
189 * Insert a window into the siblings linked list.
190 * The window is inserted after the specified window, which can also
191 * be specified as HWND_TOP or HWND_BOTTOM.
193 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
195 WND *wndPtr, **ppWnd;
197 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
199 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
201 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
202 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
203 while (*ppWnd) ppWnd = &(*ppWnd)->next;
205 else /* Normal case */
207 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
208 if (!afterPtr) return FALSE;
209 ppWnd = &afterPtr->next;
211 wndPtr->next = *ppWnd;
212 *ppWnd = wndPtr;
213 return TRUE;
217 /***********************************************************************
218 * WIN_FindWinToRepaint
220 * Find a window that needs repaint.
222 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
224 HWND32 hwndRet;
225 WND *pWnd = pWndDesktop;
227 /* Note: the desktop window never gets WM_PAINT messages
228 * The real reason why is because Windows DesktopWndProc
229 * does ValidateRgn inside WM_ERASEBKGND handler.
232 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
234 for ( ; pWnd ; pWnd = pWnd->next )
236 if (!(pWnd->dwStyle & WS_VISIBLE))
238 TRACE(win, "skipping window %04x\n",
239 pWnd->hwndSelf );
240 continue;
242 if ((pWnd->hmemTaskQ == hQueue) &&
243 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
245 if (pWnd->child )
246 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
247 return hwndRet;
250 if (!pWnd) return 0;
252 hwndRet = pWnd->hwndSelf;
254 /* look among siblings if we got a transparent window */
255 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
256 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
258 pWnd = pWnd->next;
260 if (pWnd) hwndRet = pWnd->hwndSelf;
261 TRACE(win,"found %04x\n",hwndRet);
262 return hwndRet;
266 /***********************************************************************
267 * WIN_DestroyWindow
269 * Destroy storage associated to a window. "Internals" p.358
271 static WND* WIN_DestroyWindow( WND* wndPtr )
273 HWND32 hwnd = wndPtr->hwndSelf;
274 WND *pWnd;
276 TRACE(win, "%04x\n", wndPtr->hwndSelf );
278 #ifdef CONFIG_IPC
279 if (main_block)
280 DDE_DestroyWindow(wndPtr->hwndSelf);
281 #endif /* CONFIG_IPC */
283 /* free child windows */
285 while ((pWnd = wndPtr->child))
286 wndPtr->child = WIN_DestroyWindow( pWnd );
288 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
290 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
292 WINPOS_CheckInternalPos( hwnd );
293 if( hwnd == GetCapture32()) ReleaseCapture();
295 /* free resources associated with the window */
297 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
298 PROPERTY_RemoveWindowProps( wndPtr );
300 wndPtr->dwMagic = 0; /* Mark it as invalid */
301 wndPtr->hwndSelf = 0;
303 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
305 if (wndPtr->hrgnUpdate > 1) DeleteObject32( wndPtr->hrgnUpdate );
306 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
309 /* toss stale messages from the queue */
311 if( wndPtr->hmemTaskQ )
313 int pos;
314 BOOL32 bPostQuit = FALSE;
315 WPARAM32 wQuitParam = 0;
316 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
318 while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
320 if( msgQ->messages[pos].msg.message == WM_QUIT )
322 bPostQuit = TRUE;
323 wQuitParam = msgQ->messages[pos].msg.wParam;
325 QUEUE_RemoveMsg(msgQ, pos);
327 /* repost WM_QUIT to make sure this app exits its message loop */
328 if( bPostQuit ) PostQuitMessage32(wQuitParam);
329 wndPtr->hmemTaskQ = 0;
332 if (!(wndPtr->dwStyle & WS_CHILD))
333 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
334 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
335 if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
336 if (wndPtr->class->style & CS_OWNDC) DCE_FreeWindowDCE( wndPtr );
338 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
340 wndPtr->class->cWindows--;
341 wndPtr->class = NULL;
342 pWnd = wndPtr->next;
344 USER_HEAP_FREE( hwnd );
345 return pWnd;
348 /***********************************************************************
349 * WIN_ResetQueueWindows
351 * Reset the queue of all the children of a given window.
352 * Return TRUE if something was done.
354 BOOL32 WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
356 BOOL32 ret = FALSE;
358 if (hNew) /* Set a new queue */
360 for (wnd = wnd->child; (wnd); wnd = wnd->next)
362 if (wnd->hmemTaskQ == hQueue)
364 wnd->hmemTaskQ = hNew;
365 ret = TRUE;
367 if (wnd->child)
368 ret |= WIN_ResetQueueWindows( wnd->child, hQueue, hNew );
371 else /* Queue is being destroyed */
373 while (wnd->child)
375 WND *tmp = wnd->child;
376 ret = FALSE;
377 while (tmp)
379 if (tmp->hmemTaskQ == hQueue)
381 DestroyWindow32( tmp->hwndSelf );
382 ret = TRUE;
383 break;
385 if (tmp->child && WIN_ResetQueueWindows(tmp->child,hQueue,0))
386 ret = TRUE;
387 else
388 tmp = tmp->next;
390 if (!ret) break;
393 return ret;
396 /***********************************************************************
397 * WIN_CreateDesktopWindow
399 * Create the desktop window.
401 BOOL32 WIN_CreateDesktopWindow(void)
403 CLASS *class;
404 HWND32 hwndDesktop;
406 TRACE(win,"Creating desktop window\n");
408 if (!ICONTITLE_Init() ||
409 !WINPOS_CreateInternalPosAtom() ||
410 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
411 return FALSE;
413 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
414 if (!hwndDesktop) return FALSE;
415 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
417 pWndDesktop->next = NULL;
418 pWndDesktop->child = NULL;
419 pWndDesktop->parent = NULL;
420 pWndDesktop->owner = NULL;
421 pWndDesktop->class = class;
422 pWndDesktop->dwMagic = WND_MAGIC;
423 pWndDesktop->hwndSelf = hwndDesktop;
424 pWndDesktop->hInstance = 0;
425 pWndDesktop->rectWindow.left = 0;
426 pWndDesktop->rectWindow.top = 0;
427 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
428 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
429 pWndDesktop->rectClient = pWndDesktop->rectWindow;
430 pWndDesktop->text = NULL;
431 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
432 pWndDesktop->hrgnUpdate = 0;
433 pWndDesktop->hwndLastActive = hwndDesktop;
434 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
435 WS_CLIPSIBLINGS;
436 pWndDesktop->dwExStyle = 0;
437 pWndDesktop->dce = NULL;
438 pWndDesktop->pVScroll = NULL;
439 pWndDesktop->pHScroll = NULL;
440 pWndDesktop->pProp = NULL;
441 pWndDesktop->wIDmenu = 0;
442 pWndDesktop->flags = 0;
443 pWndDesktop->window = rootWindow;
444 pWndDesktop->hSysMenu = 0;
445 pWndDesktop->userdata = 0;
447 pWndDesktop->winproc = (WNDPROC16)class->winproc;
449 EVENT_RegisterWindow( pWndDesktop );
450 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
451 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
452 return TRUE;
456 /***********************************************************************
457 * WIN_CreateWindowEx
459 * Implementation of CreateWindowEx().
461 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
462 BOOL32 win32, BOOL32 unicode )
464 CLASS *classPtr;
465 WND *wndPtr;
466 HWND16 hwnd, hwndLinkAfter;
467 POINT32 maxSize, maxPos, minTrack, maxTrack;
468 LRESULT (WINAPI *localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
470 TRACE(win, "%s %s %08lx %08lx %d,%d %dx%d "
471 "%04x %04x %08x %p\n", debugres(cs->lpszName),
472 debugres(cs->lpszClass), cs->dwExStyle,
473 cs->style, cs->x, cs->y, cs->cx, cs->cy,
474 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
476 /* Find the parent window */
478 if (cs->hwndParent)
480 /* Make sure parent is valid */
481 if (!IsWindow32( cs->hwndParent ))
483 fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
484 return 0;
486 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
487 fprintf( stderr, "CreateWindowEx: no parent for child window\n" );
488 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
491 /* Find the window class */
492 if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
494 char buffer[256];
495 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
496 fprintf( stderr, "CreateWindowEx: bad class '%s'\n", buffer );
497 return 0;
500 /* Fix the coordinates */
502 if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0;
503 if (cs->cx == CW_USEDEFAULT32)
505 /* if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0;
506 else */
508 cs->cx = 600;
509 cs->cy = 400;
513 /* Create the window structure */
515 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
516 - sizeof(wndPtr->wExtra) )))
518 TRACE(win, "out of memory\n" );
519 return 0;
522 /* Fill the window structure */
524 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
525 wndPtr->next = NULL;
526 wndPtr->child = NULL;
528 if ((cs->style & WS_CHILD) && cs->hwndParent)
530 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
531 wndPtr->owner = NULL;
533 else
535 wndPtr->parent = pWndDesktop;
536 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
537 wndPtr->owner = NULL;
538 else
539 wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
542 wndPtr->window = 0;
543 wndPtr->class = classPtr;
544 wndPtr->winproc = classPtr->winproc;
545 wndPtr->dwMagic = WND_MAGIC;
546 wndPtr->hwndSelf = hwnd;
547 wndPtr->hInstance = cs->hInstance;
548 wndPtr->text = NULL;
549 wndPtr->hmemTaskQ = GetTaskQueue(0);
550 wndPtr->hrgnUpdate = 0;
551 wndPtr->hwndLastActive = hwnd;
552 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
553 wndPtr->dwExStyle = cs->dwExStyle;
554 wndPtr->wIDmenu = 0;
555 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
556 wndPtr->pVScroll = NULL;
557 wndPtr->pHScroll = NULL;
558 wndPtr->pProp = NULL;
559 wndPtr->userdata = 0;
560 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
561 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
563 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
565 /* Call the WH_CBT hook */
567 hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
569 if (HOOK_IsHooked( WH_CBT ))
571 CBT_CREATEWND32A cbtc;
573 cbtc.lpcs = cs;
574 cbtc.hwndInsertAfter = hwndLinkAfter;
575 if ( HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc) )
577 TRACE(win, "CBT-hook returned 0\n");
578 USER_HEAP_FREE( hwnd );
579 return 0;
583 /* Increment class window counter */
585 classPtr->cWindows++;
587 /* Correct the window style */
589 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
591 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
592 wndPtr->flags |= WIN_NEED_SIZE;
594 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
596 /* Get class or window DC if needed */
598 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
599 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
600 else wndPtr->dce = NULL;
602 /* Insert the window in the linked list */
604 WIN_LinkWindow( hwnd, hwndLinkAfter );
606 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
608 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
610 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
611 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
612 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
613 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
614 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
617 if(cs->style & WS_CHILD)
619 if(cs->cx < 0) cs->cx = 0;
620 if(cs->cy < 0) cs->cy = 0;
622 else
624 if (cs->cx <= 0) cs->cx = 1;
625 if (cs->cy <= 0) cs->cy = 1;
628 wndPtr->rectWindow.left = cs->x;
629 wndPtr->rectWindow.top = cs->y;
630 wndPtr->rectWindow.right = cs->x + cs->cx;
631 wndPtr->rectWindow.bottom = cs->y + cs->cy;
632 wndPtr->rectClient = wndPtr->rectWindow;
634 /* Create the X window (only for top-level windows, and then only */
635 /* when there's no desktop window) */
637 if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
639 XSetWindowAttributes win_attr;
641 if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
642 (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
644 win_attr.event_mask = ExposureMask | KeyPressMask |
645 KeyReleaseMask | PointerMotionMask |
646 ButtonPressMask | ButtonReleaseMask |
647 FocusChangeMask | StructureNotifyMask;
648 win_attr.override_redirect = FALSE;
649 wndPtr->flags |= WIN_MANAGED;
651 else
653 win_attr.event_mask = ExposureMask | KeyPressMask |
654 KeyReleaseMask | PointerMotionMask |
655 ButtonPressMask | ButtonReleaseMask |
656 FocusChangeMask;
657 win_attr.override_redirect = TRUE;
659 win_attr.colormap = COLOR_GetColormap();
660 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
661 win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
662 win_attr.cursor = CURSORICON_XCursor;
663 wndPtr->window = TSXCreateWindow( display, rootWindow, cs->x, cs->y,
664 cs->cx, cs->cy, 0, CopyFromParent,
665 InputOutput, CopyFromParent,
666 CWEventMask | CWOverrideRedirect |
667 CWColormap | CWCursor | CWSaveUnder |
668 CWBackingStore, &win_attr );
670 if ((wndPtr->flags & WIN_MANAGED) &&
671 (cs->dwExStyle & WS_EX_DLGMODALFRAME))
673 XSizeHints* size_hints = TSXAllocSizeHints();
675 if (size_hints)
677 size_hints->min_width = size_hints->max_width = cs->cx;
678 size_hints->min_height = size_hints->max_height = cs->cy;
679 size_hints->flags = (PSize | PMinSize | PMaxSize);
680 TSXSetWMSizeHints( display, wndPtr->window, size_hints,
681 XA_WM_NORMAL_HINTS );
682 TSXFree(size_hints);
686 if (cs->hwndParent) /* Get window owner */
688 Window win = WIN_GetXWindow( cs->hwndParent );
689 if (win) TSXSetTransientForHint( display, wndPtr->window, win );
691 EVENT_RegisterWindow( wndPtr );
694 /* Set the window menu */
696 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
698 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
699 else
701 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
702 if (classPtr->menuNameA)
703 cs->hMenu = HIWORD(classPtr->menuNameA) ?
704 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
705 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
706 #else
707 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
708 /* hInstance is still 16-bit in 980215 winelib */
709 if (HIWORD(cs->hInstance) || __winelib)
710 cs->hMenu = LoadMenu32A(cs->hInstance,PTR_SEG_TO_LIN(menuName));
711 else
712 /* doesn't work for winelib, since resources are unicode */
713 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
714 #endif
716 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
718 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
720 /* Send the WM_CREATE message
721 * Perhaps we shouldn't allow width/height changes as well.
722 * See p327 in "Internals".
725 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
727 localSend32 = unicode ? SendMessage32W : SendMessage32A;
728 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
730 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
731 NULL, NULL, 0, &wndPtr->rectClient );
732 OffsetRect32(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
733 maxPos.y - wndPtr->rectWindow.top);
734 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
736 /* Send the size messages */
738 if (!(wndPtr->flags & WIN_NEED_SIZE))
740 /* send it anyway */
742 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
743 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
744 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
745 SendMessage32A( hwnd, WM_MOVE, 0,
746 MAKELONG( wndPtr->rectClient.left,
747 wndPtr->rectClient.top ) );
750 /* Show the window, maximizing or minimizing if needed */
752 if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
754 RECT16 newPos;
755 UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
756 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
757 WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
758 swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow32()) ? SWP_NOACTIVATE : 0;
759 SetWindowPos32( hwnd, 0, newPos.left, newPos.top,
760 newPos.right, newPos.bottom, SWP_FRAMECHANGED | swFlag );
763 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
765 /* Notify the parent window only */
767 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
768 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
769 if( !IsWindow32(hwnd) ) return 0;
772 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
774 /* Call WH_SHELL hook */
776 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
777 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
779 TRACE(win, "created window %04x\n", hwnd);
780 return hwnd;
784 /* Abort window creation */
786 WARN(win, "aborted by WM_xxCREATE!\n");
787 WIN_UnlinkWindow( hwnd );
788 WIN_DestroyWindow( wndPtr );
789 return 0;
793 /***********************************************************************
794 * CreateWindow16 (USER.41)
796 HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
797 DWORD style, INT16 x, INT16 y, INT16 width,
798 INT16 height, HWND16 parent, HMENU16 menu,
799 HINSTANCE16 instance, LPVOID data )
801 return CreateWindowEx16( 0, className, windowName, style,
802 x, y, width, height, parent, menu, instance, data );
806 /***********************************************************************
807 * CreateWindowEx16 (USER.452)
809 HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
810 LPCSTR windowName, DWORD style, INT16 x,
811 INT16 y, INT16 width, INT16 height,
812 HWND16 parent, HMENU16 menu,
813 HINSTANCE16 instance, LPVOID data )
815 ATOM classAtom;
816 CREATESTRUCT32A cs;
818 /* Find the class atom */
820 if (!(classAtom = GlobalFindAtom32A( className )))
822 fprintf( stderr, "CreateWindowEx16: bad class name " );
823 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
824 else fprintf( stderr, "'%s'\n", className );
825 return 0;
828 /* Fix the coordinates */
830 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
831 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
832 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
833 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
835 /* Create the window */
837 cs.lpCreateParams = data;
838 cs.hInstance = (HINSTANCE32)instance;
839 cs.hMenu = (HMENU32)menu;
840 cs.hwndParent = (HWND32)parent;
841 cs.style = style;
842 cs.lpszName = windowName;
843 cs.lpszClass = className;
844 cs.dwExStyle = exStyle;
845 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
849 /***********************************************************************
850 * CreateWindowEx32A (USER32.83)
852 HWND32 WINAPI CreateWindowEx32A( DWORD exStyle, LPCSTR className,
853 LPCSTR windowName, DWORD style, INT32 x,
854 INT32 y, INT32 width, INT32 height,
855 HWND32 parent, HMENU32 menu,
856 HINSTANCE32 instance, LPVOID data )
858 ATOM classAtom;
859 CREATESTRUCT32A cs;
861 /* Find the class atom */
863 if (!(classAtom = GlobalFindAtom32A( className )))
865 fprintf( stderr, "CreateWindowEx32A: bad class name " );
866 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
867 else fprintf( stderr, "'%s'\n", className );
868 return 0;
871 /* Create the window */
873 cs.lpCreateParams = data;
874 cs.hInstance = instance;
875 cs.hMenu = menu;
876 cs.hwndParent = parent;
877 cs.x = x;
878 cs.y = y;
879 cs.cx = width;
880 cs.cy = height;
881 cs.style = style;
882 cs.lpszName = windowName;
883 cs.lpszClass = className;
884 cs.dwExStyle = exStyle;
885 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
889 /***********************************************************************
890 * CreateWindowEx32W (USER32.84)
892 HWND32 WINAPI CreateWindowEx32W( DWORD exStyle, LPCWSTR className,
893 LPCWSTR windowName, DWORD style, INT32 x,
894 INT32 y, INT32 width, INT32 height,
895 HWND32 parent, HMENU32 menu,
896 HINSTANCE32 instance, LPVOID data )
898 ATOM classAtom;
899 CREATESTRUCT32W cs;
901 /* Find the class atom */
903 if (!(classAtom = GlobalFindAtom32W( className )))
905 if (HIWORD(className))
907 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
908 fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
909 HeapFree( GetProcessHeap(), 0, cn );
911 else
912 fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
913 return 0;
916 /* Create the window */
918 cs.lpCreateParams = data;
919 cs.hInstance = instance;
920 cs.hMenu = menu;
921 cs.hwndParent = parent;
922 cs.x = x;
923 cs.y = y;
924 cs.cx = width;
925 cs.cy = height;
926 cs.style = style;
927 cs.lpszName = windowName;
928 cs.lpszClass = className;
929 cs.dwExStyle = exStyle;
930 /* Note: we rely on the fact that CREATESTRUCT32A and */
931 /* CREATESTRUCT32W have the same layout. */
932 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
936 /***********************************************************************
937 * WIN_CheckFocus
939 static void WIN_CheckFocus( WND* pWnd )
941 if( GetFocus16() == pWnd->hwndSelf )
942 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
945 /***********************************************************************
946 * WIN_SendDestroyMsg
948 static void WIN_SendDestroyMsg( WND* pWnd )
950 WIN_CheckFocus(pWnd);
952 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
953 if( !pWnd->window ) CLIPBOARD_ResetOwner( pWnd );
955 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
957 if( IsWindow32(pWnd->hwndSelf) )
959 WND* pChild = pWnd->child;
960 while( pChild )
962 WIN_SendDestroyMsg( pChild );
963 pChild = pChild->next;
965 WIN_CheckFocus(pWnd);
967 else
968 WARN(win, "\tdestroyed itself while in WM_DESTROY!\n");
972 /***********************************************************************
973 * DestroyWindow16 (USER.53)
975 BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
977 return DestroyWindow32(hwnd);
981 /***********************************************************************
982 * DestroyWindow32 (USER32.135)
984 BOOL32 WINAPI DestroyWindow32( HWND32 hwnd )
986 WND * wndPtr;
988 TRACE(win, "(%04x)\n", hwnd);
990 /* Initialization */
992 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
993 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
995 /* Call hooks */
997 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
998 return FALSE;
1000 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1002 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
1003 /* FIXME: clean up palette - see "Internals" p.352 */
1006 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
1007 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
1009 /* Notify the parent window only */
1010 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
1011 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
1012 if( !IsWindow32(hwnd) ) return TRUE;
1015 if( wndPtr->window ) CLIPBOARD_ResetOwner( wndPtr ); /* before the window is unmapped */
1017 /* Hide the window */
1019 if (wndPtr->dwStyle & WS_VISIBLE)
1021 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
1022 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
1023 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
1024 if (!IsWindow32(hwnd)) return TRUE;
1027 /* Recursively destroy owned windows */
1029 if( !(wndPtr->dwStyle & WS_CHILD) )
1031 /* make sure top menu popup doesn't get destroyed */
1032 MENU_PatchResidentPopup( (HQUEUE16)0xFFFF, wndPtr );
1034 for (;;)
1036 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1037 while (siblingPtr)
1039 if (siblingPtr->owner == wndPtr)
1040 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1041 break;
1042 else
1043 siblingPtr->owner = NULL;
1044 siblingPtr = siblingPtr->next;
1046 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1047 else break;
1050 if( !Options.managed || EVENT_CheckFocus() )
1051 WINPOS_ActivateOtherWindow(wndPtr);
1053 if( wndPtr->owner &&
1054 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1055 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1058 /* Send destroy messages */
1060 WIN_SendDestroyMsg( wndPtr );
1061 if (!IsWindow32(hwnd)) return TRUE;
1063 /* Unlink now so we won't bother with the children later on */
1065 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1067 /* Destroy the window storage */
1069 WIN_DestroyWindow( wndPtr );
1070 return TRUE;
1074 /***********************************************************************
1075 * CloseWindow16 (USER.43)
1077 BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
1079 return CloseWindow32( hwnd );
1083 /***********************************************************************
1084 * CloseWindow32 (USER32.56)
1086 BOOL32 WINAPI CloseWindow32( HWND32 hwnd )
1088 WND * wndPtr = WIN_FindWndPtr( hwnd );
1089 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1090 ShowWindow32( hwnd, SW_MINIMIZE );
1091 return TRUE;
1095 /***********************************************************************
1096 * OpenIcon16 (USER.44)
1098 BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
1100 return OpenIcon32( hwnd );
1104 /***********************************************************************
1105 * OpenIcon32 (USER32.410)
1107 BOOL32 WINAPI OpenIcon32( HWND32 hwnd )
1109 if (!IsIconic32( hwnd )) return FALSE;
1110 ShowWindow32( hwnd, SW_SHOWNORMAL );
1111 return TRUE;
1115 /***********************************************************************
1116 * WIN_FindWindow
1118 * Implementation of FindWindow() and FindWindowEx().
1120 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1121 LPCSTR title )
1123 WND *pWnd;
1124 CLASS *pClass = NULL;
1126 if (child)
1128 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1129 if (parent)
1131 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1133 else if (pWnd->parent != pWndDesktop) return 0;
1134 pWnd = pWnd->next;
1136 else
1138 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1139 pWnd = pWnd->child;
1141 if (!pWnd) return 0;
1143 /* For a child window, all siblings will have the same hInstance, */
1144 /* so we can look for the class once and for all. */
1146 if (className && (pWnd->dwStyle & WS_CHILD))
1148 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1149 return 0;
1153 for ( ; pWnd; pWnd = pWnd->next)
1155 if (className && !(pWnd->dwStyle & WS_CHILD))
1157 if (!(pClass = CLASS_FindClassByAtom( className, GetExePtr(pWnd->hInstance))))
1158 continue; /* Skip this window */
1161 if (pClass && (pWnd->class != pClass))
1162 continue; /* Not the right class */
1164 /* Now check the title */
1166 if (!title) return pWnd->hwndSelf;
1167 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1169 return 0;
1174 /***********************************************************************
1175 * FindWindow16 (USER.50)
1177 HWND16 WINAPI FindWindow16( SEGPTR className, LPCSTR title )
1179 return FindWindowEx16( 0, 0, className, title );
1183 /***********************************************************************
1184 * FindWindowEx16 (USER.427)
1186 HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child,
1187 SEGPTR className, LPCSTR title )
1189 ATOM atom = 0;
1191 TRACE(win, "%04x %04x '%s' '%s'\n", parent,
1192 child, HIWORD(className)?(char *)PTR_SEG_TO_LIN(className):"",
1193 title ? title : "");
1195 if (className)
1197 /* If the atom doesn't exist, then no class */
1198 /* with this name exists either. */
1199 if (!(atom = GlobalFindAtom16( className ))) return 0;
1201 return WIN_FindWindow( parent, child, atom, title );
1205 /***********************************************************************
1206 * FindWindow32A (USER32.198)
1208 HWND32 WINAPI FindWindow32A( LPCSTR className, LPCSTR title )
1210 return FindWindowEx32A( 0, 0, className, title );
1214 /***********************************************************************
1215 * FindWindowEx32A (USER32.199)
1217 HWND32 WINAPI FindWindowEx32A( HWND32 parent, HWND32 child,
1218 LPCSTR className, LPCSTR title )
1220 ATOM atom = 0;
1222 if (className)
1224 /* If the atom doesn't exist, then no class */
1225 /* with this name exists either. */
1226 if (!(atom = GlobalFindAtom32A( className ))) return 0;
1228 return WIN_FindWindow( parent, child, atom, title );
1232 /***********************************************************************
1233 * FindWindowEx32W (USER32.200)
1235 HWND32 WINAPI FindWindowEx32W( HWND32 parent, HWND32 child,
1236 LPCWSTR className, LPCWSTR title )
1238 ATOM atom = 0;
1239 char *buffer;
1240 HWND32 hwnd;
1242 if (className)
1244 /* If the atom doesn't exist, then no class */
1245 /* with this name exists either. */
1246 if (!(atom = GlobalFindAtom32W( className ))) return 0;
1248 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1249 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1250 HeapFree( GetProcessHeap(), 0, buffer );
1251 return hwnd;
1255 /***********************************************************************
1256 * FindWindow32W (USER32.201)
1258 HWND32 WINAPI FindWindow32W( LPCWSTR className, LPCWSTR title )
1260 return FindWindowEx32W( 0, 0, className, title );
1264 /**********************************************************************
1265 * WIN_GetDesktop
1267 WND *WIN_GetDesktop(void)
1269 return pWndDesktop;
1273 /**********************************************************************
1274 * GetDesktopWindow16 (USER.286)
1276 HWND16 WINAPI GetDesktopWindow16(void)
1278 return (HWND16)pWndDesktop->hwndSelf;
1282 /**********************************************************************
1283 * GetDesktopWindow32 (USER32.232)
1285 HWND32 WINAPI GetDesktopWindow32(void)
1287 return pWndDesktop->hwndSelf;
1291 /**********************************************************************
1292 * GetDesktopHwnd (USER.278)
1294 * Exactly the same thing as GetDesktopWindow(), but not documented.
1295 * Don't ask me why...
1297 HWND16 WINAPI GetDesktopHwnd(void)
1299 return (HWND16)pWndDesktop->hwndSelf;
1303 /*******************************************************************
1304 * EnableWindow16 (USER.34)
1306 BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
1308 return EnableWindow32( hwnd, enable );
1312 /*******************************************************************
1313 * EnableWindow32 (USER32.172)
1315 BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
1317 WND *wndPtr;
1319 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1320 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1322 /* Enable window */
1323 wndPtr->dwStyle &= ~WS_DISABLED;
1324 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1325 return TRUE;
1327 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1329 /* Disable window */
1330 wndPtr->dwStyle |= WS_DISABLED;
1331 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1332 SetFocus32( 0 ); /* A disabled window can't have the focus */
1333 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1334 ReleaseCapture(); /* A disabled window can't capture the mouse */
1335 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1336 return FALSE;
1338 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1342 /***********************************************************************
1343 * IsWindowEnabled16 (USER.35)
1345 BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
1347 return IsWindowEnabled32(hWnd);
1351 /***********************************************************************
1352 * IsWindowEnabled32 (USER32.349)
1354 BOOL32 WINAPI IsWindowEnabled32(HWND32 hWnd)
1356 WND * wndPtr;
1358 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1359 return !(wndPtr->dwStyle & WS_DISABLED);
1363 /***********************************************************************
1364 * IsWindowUnicode (USER32.350)
1366 BOOL32 WINAPI IsWindowUnicode( HWND32 hwnd )
1368 WND * wndPtr;
1370 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1371 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1375 /**********************************************************************
1376 * GetWindowWord16 (USER.133)
1378 WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
1380 return GetWindowWord32( hwnd, offset );
1384 /**********************************************************************
1385 * GetWindowWord32 (USER32.314)
1387 WORD WINAPI GetWindowWord32( HWND32 hwnd, INT32 offset )
1389 WND * wndPtr = WIN_FindWndPtr( hwnd );
1390 if (!wndPtr) return 0;
1391 if (offset >= 0)
1393 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1395 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1396 return 0;
1398 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1400 switch(offset)
1402 case GWW_ID:
1403 if (HIWORD(wndPtr->wIDmenu))
1404 fprintf(stderr,"GetWindowWord32(GWW_ID) discards high bits of 0x%08x!\n",wndPtr->wIDmenu);
1405 return (WORD)wndPtr->wIDmenu;
1406 case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
1407 case GWW_HINSTANCE:
1408 if (HIWORD(wndPtr->hInstance))
1409 fprintf(stderr,"GetWindowWord32(GWW_HINSTANCE) discards high bits of 0x%08x!\n",wndPtr->hInstance);
1410 return (WORD)wndPtr->hInstance;
1411 default:
1412 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1413 return 0;
1418 /**********************************************************************
1419 * WIN_GetWindowInstance
1421 HINSTANCE32 WIN_GetWindowInstance( HWND32 hwnd )
1423 WND * wndPtr = WIN_FindWndPtr( hwnd );
1424 if (!wndPtr) return (HINSTANCE32)0;
1425 return wndPtr->hInstance;
1429 /**********************************************************************
1430 * SetWindowWord16 (USER.134)
1432 WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1434 return SetWindowWord32( hwnd, offset, newval );
1438 /**********************************************************************
1439 * SetWindowWord32 (USER32.524)
1441 WORD WINAPI SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1443 WORD *ptr, retval;
1444 WND * wndPtr = WIN_FindWndPtr( hwnd );
1445 if (!wndPtr) return 0;
1446 if (offset >= 0)
1448 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1450 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1451 return 0;
1453 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1455 else switch(offset)
1457 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1458 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1459 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1460 default:
1461 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1462 return 0;
1464 retval = *ptr;
1465 *ptr = newval;
1466 return retval;
1470 /**********************************************************************
1471 * WIN_GetWindowLong
1473 * Helper function for GetWindowLong().
1475 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1477 LONG retval;
1478 WND * wndPtr = WIN_FindWndPtr( hwnd );
1479 if (!wndPtr) return 0;
1480 if (offset >= 0)
1482 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1484 fprintf( stderr, "GetWindowLong: invalid offset %d\n", offset );
1485 return 0;
1487 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1488 /* Special case for dialog window procedure */
1489 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1490 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1491 return retval;
1493 switch(offset)
1495 case GWL_USERDATA: return wndPtr->userdata;
1496 case GWL_STYLE: return wndPtr->dwStyle;
1497 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1498 case GWL_ID: return (LONG)wndPtr->wIDmenu;
1499 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1500 type );
1501 case GWL_HWNDPARENT: return wndPtr->parent ?
1502 (HWND32)wndPtr->parent->hwndSelf : 0;
1503 case GWL_HINSTANCE: return wndPtr->hInstance;
1504 default:
1505 fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
1507 return 0;
1511 /**********************************************************************
1512 * WIN_SetWindowLong
1514 * Helper function for SetWindowLong().
1516 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1517 WINDOWPROCTYPE type )
1519 LONG *ptr, retval;
1520 WND * wndPtr = WIN_FindWndPtr( hwnd );
1522 if (!wndPtr) return 0;
1523 if (offset >= 0)
1525 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1527 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1528 return 0;
1530 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1531 /* Special case for dialog window procedure */
1532 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1534 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1535 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1536 type, WIN_PROC_WINDOW );
1537 return retval;
1540 else switch(offset)
1542 case GWL_ID:
1543 ptr = (DWORD*)&wndPtr->wIDmenu;
1544 break;
1545 case GWL_HINSTANCE:
1546 return SetWindowWord32( hwnd, offset, newval );
1547 case GWL_WNDPROC:
1548 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1549 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1550 type, WIN_PROC_WINDOW );
1551 return retval;
1552 case GWL_STYLE:
1554 /* FIXME: WM_STYLE... messages for WIN_ISWIN32 windows */
1556 ptr = &wndPtr->dwStyle;
1557 /* Some bits can't be changed this way */
1558 newval &= ~(WS_VISIBLE | WS_CHILD);
1559 newval |= (*ptr & (WS_VISIBLE | WS_CHILD));
1560 break;
1561 case GWL_USERDATA: ptr = &wndPtr->userdata; break;
1562 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
1563 default:
1564 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1565 return 0;
1567 retval = *ptr;
1568 *ptr = newval;
1569 return retval;
1573 /**********************************************************************
1574 * GetWindowLong16 (USER.135)
1576 LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
1578 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1582 /**********************************************************************
1583 * GetWindowLong32A (USER32.305)
1585 LONG WINAPI GetWindowLong32A( HWND32 hwnd, INT32 offset )
1587 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1591 /**********************************************************************
1592 * GetWindowLong32W (USER32.306)
1594 LONG WINAPI GetWindowLong32W( HWND32 hwnd, INT32 offset )
1596 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1600 /**********************************************************************
1601 * SetWindowLong16 (USER.136)
1603 LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1605 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1609 /**********************************************************************
1610 * SetWindowLong32A (USER32.517)
1612 LONG WINAPI SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1614 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1618 /**********************************************************************
1619 * SetWindowLong32W (USER32.518)
1621 LONG WINAPI SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
1623 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1627 /*******************************************************************
1628 * GetWindowText16 (USER.36)
1630 INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1632 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1636 /*******************************************************************
1637 * GetWindowText32A (USER32.309)
1639 INT32 WINAPI GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1641 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1642 (LPARAM)lpString );
1646 /*******************************************************************
1647 * GetWindowText32W (USER32.312)
1649 INT32 WINAPI GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1651 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1652 (LPARAM)lpString );
1656 /*******************************************************************
1657 * SetWindowText16 (USER.37)
1659 void WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1661 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1665 /*******************************************************************
1666 * SetWindowText32A (USER32.521)
1668 void WINAPI SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1670 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1674 /*******************************************************************
1675 * SetWindowText32W (USER32.523)
1677 void WINAPI SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1679 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1683 /*******************************************************************
1684 * GetWindowTextLength16 (USER.38)
1686 INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
1688 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1692 /*******************************************************************
1693 * GetWindowTextLength32A (USER32.310)
1695 INT32 WINAPI GetWindowTextLength32A( HWND32 hwnd )
1697 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1700 /*******************************************************************
1701 * GetWindowTextLength32W (USER32.311)
1703 INT32 WINAPI GetWindowTextLength32W( HWND32 hwnd )
1705 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1709 /*******************************************************************
1710 * IsWindow16 (USER.47)
1712 BOOL16 WINAPI IsWindow16( HWND16 hwnd )
1714 return IsWindow32( hwnd );
1718 /*******************************************************************
1719 * IsWindow32 (USER32.348)
1721 BOOL32 WINAPI IsWindow32( HWND32 hwnd )
1723 WND * wndPtr = WIN_FindWndPtr( hwnd );
1724 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1728 /*****************************************************************
1729 * GetParent16 (USER.46)
1731 HWND16 WINAPI GetParent16( HWND16 hwnd )
1733 return (HWND16)GetParent32( hwnd );
1737 /*****************************************************************
1738 * GetParent32 (USER32.278)
1740 HWND32 WINAPI GetParent32( HWND32 hwnd )
1742 WND *wndPtr = WIN_FindWndPtr(hwnd);
1743 if (!wndPtr) return 0;
1744 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1745 return wndPtr ? wndPtr->hwndSelf : 0;
1748 /*****************************************************************
1749 * WIN_GetTopParent
1751 * Get the top-level parent for a child window.
1753 WND* WIN_GetTopParentPtr( WND* pWnd )
1755 while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
1756 return pWnd;
1759 /*****************************************************************
1760 * WIN_GetTopParent
1762 * Get the top-level parent for a child window.
1764 HWND32 WIN_GetTopParent( HWND32 hwnd )
1766 WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
1767 return wndPtr ? wndPtr->hwndSelf : 0;
1771 /*****************************************************************
1772 * SetParent16 (USER.233)
1774 HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1776 return SetParent32( hwndChild, hwndNewParent );
1780 /*****************************************************************
1781 * SetParent32 (USER32.495)
1783 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1785 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1786 WND *pWndParent = (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent )
1787 : pWndDesktop;
1789 if( wndPtr && pWndParent && (wndPtr != pWndDesktop) )
1791 WND* pWndPrev = wndPtr->parent;
1793 if( pWndParent != pWndPrev )
1795 BOOL32 bFixupDCE = IsWindowVisible32(hwndChild);
1797 if ( wndPtr->window )
1799 /* Toplevel window needs to be reparented. Used by Tk 8.0 */
1801 TSXDestroyWindow( display, wndPtr->window );
1802 wndPtr->window = None;
1804 else if( bFixupDCE )
1805 DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
1807 WIN_UnlinkWindow(hwndChild);
1808 wndPtr->parent = pWndParent;
1810 /* FIXME: Create an X counterpart for reparented top-level windows
1811 * when not in the desktop mode. */
1813 if ( pWndParent == pWndDesktop )
1814 wndPtr->dwStyle &= ~WS_CHILD;
1815 else wndPtr->dwStyle |= WS_CHILD;
1816 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
1818 if( bFixupDCE )
1820 DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
1821 UpdateWindow32(hwndChild);
1824 return pWndPrev->hwndSelf;
1825 } /* failure */
1826 return 0;
1830 /*******************************************************************
1831 * IsChild16 (USER.48)
1833 BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
1835 return IsChild32(parent,child);
1839 /*******************************************************************
1840 * IsChild32 (USER32.339)
1842 BOOL32 WINAPI IsChild32( HWND32 parent, HWND32 child )
1844 WND * wndPtr = WIN_FindWndPtr( child );
1845 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1847 wndPtr = wndPtr->parent;
1848 if (wndPtr->hwndSelf == parent) return TRUE;
1850 return FALSE;
1854 /***********************************************************************
1855 * IsWindowVisible16 (USER.49)
1857 BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
1859 return IsWindowVisible32(hwnd);
1863 /***********************************************************************
1864 * IsWindowVisible32 (USER32.351)
1866 BOOL32 WINAPI IsWindowVisible32( HWND32 hwnd )
1868 WND *wndPtr = WIN_FindWndPtr( hwnd );
1869 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1871 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1872 wndPtr = wndPtr->parent;
1874 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1878 /***********************************************************************
1879 * WIN_IsWindowDrawable
1881 * hwnd is drawable when it is visible, all parents are not
1882 * minimized, and it is itself not minimized unless we are
1883 * trying to draw its default class icon.
1885 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
1887 if( (wnd->dwStyle & WS_MINIMIZE &&
1888 icon && wnd->class->hIcon) ||
1889 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
1890 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
1891 if( wnd->dwStyle & WS_MINIMIZE ||
1892 !(wnd->dwStyle & WS_VISIBLE) ) break;
1893 return (wnd == NULL);
1897 /*******************************************************************
1898 * GetTopWindow16 (USER.229)
1900 HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
1902 return GetTopWindow32(hwnd);
1906 /*******************************************************************
1907 * GetTopWindow32 (USER.229)
1909 HWND32 WINAPI GetTopWindow32( HWND32 hwnd )
1911 WND * wndPtr = WIN_FindWndPtr( hwnd );
1912 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1913 else return 0;
1917 /*******************************************************************
1918 * GetWindow16 (USER.262)
1920 HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
1922 return GetWindow32( hwnd,rel );
1926 /*******************************************************************
1927 * GetWindow32 (USER32.302)
1929 HWND32 WINAPI GetWindow32( HWND32 hwnd, WORD rel )
1931 WND * wndPtr = WIN_FindWndPtr( hwnd );
1932 if (!wndPtr) return 0;
1933 switch(rel)
1935 case GW_HWNDFIRST:
1936 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
1937 else return 0;
1939 case GW_HWNDLAST:
1940 if (!wndPtr->parent) return 0; /* Desktop window */
1941 while (wndPtr->next) wndPtr = wndPtr->next;
1942 return wndPtr->hwndSelf;
1944 case GW_HWNDNEXT:
1945 if (!wndPtr->next) return 0;
1946 return wndPtr->next->hwndSelf;
1948 case GW_HWNDPREV:
1949 if (!wndPtr->parent) return 0; /* Desktop window */
1950 wndPtr = wndPtr->parent->child; /* First sibling */
1951 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
1952 while (wndPtr->next)
1954 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
1955 wndPtr = wndPtr->next;
1957 return 0;
1959 case GW_OWNER:
1960 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
1962 case GW_CHILD:
1963 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
1965 return 0;
1969 /*******************************************************************
1970 * GetNextWindow16 (USER.230)
1972 HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
1974 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1975 return GetWindow16( hwnd, flag );
1978 /*******************************************************************
1979 * ShowOwnedPopups16 (USER.265)
1981 void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
1983 ShowOwnedPopups32( owner, fShow );
1987 /*******************************************************************
1988 * ShowOwnedPopups32 (USER32.531)
1990 BOOL32 WINAPI ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
1992 WND *pWnd = pWndDesktop->child;
1993 while (pWnd)
1995 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
1996 (pWnd->dwStyle & WS_POPUP))
1997 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
1998 pWnd = pWnd->next;
2000 return TRUE;
2004 /*******************************************************************
2005 * GetLastActivePopup16 (USER.287)
2007 HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
2009 return GetLastActivePopup32( hwnd );
2012 /*******************************************************************
2013 * GetLastActivePopup32 (USER32.256)
2015 HWND32 WINAPI GetLastActivePopup32( HWND32 hwnd )
2017 WND *wndPtr;
2018 wndPtr = WIN_FindWndPtr(hwnd);
2019 if (wndPtr == NULL) return hwnd;
2020 return wndPtr->hwndLastActive;
2024 /*******************************************************************
2025 * WIN_BuildWinArray
2027 * Build an array of pointers to the children of a given window.
2028 * The array must be freed with HeapFree(SystemHeap). Return NULL
2029 * when no windows are found.
2031 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
2033 WND **list, **ppWnd;
2034 WND *pWnd;
2035 UINT32 count, skipOwned, skipHidden;
2036 DWORD skipFlags;
2038 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2039 skipOwned = bwaFlags & BWA_SKIPOWNED;
2040 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2041 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
2043 /* First count the windows */
2045 if (!wndPtr) wndPtr = pWndDesktop;
2046 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
2048 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2049 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
2052 if( count )
2054 /* Now build the list of all windows */
2056 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
2058 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
2060 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2061 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2063 *ppWnd++ = pWnd;
2064 count++;
2067 *ppWnd = NULL;
2069 else count = 0;
2070 } else list = NULL;
2072 if( pTotal ) *pTotal = count;
2073 return list;
2077 /*******************************************************************
2078 * EnumWindows16 (USER.54)
2080 BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2082 WND **list, **ppWnd;
2084 /* We have to build a list of all windows first, to avoid */
2085 /* unpleasant side-effects, for instance if the callback */
2086 /* function changes the Z-order of the windows. */
2088 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2090 /* Now call the callback function for every window */
2092 for (ppWnd = list; *ppWnd; ppWnd++)
2094 /* Make sure that the window still exists */
2095 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2096 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2098 HeapFree( SystemHeap, 0, list );
2099 return TRUE;
2103 /*******************************************************************
2104 * EnumWindows32 (USER32.193)
2106 BOOL32 WINAPI EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2108 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2112 /**********************************************************************
2113 * EnumTaskWindows16 (USER.225)
2115 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2116 LPARAM lParam )
2118 WND **list, **ppWnd;
2119 HQUEUE16 hQueue = GetTaskQueue( hTask );
2121 /* This function is the same as EnumWindows(), */
2122 /* except for an added check on the window queue. */
2124 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2126 /* Now call the callback function for every window */
2128 for (ppWnd = list; *ppWnd; ppWnd++)
2130 /* Make sure that the window still exists */
2131 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2132 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
2133 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2135 HeapFree( SystemHeap, 0, list );
2136 return TRUE;
2140 /**********************************************************************
2141 * EnumThreadWindows (USER32.190)
2143 BOOL32 WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2145 THDB *tdb = THREAD_ID_TO_THDB(id);
2147 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2151 /**********************************************************************
2152 * WIN_EnumChildWindows
2154 * Helper function for EnumChildWindows().
2156 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2157 LPARAM lParam )
2159 WND **childList;
2160 BOOL16 ret = FALSE;
2162 for ( ; *ppWnd; ppWnd++)
2164 /* Make sure that the window still exists */
2165 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2166 /* Build children list first */
2167 if (!(childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL )))
2168 return FALSE;
2169 if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
2170 ret = WIN_EnumChildWindows( childList, func, lParam );
2171 HeapFree( SystemHeap, 0, childList );
2172 if (!ret) return FALSE;
2174 return TRUE;
2178 /**********************************************************************
2179 * EnumChildWindows16 (USER.55)
2181 BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2182 LPARAM lParam )
2184 WND **list, *pParent;
2186 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2187 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2188 WIN_EnumChildWindows( list, func, lParam );
2189 HeapFree( SystemHeap, 0, list );
2190 return TRUE;
2194 /**********************************************************************
2195 * EnumChildWindows32 (USER32.178)
2197 BOOL32 WINAPI EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
2198 LPARAM lParam )
2200 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2201 lParam );
2205 /*******************************************************************
2206 * AnyPopup16 (USER.52)
2208 BOOL16 WINAPI AnyPopup16(void)
2210 return AnyPopup32();
2214 /*******************************************************************
2215 * AnyPopup32 (USER32.4)
2217 BOOL32 WINAPI AnyPopup32(void)
2219 WND *wndPtr;
2220 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2221 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2222 return FALSE;
2226 /*******************************************************************
2227 * FlashWindow16 (USER.105)
2229 BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2231 return FlashWindow32( hWnd, bInvert );
2235 /*******************************************************************
2236 * FlashWindow32 (USER32.202)
2238 BOOL32 WINAPI FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2240 WND *wndPtr = WIN_FindWndPtr(hWnd);
2242 TRACE(win,"%04x\n", hWnd);
2244 if (!wndPtr) return FALSE;
2246 if (wndPtr->dwStyle & WS_MINIMIZE)
2248 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2250 HDC32 hDC = GetDC32(hWnd);
2252 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2253 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2255 ReleaseDC32( hWnd, hDC );
2256 wndPtr->flags |= WIN_NCACTIVATED;
2258 else
2260 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2261 RDW_UPDATENOW | RDW_FRAME, 0 );
2262 wndPtr->flags &= ~WIN_NCACTIVATED;
2264 return TRUE;
2266 else
2268 WPARAM16 wparam;
2269 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2270 else wparam = (hWnd == GetActiveWindow32());
2272 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2273 return wparam;
2278 /*******************************************************************
2279 * SetSysModalWindow16 (USER.188)
2281 HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
2283 HWND32 hWndOldModal = hwndSysModal;
2284 hwndSysModal = hWnd;
2285 FIXME(win, "EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2286 return hWndOldModal;
2290 /*******************************************************************
2291 * GetSysModalWindow16 (USER.52)
2293 HWND16 WINAPI GetSysModalWindow16(void)
2295 return hwndSysModal;
2299 /*******************************************************************
2300 * DRAG_QueryUpdate
2302 * recursively find a child that contains spDragInfo->pt point
2303 * and send WM_QUERYDROPOBJECT
2305 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2307 BOOL16 wParam,bResult = 0;
2308 POINT32 pt;
2309 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2310 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2311 RECT32 tempRect;
2313 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2315 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2317 GetWindowRect32(hQueryWnd,&tempRect);
2319 if( !PtInRect32(&tempRect,pt) ||
2320 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2321 return 0;
2323 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2325 tempRect = ptrQueryWnd->rectClient;
2326 if(ptrQueryWnd->dwStyle & WS_CHILD)
2327 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2328 (LPPOINT32)&tempRect, 2 );
2330 if (PtInRect32( &tempRect, pt))
2332 wParam = 0;
2334 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2335 if( ptrWnd->dwStyle & WS_VISIBLE )
2337 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2338 if (PtInRect32( &tempRect, pt )) break;
2341 if(ptrWnd)
2343 TRACE(msg,"hwnd = %04x, %d %d - %d %d\n",
2344 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2345 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2346 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2347 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2350 if(bResult) return bResult;
2352 else wParam = 1;
2354 else wParam = 1;
2356 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2358 ptrDragInfo->hScope = hQueryWnd;
2360 bResult = ( bNoSend )
2361 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2362 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2363 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2364 if( !bResult )
2365 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2367 return bResult;
2371 /*******************************************************************
2372 * DragDetect (USER.465)
2374 BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
2376 POINT32 pt32;
2377 CONV_POINT16TO32( &pt, &pt32 );
2378 return DragDetect32( hWnd, pt32 );
2381 /*******************************************************************
2382 * DragDetect32 (USER32.151)
2384 BOOL32 WINAPI DragDetect32( HWND32 hWnd, POINT32 pt )
2386 MSG16 msg;
2387 RECT16 rect;
2389 rect.left = pt.x - wDragWidth;
2390 rect.right = pt.x + wDragWidth;
2392 rect.top = pt.y - wDragHeight;
2393 rect.bottom = pt.y + wDragHeight;
2395 SetCapture32(hWnd);
2397 while(1)
2399 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2401 if( msg.message == WM_LBUTTONUP )
2403 ReleaseCapture();
2404 return 0;
2406 if( msg.message == WM_MOUSEMOVE )
2408 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2410 ReleaseCapture();
2411 return 1;
2415 WaitMessage();
2417 return 0;
2420 /******************************************************************************
2421 * DragObject16 (USER.464)
2423 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2424 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2426 MSG16 msg;
2427 LPDRAGINFO lpDragInfo;
2428 SEGPTR spDragInfo;
2429 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2430 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2431 WND *wndPtr = WIN_FindWndPtr(hWnd);
2432 HCURSOR16 hCurrentCursor = 0;
2433 HWND16 hCurrentWnd = 0;
2435 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2436 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2438 if( !lpDragInfo || !spDragInfo ) return 0L;
2440 hBummer = LoadCursor16(0, IDC_BUMMER);
2442 if( !hBummer || !wndPtr )
2444 GlobalFree16(hDragInfo);
2445 return 0L;
2448 if(hCursor)
2450 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2452 GlobalFree16(hDragInfo);
2453 return 0L;
2456 if( hDragCursor == hCursor ) hDragCursor = 0;
2457 else hCursor = hDragCursor;
2459 hOldCursor = SetCursor32(hDragCursor);
2462 lpDragInfo->hWnd = hWnd;
2463 lpDragInfo->hScope = 0;
2464 lpDragInfo->wFlags = wObj;
2465 lpDragInfo->hList = szList; /* near pointer! */
2466 lpDragInfo->hOfStruct = hOfStruct;
2467 lpDragInfo->l = 0L;
2469 SetCapture32(hWnd);
2470 ShowCursor32( TRUE );
2474 do{ WaitMessage(); }
2475 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2477 *(lpDragInfo+1) = *lpDragInfo;
2479 lpDragInfo->pt = msg.pt;
2481 /* update DRAGINFO struct */
2482 TRACE(msg,"lpDI->hScope = %04x\n",lpDragInfo->hScope);
2484 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2485 hCurrentCursor = hCursor;
2486 else
2488 hCurrentCursor = hBummer;
2489 lpDragInfo->hScope = 0;
2491 if( hCurrentCursor )
2492 SetCursor32(hCurrentCursor);
2494 /* send WM_DRAGLOOP */
2495 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2496 (LPARAM) spDragInfo );
2497 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2498 if( hCurrentWnd != lpDragInfo->hScope )
2500 if( hCurrentWnd )
2501 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2502 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2503 HIWORD(spDragInfo)) );
2504 hCurrentWnd = lpDragInfo->hScope;
2505 if( hCurrentWnd )
2506 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2508 else
2509 if( hCurrentWnd )
2510 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2512 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2514 ReleaseCapture();
2515 ShowCursor32( FALSE );
2517 if( hCursor )
2519 SetCursor32( hOldCursor );
2520 if (hDragCursor) DestroyCursor32( hDragCursor );
2523 if( hCurrentCursor != hBummer )
2524 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2525 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2526 else
2527 msg.lParam = 0;
2528 GlobalFree16(hDragInfo);
2530 return (DWORD)(msg.lParam);