Release 980329
[wine.git] / windows / win.c
blobb15181de720de81f1a787d05ed13d25a4262975e
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"
35 /* Desktop window */
36 static WND *pWndDesktop = NULL;
38 static HWND32 hwndSysModal = 0;
40 static WORD wDragWidth = 4;
41 static WORD wDragHeight= 3;
43 extern BOOL32 ICONTITLE_Init(void);
44 extern BOOL32 MENU_PatchResidentPopup( HQUEUE16, WND* );
45 extern HWND32 CARET_GetHwnd(void);
46 extern BOOL32 EVENT_CheckFocus(void);
48 /***********************************************************************
49 * WIN_FindWndPtr
51 * Return a pointer to the WND structure corresponding to a HWND.
53 WND * WIN_FindWndPtr( HWND32 hwnd )
55 WND * ptr;
57 if (!hwnd || HIWORD(hwnd)) return NULL;
58 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
59 if (ptr->dwMagic != WND_MAGIC) return NULL;
60 if (ptr->hwndSelf != hwnd)
62 fprintf( stderr, "Can't happen: hwnd %04x self pointer is %04x\n",
63 hwnd, ptr->hwndSelf );
64 return NULL;
66 return ptr;
70 /***********************************************************************
71 * WIN_DumpWindow
73 * Dump the content of a window structure to stderr.
75 void WIN_DumpWindow( HWND32 hwnd )
77 WND *ptr;
78 char className[80];
79 int i;
81 if (!(ptr = WIN_FindWndPtr( hwnd )))
83 fprintf( stderr, "%04x is not a window handle\n", hwnd );
84 return;
87 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
88 strcpy( className, "#NULL#" );
90 fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
91 fprintf( stderr,
92 "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
93 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
94 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
95 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
96 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
97 ptr->next, ptr->child, ptr->parent, ptr->owner,
98 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
99 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
100 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
101 ptr->text ? ptr->text : "",
102 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
103 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
104 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
105 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
107 if (ptr->class->cbWndExtra)
109 fprintf( stderr, "extra bytes:" );
110 for (i = 0; i < ptr->class->cbWndExtra; i++)
111 fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
112 fprintf( stderr, "\n" );
114 fprintf( stderr, "\n" );
118 /***********************************************************************
119 * WIN_WalkWindows
121 * Walk the windows tree and print each window on stderr.
123 void WIN_WalkWindows( HWND32 hwnd, int indent )
125 WND *ptr;
126 char className[80];
128 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
129 if (!ptr)
131 fprintf( stderr, "*** Invalid window handle %04x\n", hwnd );
132 return;
135 if (!indent) /* first time around */
136 fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
137 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
139 while (ptr)
141 fprintf(stderr, "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
143 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
145 fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %08x\n",
146 (DWORD)ptr, ptr->hmemTaskQ, className,
147 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc );
149 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
150 ptr = ptr->next;
155 /***********************************************************************
156 * WIN_GetXWindow
158 * Return the X window associated to a window.
160 Window WIN_GetXWindow( HWND32 hwnd )
162 WND *wndPtr = WIN_FindWndPtr( hwnd );
163 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
164 return wndPtr ? wndPtr->window : 0;
168 /***********************************************************************
169 * WIN_UnlinkWindow
171 * Remove a window from the siblings linked list.
173 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
175 WND *wndPtr, **ppWnd;
177 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
178 ppWnd = &wndPtr->parent->child;
179 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
180 *ppWnd = wndPtr->next;
181 return TRUE;
185 /***********************************************************************
186 * WIN_LinkWindow
188 * Insert a window into the siblings linked list.
189 * The window is inserted after the specified window, which can also
190 * be specified as HWND_TOP or HWND_BOTTOM.
192 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
194 WND *wndPtr, **ppWnd;
196 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
198 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
200 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
201 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
202 while (*ppWnd) ppWnd = &(*ppWnd)->next;
204 else /* Normal case */
206 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
207 if (!afterPtr) return FALSE;
208 ppWnd = &afterPtr->next;
210 wndPtr->next = *ppWnd;
211 *ppWnd = wndPtr;
212 return TRUE;
216 /***********************************************************************
217 * WIN_FindWinToRepaint
219 * Find a window that needs repaint.
221 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
223 HWND32 hwndRet;
224 WND *pWnd = pWndDesktop;
226 /* Note: the desktop window never gets WM_PAINT messages
227 * The real reason why is because Windows DesktopWndProc
228 * does ValidateRgn inside WM_ERASEBKGND handler.
231 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
233 for ( ; pWnd ; pWnd = pWnd->next )
235 if (!(pWnd->dwStyle & WS_VISIBLE))
237 TRACE(win, "skipping window %04x\n",
238 pWnd->hwndSelf );
239 continue;
241 if ((pWnd->hmemTaskQ == hQueue) &&
242 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
244 if (pWnd->child )
245 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
246 return hwndRet;
249 if (!pWnd) return 0;
251 hwndRet = pWnd->hwndSelf;
253 /* look among siblings if we got a transparent window */
254 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
255 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
257 pWnd = pWnd->next;
259 if (pWnd) hwndRet = pWnd->hwndSelf;
260 TRACE(win,"found %04x\n",hwndRet);
261 return hwndRet;
265 /***********************************************************************
266 * WIN_DestroyWindow
268 * Destroy storage associated to a window. "Internals" p.358
270 static WND* WIN_DestroyWindow( WND* wndPtr )
272 HWND32 hwnd = wndPtr->hwndSelf;
273 WND *pWnd;
275 TRACE(win, "%04x\n", wndPtr->hwndSelf );
277 #ifdef CONFIG_IPC
278 if (main_block)
279 DDE_DestroyWindow(wndPtr->hwndSelf);
280 #endif /* CONFIG_IPC */
282 /* free child windows */
284 while ((pWnd = wndPtr->child))
285 wndPtr->child = WIN_DestroyWindow( pWnd );
287 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
289 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
291 WINPOS_CheckInternalPos( hwnd );
292 if( hwnd == GetCapture32()) ReleaseCapture();
294 /* free resources associated with the window */
296 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
297 PROPERTY_RemoveWindowProps( wndPtr );
299 wndPtr->dwMagic = 0; /* Mark it as invalid */
300 wndPtr->hwndSelf = 0;
302 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
304 if (wndPtr->hrgnUpdate > 1) DeleteObject32( wndPtr->hrgnUpdate );
305 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
308 /* toss stale messages from the queue */
310 if( wndPtr->hmemTaskQ )
312 int pos;
313 BOOL32 bPostQuit = FALSE;
314 WPARAM32 wQuitParam = 0;
315 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
317 while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
319 if( msgQ->messages[pos].msg.message == WM_QUIT )
321 bPostQuit = TRUE;
322 wQuitParam = msgQ->messages[pos].msg.wParam;
324 QUEUE_RemoveMsg(msgQ, pos);
326 /* repost WM_QUIT to make sure this app exits its message loop */
327 if( bPostQuit ) PostQuitMessage32(wQuitParam);
328 wndPtr->hmemTaskQ = 0;
331 if (!(wndPtr->dwStyle & WS_CHILD))
332 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
333 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
334 if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
335 if (wndPtr->class->style & CS_OWNDC) DCE_FreeWindowDCE( wndPtr );
337 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
339 wndPtr->class->cWindows--;
340 wndPtr->class = NULL;
341 pWnd = wndPtr->next;
343 USER_HEAP_FREE( hwnd );
344 return pWnd;
347 /***********************************************************************
348 * WIN_ResetQueueWindows
350 * Reset the queue of all the children of a given window.
351 * Return TRUE if something was done.
353 BOOL32 WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
355 BOOL32 ret = FALSE;
357 if (hNew) /* Set a new queue */
359 for (wnd = wnd->child; (wnd); wnd = wnd->next)
361 if (wnd->hmemTaskQ == hQueue)
363 wnd->hmemTaskQ = hNew;
364 ret = TRUE;
366 if (wnd->child)
367 ret |= WIN_ResetQueueWindows( wnd->child, hQueue, hNew );
370 else /* Queue is being destroyed */
372 while (wnd->child)
374 WND *tmp = wnd->child;
375 ret = FALSE;
376 while (tmp)
378 if (tmp->hmemTaskQ == hQueue)
380 DestroyWindow32( tmp->hwndSelf );
381 ret = TRUE;
382 break;
384 if (tmp->child && WIN_ResetQueueWindows(tmp->child,hQueue,0))
385 ret = TRUE;
386 else
387 tmp = tmp->next;
389 if (!ret) break;
392 return ret;
395 /***********************************************************************
396 * WIN_CreateDesktopWindow
398 * Create the desktop window.
400 BOOL32 WIN_CreateDesktopWindow(void)
402 CLASS *class;
403 HWND32 hwndDesktop;
405 TRACE(win,"Creating desktop window\n");
407 if (!ICONTITLE_Init() ||
408 !WINPOS_CreateInternalPosAtom() ||
409 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
410 return FALSE;
412 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
413 if (!hwndDesktop) return FALSE;
414 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
416 pWndDesktop->next = NULL;
417 pWndDesktop->child = NULL;
418 pWndDesktop->parent = NULL;
419 pWndDesktop->owner = NULL;
420 pWndDesktop->class = class;
421 pWndDesktop->dwMagic = WND_MAGIC;
422 pWndDesktop->hwndSelf = hwndDesktop;
423 pWndDesktop->hInstance = 0;
424 pWndDesktop->rectWindow.left = 0;
425 pWndDesktop->rectWindow.top = 0;
426 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
427 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
428 pWndDesktop->rectClient = pWndDesktop->rectWindow;
429 pWndDesktop->text = NULL;
430 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
431 pWndDesktop->hrgnUpdate = 0;
432 pWndDesktop->hwndLastActive = hwndDesktop;
433 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
434 WS_CLIPSIBLINGS;
435 pWndDesktop->dwExStyle = 0;
436 pWndDesktop->dce = NULL;
437 pWndDesktop->pVScroll = NULL;
438 pWndDesktop->pHScroll = NULL;
439 pWndDesktop->pProp = NULL;
440 pWndDesktop->wIDmenu = 0;
441 pWndDesktop->flags = 0;
442 pWndDesktop->window = rootWindow;
443 pWndDesktop->hSysMenu = 0;
444 pWndDesktop->userdata = 0;
446 pWndDesktop->winproc = (WNDPROC16)class->winproc;
448 EVENT_RegisterWindow( pWndDesktop );
449 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
450 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
451 return TRUE;
455 /***********************************************************************
456 * WIN_CreateWindowEx
458 * Implementation of CreateWindowEx().
460 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
461 BOOL32 win32, BOOL32 unicode )
463 CLASS *classPtr;
464 WND *wndPtr;
465 HWND16 hwnd, hwndLinkAfter;
466 POINT32 maxSize, maxPos, minTrack, maxTrack;
467 LRESULT (WINAPI *localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
469 TRACE(win, "%s %s %08lx %08lx %d,%d %dx%d "
470 "%04x %04x %08x %p\n", debugres(cs->lpszName),
471 debugres(cs->lpszClass), cs->dwExStyle,
472 cs->style, cs->x, cs->y, cs->cx, cs->cy,
473 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
475 /* Find the parent window */
477 if (cs->hwndParent)
479 /* Make sure parent is valid */
480 if (!IsWindow32( cs->hwndParent ))
482 fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
483 return 0;
485 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
486 fprintf( stderr, "CreateWindowEx: no parent for child window\n" );
487 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
490 /* Find the window class */
491 if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
493 char buffer[256];
494 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
495 fprintf( stderr, "CreateWindowEx: bad class '%s'\n", buffer );
496 return 0;
499 /* Fix the coordinates */
501 if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0;
502 if (cs->cx == CW_USEDEFAULT32)
504 /* if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0;
505 else */
507 cs->cx = 600;
508 cs->cy = 400;
512 /* Create the window structure */
514 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
515 - sizeof(wndPtr->wExtra) )))
517 TRACE(win, "out of memory\n" );
518 return 0;
521 /* Fill the window structure */
523 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
524 wndPtr->next = NULL;
525 wndPtr->child = NULL;
527 if ((cs->style & WS_CHILD) && cs->hwndParent)
529 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
530 wndPtr->owner = NULL;
532 else
534 wndPtr->parent = pWndDesktop;
535 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
536 wndPtr->owner = NULL;
537 else
538 wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
541 wndPtr->window = 0;
542 wndPtr->class = classPtr;
543 wndPtr->winproc = classPtr->winproc;
544 wndPtr->dwMagic = WND_MAGIC;
545 wndPtr->hwndSelf = hwnd;
546 wndPtr->hInstance = cs->hInstance;
547 wndPtr->text = NULL;
548 wndPtr->hmemTaskQ = GetTaskQueue(0);
549 wndPtr->hrgnUpdate = 0;
550 wndPtr->hwndLastActive = hwnd;
551 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
552 wndPtr->dwExStyle = cs->dwExStyle;
553 wndPtr->wIDmenu = 0;
554 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
555 wndPtr->pVScroll = NULL;
556 wndPtr->pHScroll = NULL;
557 wndPtr->pProp = NULL;
558 wndPtr->userdata = 0;
559 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
560 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
562 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
564 /* Call the WH_CBT hook */
566 hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
568 if (HOOK_IsHooked( WH_CBT ))
570 CBT_CREATEWND32A cbtc;
572 cbtc.lpcs = cs;
573 cbtc.hwndInsertAfter = hwndLinkAfter;
574 if ( HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc) )
576 TRACE(win, "CBT-hook returned 0\n");
577 USER_HEAP_FREE( hwnd );
578 return 0;
582 /* Increment class window counter */
584 classPtr->cWindows++;
586 /* Correct the window style */
588 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
590 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
591 wndPtr->flags |= WIN_NEED_SIZE;
593 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
595 /* Get class or window DC if needed */
597 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
598 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
599 else wndPtr->dce = NULL;
601 /* Insert the window in the linked list */
603 WIN_LinkWindow( hwnd, hwndLinkAfter );
605 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
607 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
609 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
610 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
611 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
612 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
613 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
616 if(cs->style & WS_CHILD)
618 if(cs->cx < 0) cs->cx = 0;
619 if(cs->cy < 0) cs->cy = 0;
621 else
623 if (cs->cx <= 0) cs->cx = 1;
624 if (cs->cy <= 0) cs->cy = 1;
627 wndPtr->rectWindow.left = cs->x;
628 wndPtr->rectWindow.top = cs->y;
629 wndPtr->rectWindow.right = cs->x + cs->cx;
630 wndPtr->rectWindow.bottom = cs->y + cs->cy;
631 wndPtr->rectClient = wndPtr->rectWindow;
633 /* Create the X window (only for top-level windows, and then only */
634 /* when there's no desktop window) */
636 if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
638 XSetWindowAttributes win_attr;
640 if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
641 (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
643 win_attr.event_mask = ExposureMask | KeyPressMask |
644 KeyReleaseMask | PointerMotionMask |
645 ButtonPressMask | ButtonReleaseMask |
646 FocusChangeMask | StructureNotifyMask;
647 win_attr.override_redirect = FALSE;
648 wndPtr->flags |= WIN_MANAGED;
650 else
652 win_attr.event_mask = ExposureMask | KeyPressMask |
653 KeyReleaseMask | PointerMotionMask |
654 ButtonPressMask | ButtonReleaseMask |
655 FocusChangeMask;
656 win_attr.override_redirect = TRUE;
658 win_attr.colormap = COLOR_GetColormap();
659 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
660 win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
661 win_attr.cursor = CURSORICON_XCursor;
662 wndPtr->window = TSXCreateWindow( display, rootWindow, cs->x, cs->y,
663 cs->cx, cs->cy, 0, CopyFromParent,
664 InputOutput, CopyFromParent,
665 CWEventMask | CWOverrideRedirect |
666 CWColormap | CWCursor | CWSaveUnder |
667 CWBackingStore, &win_attr );
669 if ((wndPtr->flags & WIN_MANAGED) &&
670 (cs->dwExStyle & WS_EX_DLGMODALFRAME))
672 XSizeHints* size_hints = TSXAllocSizeHints();
674 if (size_hints)
676 size_hints->min_width = size_hints->max_width = cs->cx;
677 size_hints->min_height = size_hints->max_height = cs->cy;
678 size_hints->flags = (PSize | PMinSize | PMaxSize);
679 TSXSetWMSizeHints( display, wndPtr->window, size_hints,
680 XA_WM_NORMAL_HINTS );
681 TSXFree(size_hints);
685 if (cs->hwndParent) /* Get window owner */
687 Window win = WIN_GetXWindow( cs->hwndParent );
688 if (win) TSXSetTransientForHint( display, wndPtr->window, win );
690 EVENT_RegisterWindow( wndPtr );
693 /* Set the window menu */
695 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
697 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
698 else
700 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
701 if (classPtr->menuNameA)
702 cs->hMenu = HIWORD(classPtr->menuNameA) ?
703 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
704 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
705 #else
706 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
707 if (menuName)
709 /* hInstance is still 16-bit in 980215 winelib */
710 if (HIWORD(cs->hInstance) || __winelib)
711 cs->hMenu = LoadMenu32A(cs->hInstance,PTR_SEG_TO_LIN(menuName));
712 else
713 /* doesn't work for winelib, since resources are unicode */
714 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
716 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
718 #endif
721 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
723 /* Send the WM_CREATE message
724 * Perhaps we shouldn't allow width/height changes as well.
725 * See p327 in "Internals".
728 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
730 localSend32 = unicode ? SendMessage32W : SendMessage32A;
731 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
733 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
734 NULL, NULL, 0, &wndPtr->rectClient );
735 OffsetRect32(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
736 maxPos.y - wndPtr->rectWindow.top);
737 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
739 /* Send the size messages */
741 if (!(wndPtr->flags & WIN_NEED_SIZE))
743 /* send it anyway */
745 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
746 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
747 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
748 SendMessage32A( hwnd, WM_MOVE, 0,
749 MAKELONG( wndPtr->rectClient.left,
750 wndPtr->rectClient.top ) );
753 /* Show the window, maximizing or minimizing if needed */
755 if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
757 RECT16 newPos;
758 UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
759 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
760 WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
761 swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow32()) ? SWP_NOACTIVATE : 0;
762 SetWindowPos32( hwnd, 0, newPos.left, newPos.top,
763 newPos.right, newPos.bottom, SWP_FRAMECHANGED | swFlag );
766 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
768 /* Notify the parent window only */
770 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
771 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
772 if( !IsWindow32(hwnd) ) return 0;
775 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
777 /* Call WH_SHELL hook */
779 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
780 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
782 TRACE(win, "created window %04x\n", hwnd);
783 return hwnd;
787 /* Abort window creation */
789 WARN(win, "aborted by WM_xxCREATE!\n");
790 WIN_UnlinkWindow( hwnd );
791 WIN_DestroyWindow( wndPtr );
792 return 0;
796 /***********************************************************************
797 * CreateWindow16 (USER.41)
799 HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
800 DWORD style, INT16 x, INT16 y, INT16 width,
801 INT16 height, HWND16 parent, HMENU16 menu,
802 HINSTANCE16 instance, LPVOID data )
804 return CreateWindowEx16( 0, className, windowName, style,
805 x, y, width, height, parent, menu, instance, data );
809 /***********************************************************************
810 * CreateWindowEx16 (USER.452)
812 HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
813 LPCSTR windowName, DWORD style, INT16 x,
814 INT16 y, INT16 width, INT16 height,
815 HWND16 parent, HMENU16 menu,
816 HINSTANCE16 instance, LPVOID data )
818 ATOM classAtom;
819 CREATESTRUCT32A cs;
821 /* Find the class atom */
823 if (!(classAtom = GlobalFindAtom32A( className )))
825 fprintf( stderr, "CreateWindowEx16: bad class name " );
826 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
827 else fprintf( stderr, "'%s'\n", className );
828 return 0;
831 /* Fix the coordinates */
833 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
834 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
835 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
836 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
838 /* Create the window */
840 cs.lpCreateParams = data;
841 cs.hInstance = (HINSTANCE32)instance;
842 cs.hMenu = (HMENU32)menu;
843 cs.hwndParent = (HWND32)parent;
844 cs.style = style;
845 cs.lpszName = windowName;
846 cs.lpszClass = className;
847 cs.dwExStyle = exStyle;
848 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
852 /***********************************************************************
853 * CreateWindowEx32A (USER32.83)
855 HWND32 WINAPI CreateWindowEx32A( DWORD exStyle, LPCSTR className,
856 LPCSTR windowName, DWORD style, INT32 x,
857 INT32 y, INT32 width, INT32 height,
858 HWND32 parent, HMENU32 menu,
859 HINSTANCE32 instance, LPVOID data )
861 ATOM classAtom;
862 CREATESTRUCT32A cs;
864 /* Find the class atom */
866 if (!(classAtom = GlobalFindAtom32A( className )))
868 fprintf( stderr, "CreateWindowEx32A: bad class name " );
869 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
870 else fprintf( stderr, "'%s'\n", className );
871 return 0;
874 /* Create the window */
876 cs.lpCreateParams = data;
877 cs.hInstance = instance;
878 cs.hMenu = menu;
879 cs.hwndParent = parent;
880 cs.x = x;
881 cs.y = y;
882 cs.cx = width;
883 cs.cy = height;
884 cs.style = style;
885 cs.lpszName = windowName;
886 cs.lpszClass = className;
887 cs.dwExStyle = exStyle;
888 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
892 /***********************************************************************
893 * CreateWindowEx32W (USER32.84)
895 HWND32 WINAPI CreateWindowEx32W( DWORD exStyle, LPCWSTR className,
896 LPCWSTR windowName, DWORD style, INT32 x,
897 INT32 y, INT32 width, INT32 height,
898 HWND32 parent, HMENU32 menu,
899 HINSTANCE32 instance, LPVOID data )
901 ATOM classAtom;
902 CREATESTRUCT32W cs;
904 /* Find the class atom */
906 if (!(classAtom = GlobalFindAtom32W( className )))
908 if (HIWORD(className))
910 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
911 fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
912 HeapFree( GetProcessHeap(), 0, cn );
914 else
915 fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
916 return 0;
919 /* Create the window */
921 cs.lpCreateParams = data;
922 cs.hInstance = instance;
923 cs.hMenu = menu;
924 cs.hwndParent = parent;
925 cs.x = x;
926 cs.y = y;
927 cs.cx = width;
928 cs.cy = height;
929 cs.style = style;
930 cs.lpszName = windowName;
931 cs.lpszClass = className;
932 cs.dwExStyle = exStyle;
933 /* Note: we rely on the fact that CREATESTRUCT32A and */
934 /* CREATESTRUCT32W have the same layout. */
935 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
939 /***********************************************************************
940 * WIN_CheckFocus
942 static void WIN_CheckFocus( WND* pWnd )
944 if( GetFocus16() == pWnd->hwndSelf )
945 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
948 /***********************************************************************
949 * WIN_SendDestroyMsg
951 static void WIN_SendDestroyMsg( WND* pWnd )
953 WIN_CheckFocus(pWnd);
955 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
956 if( !pWnd->window ) CLIPBOARD_ResetOwner( pWnd );
958 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
960 if( IsWindow32(pWnd->hwndSelf) )
962 WND* pChild = pWnd->child;
963 while( pChild )
965 WIN_SendDestroyMsg( pChild );
966 pChild = pChild->next;
968 WIN_CheckFocus(pWnd);
970 else
971 WARN(win, "\tdestroyed itself while in WM_DESTROY!\n");
975 /***********************************************************************
976 * DestroyWindow16 (USER.53)
978 BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
980 return DestroyWindow32(hwnd);
984 /***********************************************************************
985 * DestroyWindow32 (USER32.135)
987 BOOL32 WINAPI DestroyWindow32( HWND32 hwnd )
989 WND * wndPtr;
991 TRACE(win, "(%04x)\n", hwnd);
993 /* Initialization */
995 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
996 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
998 /* Call hooks */
1000 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
1001 return FALSE;
1003 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1005 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
1006 /* FIXME: clean up palette - see "Internals" p.352 */
1009 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
1010 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
1012 /* Notify the parent window only */
1013 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
1014 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
1015 if( !IsWindow32(hwnd) ) return TRUE;
1018 if( wndPtr->window ) CLIPBOARD_ResetOwner( wndPtr ); /* before the window is unmapped */
1020 /* Hide the window */
1022 if (wndPtr->dwStyle & WS_VISIBLE)
1024 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
1025 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
1026 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
1027 if (!IsWindow32(hwnd)) return TRUE;
1030 /* Recursively destroy owned windows */
1032 if( !(wndPtr->dwStyle & WS_CHILD) )
1034 /* make sure top menu popup doesn't get destroyed */
1035 MENU_PatchResidentPopup( (HQUEUE16)0xFFFF, wndPtr );
1037 for (;;)
1039 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1040 while (siblingPtr)
1042 if (siblingPtr->owner == wndPtr)
1043 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1044 break;
1045 else
1046 siblingPtr->owner = NULL;
1047 siblingPtr = siblingPtr->next;
1049 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1050 else break;
1053 if( !Options.managed || EVENT_CheckFocus() )
1054 WINPOS_ActivateOtherWindow(wndPtr);
1056 if( wndPtr->owner &&
1057 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1058 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1061 /* Send destroy messages */
1063 WIN_SendDestroyMsg( wndPtr );
1064 if (!IsWindow32(hwnd)) return TRUE;
1066 /* Unlink now so we won't bother with the children later on */
1068 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1070 /* Destroy the window storage */
1072 WIN_DestroyWindow( wndPtr );
1073 return TRUE;
1077 /***********************************************************************
1078 * CloseWindow16 (USER.43)
1080 BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
1082 return CloseWindow32( hwnd );
1086 /***********************************************************************
1087 * CloseWindow32 (USER32.56)
1089 BOOL32 WINAPI CloseWindow32( HWND32 hwnd )
1091 WND * wndPtr = WIN_FindWndPtr( hwnd );
1092 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1093 ShowWindow32( hwnd, SW_MINIMIZE );
1094 return TRUE;
1098 /***********************************************************************
1099 * OpenIcon16 (USER.44)
1101 BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
1103 return OpenIcon32( hwnd );
1107 /***********************************************************************
1108 * OpenIcon32 (USER32.410)
1110 BOOL32 WINAPI OpenIcon32( HWND32 hwnd )
1112 if (!IsIconic32( hwnd )) return FALSE;
1113 ShowWindow32( hwnd, SW_SHOWNORMAL );
1114 return TRUE;
1118 /***********************************************************************
1119 * WIN_FindWindow
1121 * Implementation of FindWindow() and FindWindowEx().
1123 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1124 LPCSTR title )
1126 WND *pWnd;
1127 CLASS *pClass = NULL;
1129 if (child)
1131 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1132 if (parent)
1134 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1136 else if (pWnd->parent != pWndDesktop) return 0;
1137 pWnd = pWnd->next;
1139 else
1141 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1142 pWnd = pWnd->child;
1144 if (!pWnd) return 0;
1146 /* For a child window, all siblings will have the same hInstance, */
1147 /* so we can look for the class once and for all. */
1149 if (className && (pWnd->dwStyle & WS_CHILD))
1151 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1152 return 0;
1156 for ( ; pWnd; pWnd = pWnd->next)
1158 if (className && !(pWnd->dwStyle & WS_CHILD))
1160 if (!(pClass = CLASS_FindClassByAtom( className, GetExePtr(pWnd->hInstance))))
1161 continue; /* Skip this window */
1164 if (pClass && (pWnd->class != pClass))
1165 continue; /* Not the right class */
1167 /* Now check the title */
1169 if (!title) return pWnd->hwndSelf;
1170 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1172 return 0;
1177 /***********************************************************************
1178 * FindWindow16 (USER.50)
1180 HWND16 WINAPI FindWindow16( SEGPTR className, LPCSTR title )
1182 return FindWindowEx16( 0, 0, className, title );
1186 /***********************************************************************
1187 * FindWindowEx16 (USER.427)
1189 HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child,
1190 SEGPTR className, LPCSTR title )
1192 ATOM atom = 0;
1194 TRACE(win, "%04x %04x '%s' '%s'\n", parent,
1195 child, HIWORD(className)?(char *)PTR_SEG_TO_LIN(className):"",
1196 title ? title : "");
1198 if (className)
1200 /* If the atom doesn't exist, then no class */
1201 /* with this name exists either. */
1202 if (!(atom = GlobalFindAtom16( className ))) return 0;
1204 return WIN_FindWindow( parent, child, atom, title );
1208 /***********************************************************************
1209 * FindWindow32A (USER32.198)
1211 HWND32 WINAPI FindWindow32A( LPCSTR className, LPCSTR title )
1213 return FindWindowEx32A( 0, 0, className, title );
1217 /***********************************************************************
1218 * FindWindowEx32A (USER32.199)
1220 HWND32 WINAPI FindWindowEx32A( HWND32 parent, HWND32 child,
1221 LPCSTR className, LPCSTR title )
1223 ATOM atom = 0;
1225 if (className)
1227 /* If the atom doesn't exist, then no class */
1228 /* with this name exists either. */
1229 if (!(atom = GlobalFindAtom32A( className ))) return 0;
1231 return WIN_FindWindow( parent, child, atom, title );
1235 /***********************************************************************
1236 * FindWindowEx32W (USER32.200)
1238 HWND32 WINAPI FindWindowEx32W( HWND32 parent, HWND32 child,
1239 LPCWSTR className, LPCWSTR title )
1241 ATOM atom = 0;
1242 char *buffer;
1243 HWND32 hwnd;
1245 if (className)
1247 /* If the atom doesn't exist, then no class */
1248 /* with this name exists either. */
1249 if (!(atom = GlobalFindAtom32W( className ))) return 0;
1251 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1252 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1253 HeapFree( GetProcessHeap(), 0, buffer );
1254 return hwnd;
1258 /***********************************************************************
1259 * FindWindow32W (USER32.201)
1261 HWND32 WINAPI FindWindow32W( LPCWSTR className, LPCWSTR title )
1263 return FindWindowEx32W( 0, 0, className, title );
1267 /**********************************************************************
1268 * WIN_GetDesktop
1270 WND *WIN_GetDesktop(void)
1272 return pWndDesktop;
1276 /**********************************************************************
1277 * GetDesktopWindow16 (USER.286)
1279 HWND16 WINAPI GetDesktopWindow16(void)
1281 return (HWND16)pWndDesktop->hwndSelf;
1285 /**********************************************************************
1286 * GetDesktopWindow32 (USER32.232)
1288 HWND32 WINAPI GetDesktopWindow32(void)
1290 return pWndDesktop->hwndSelf;
1294 /**********************************************************************
1295 * GetDesktopHwnd (USER.278)
1297 * Exactly the same thing as GetDesktopWindow(), but not documented.
1298 * Don't ask me why...
1300 HWND16 WINAPI GetDesktopHwnd(void)
1302 return (HWND16)pWndDesktop->hwndSelf;
1306 /*******************************************************************
1307 * EnableWindow16 (USER.34)
1309 BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
1311 return EnableWindow32( hwnd, enable );
1315 /*******************************************************************
1316 * EnableWindow32 (USER32.172)
1318 BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
1320 WND *wndPtr;
1322 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1323 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1325 /* Enable window */
1326 wndPtr->dwStyle &= ~WS_DISABLED;
1327 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1328 return TRUE;
1330 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1332 /* Disable window */
1333 wndPtr->dwStyle |= WS_DISABLED;
1334 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1335 SetFocus32( 0 ); /* A disabled window can't have the focus */
1336 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1337 ReleaseCapture(); /* A disabled window can't capture the mouse */
1338 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1339 return FALSE;
1341 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1345 /***********************************************************************
1346 * IsWindowEnabled16 (USER.35)
1348 BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
1350 return IsWindowEnabled32(hWnd);
1354 /***********************************************************************
1355 * IsWindowEnabled32 (USER32.349)
1357 BOOL32 WINAPI IsWindowEnabled32(HWND32 hWnd)
1359 WND * wndPtr;
1361 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1362 return !(wndPtr->dwStyle & WS_DISABLED);
1366 /***********************************************************************
1367 * IsWindowUnicode (USER32.350)
1369 BOOL32 WINAPI IsWindowUnicode( HWND32 hwnd )
1371 WND * wndPtr;
1373 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1374 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1378 /**********************************************************************
1379 * GetWindowWord16 (USER.133)
1381 WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
1383 return GetWindowWord32( hwnd, offset );
1387 /**********************************************************************
1388 * GetWindowWord32 (USER32.314)
1390 WORD WINAPI GetWindowWord32( HWND32 hwnd, INT32 offset )
1392 WND * wndPtr = WIN_FindWndPtr( hwnd );
1393 if (!wndPtr) return 0;
1394 if (offset >= 0)
1396 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1398 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1399 return 0;
1401 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1403 switch(offset)
1405 case GWW_ID:
1406 if (HIWORD(wndPtr->wIDmenu))
1407 fprintf(stderr,"GetWindowWord32(GWW_ID) discards high bits of 0x%08x!\n",wndPtr->wIDmenu);
1408 return (WORD)wndPtr->wIDmenu;
1409 case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
1410 case GWW_HINSTANCE:
1411 if (HIWORD(wndPtr->hInstance))
1412 fprintf(stderr,"GetWindowWord32(GWW_HINSTANCE) discards high bits of 0x%08x!\n",wndPtr->hInstance);
1413 return (WORD)wndPtr->hInstance;
1414 default:
1415 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1416 return 0;
1421 /**********************************************************************
1422 * WIN_GetWindowInstance
1424 HINSTANCE32 WIN_GetWindowInstance( HWND32 hwnd )
1426 WND * wndPtr = WIN_FindWndPtr( hwnd );
1427 if (!wndPtr) return (HINSTANCE32)0;
1428 return wndPtr->hInstance;
1432 /**********************************************************************
1433 * SetWindowWord16 (USER.134)
1435 WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1437 return SetWindowWord32( hwnd, offset, newval );
1441 /**********************************************************************
1442 * SetWindowWord32 (USER32.524)
1444 WORD WINAPI SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1446 WORD *ptr, retval;
1447 WND * wndPtr = WIN_FindWndPtr( hwnd );
1448 if (!wndPtr) return 0;
1449 if (offset >= 0)
1451 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1453 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1454 return 0;
1456 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1458 else switch(offset)
1460 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1461 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1462 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1463 default:
1464 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1465 return 0;
1467 retval = *ptr;
1468 *ptr = newval;
1469 return retval;
1473 /**********************************************************************
1474 * WIN_GetWindowLong
1476 * Helper function for GetWindowLong().
1478 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1480 LONG retval;
1481 WND * wndPtr = WIN_FindWndPtr( hwnd );
1482 if (!wndPtr) return 0;
1483 if (offset >= 0)
1485 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1487 fprintf( stderr, "GetWindowLong: invalid offset %d\n", offset );
1488 return 0;
1490 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1491 /* Special case for dialog window procedure */
1492 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1493 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1494 return retval;
1496 switch(offset)
1498 case GWL_USERDATA: return wndPtr->userdata;
1499 case GWL_STYLE: return wndPtr->dwStyle;
1500 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1501 case GWL_ID: return (LONG)wndPtr->wIDmenu;
1502 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1503 type );
1504 case GWL_HWNDPARENT: return wndPtr->parent ?
1505 (HWND32)wndPtr->parent->hwndSelf : 0;
1506 case GWL_HINSTANCE: return wndPtr->hInstance;
1507 default:
1508 fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
1510 return 0;
1514 /**********************************************************************
1515 * WIN_SetWindowLong
1517 * Helper function for SetWindowLong().
1519 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1520 WINDOWPROCTYPE type )
1522 LONG *ptr, retval;
1523 WND * wndPtr = WIN_FindWndPtr( hwnd );
1525 if (!wndPtr) return 0;
1526 if (offset >= 0)
1528 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1530 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1531 return 0;
1533 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1534 /* Special case for dialog window procedure */
1535 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1537 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1538 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1539 type, WIN_PROC_WINDOW );
1540 return retval;
1543 else switch(offset)
1545 case GWL_ID:
1546 ptr = (DWORD*)&wndPtr->wIDmenu;
1547 break;
1548 case GWL_HINSTANCE:
1549 return SetWindowWord32( hwnd, offset, newval );
1550 case GWL_WNDPROC:
1551 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1552 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1553 type, WIN_PROC_WINDOW );
1554 return retval;
1555 case GWL_STYLE:
1557 /* FIXME: WM_STYLE... messages for WIN_ISWIN32 windows */
1559 ptr = &wndPtr->dwStyle;
1560 /* Some bits can't be changed this way */
1561 newval &= ~(WS_VISIBLE | WS_CHILD);
1562 newval |= (*ptr & (WS_VISIBLE | WS_CHILD));
1563 break;
1564 case GWL_USERDATA: ptr = &wndPtr->userdata; break;
1565 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
1566 default:
1567 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1568 return 0;
1570 retval = *ptr;
1571 *ptr = newval;
1572 return retval;
1576 /**********************************************************************
1577 * GetWindowLong16 (USER.135)
1579 LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
1581 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1585 /**********************************************************************
1586 * GetWindowLong32A (USER32.305)
1588 LONG WINAPI GetWindowLong32A( HWND32 hwnd, INT32 offset )
1590 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1594 /**********************************************************************
1595 * GetWindowLong32W (USER32.306)
1597 LONG WINAPI GetWindowLong32W( HWND32 hwnd, INT32 offset )
1599 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1603 /**********************************************************************
1604 * SetWindowLong16 (USER.136)
1606 LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1608 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1612 /**********************************************************************
1613 * SetWindowLong32A (USER32.517)
1615 LONG WINAPI SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1617 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1621 /**********************************************************************
1622 * SetWindowLong32W (USER32.518)
1624 LONG WINAPI SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
1626 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1630 /*******************************************************************
1631 * GetWindowText16 (USER.36)
1633 INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1635 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1639 /*******************************************************************
1640 * GetWindowText32A (USER32.309)
1642 INT32 WINAPI GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1644 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1645 (LPARAM)lpString );
1649 /*******************************************************************
1650 * GetWindowText32W (USER32.312)
1652 INT32 WINAPI GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1654 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1655 (LPARAM)lpString );
1659 /*******************************************************************
1660 * SetWindowText16 (USER.37)
1662 void WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1664 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1668 /*******************************************************************
1669 * SetWindowText32A (USER32.521)
1671 void WINAPI SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1673 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1677 /*******************************************************************
1678 * SetWindowText32W (USER32.523)
1680 void WINAPI SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1682 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1686 /*******************************************************************
1687 * GetWindowTextLength16 (USER.38)
1689 INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
1691 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1695 /*******************************************************************
1696 * GetWindowTextLength32A (USER32.310)
1698 INT32 WINAPI GetWindowTextLength32A( HWND32 hwnd )
1700 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1703 /*******************************************************************
1704 * GetWindowTextLength32W (USER32.311)
1706 INT32 WINAPI GetWindowTextLength32W( HWND32 hwnd )
1708 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1712 /*******************************************************************
1713 * IsWindow16 (USER.47)
1715 BOOL16 WINAPI IsWindow16( HWND16 hwnd )
1717 return IsWindow32( hwnd );
1721 /*******************************************************************
1722 * IsWindow32 (USER32.348)
1724 BOOL32 WINAPI IsWindow32( HWND32 hwnd )
1726 WND * wndPtr = WIN_FindWndPtr( hwnd );
1727 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1731 /*****************************************************************
1732 * GetParent16 (USER.46)
1734 HWND16 WINAPI GetParent16( HWND16 hwnd )
1736 return (HWND16)GetParent32( hwnd );
1740 /*****************************************************************
1741 * GetParent32 (USER32.278)
1743 HWND32 WINAPI GetParent32( HWND32 hwnd )
1745 WND *wndPtr = WIN_FindWndPtr(hwnd);
1746 if ((!wndPtr) || (!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD)))) return 0;
1747 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1748 return wndPtr ? wndPtr->hwndSelf : 0;
1751 /*****************************************************************
1752 * WIN_GetTopParent
1754 * Get the top-level parent for a child window.
1756 WND* WIN_GetTopParentPtr( WND* pWnd )
1758 while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
1759 return pWnd;
1762 /*****************************************************************
1763 * WIN_GetTopParent
1765 * Get the top-level parent for a child window.
1767 HWND32 WIN_GetTopParent( HWND32 hwnd )
1769 WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
1770 return wndPtr ? wndPtr->hwndSelf : 0;
1774 /*****************************************************************
1775 * SetParent16 (USER.233)
1777 HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1779 return SetParent32( hwndChild, hwndNewParent );
1783 /*****************************************************************
1784 * SetParent32 (USER32.495)
1786 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1788 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1789 WND *pWndParent = (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent )
1790 : pWndDesktop;
1792 if( wndPtr && pWndParent && (wndPtr != pWndDesktop) )
1794 WND* pWndPrev = wndPtr->parent;
1796 if( pWndParent != pWndPrev )
1798 BOOL32 bFixupDCE = IsWindowVisible32(hwndChild);
1800 if ( wndPtr->window )
1802 /* Toplevel window needs to be reparented. Used by Tk 8.0 */
1804 TSXDestroyWindow( display, wndPtr->window );
1805 wndPtr->window = None;
1807 else if( bFixupDCE )
1808 DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
1810 WIN_UnlinkWindow(hwndChild);
1811 wndPtr->parent = pWndParent;
1813 /* FIXME: Create an X counterpart for reparented top-level windows
1814 * when not in the desktop mode. */
1816 if ( pWndParent == pWndDesktop )
1817 wndPtr->dwStyle &= ~WS_CHILD;
1818 else wndPtr->dwStyle |= WS_CHILD;
1819 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
1821 if( bFixupDCE )
1823 DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
1824 UpdateWindow32(hwndChild);
1827 return pWndPrev->hwndSelf;
1828 } /* failure */
1829 return 0;
1833 /*******************************************************************
1834 * IsChild16 (USER.48)
1836 BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
1838 return IsChild32(parent,child);
1842 /*******************************************************************
1843 * IsChild32 (USER32.339)
1845 BOOL32 WINAPI IsChild32( HWND32 parent, HWND32 child )
1847 WND * wndPtr = WIN_FindWndPtr( child );
1848 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1850 wndPtr = wndPtr->parent;
1851 if (wndPtr->hwndSelf == parent) return TRUE;
1853 return FALSE;
1857 /***********************************************************************
1858 * IsWindowVisible16 (USER.49)
1860 BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
1862 return IsWindowVisible32(hwnd);
1866 /***********************************************************************
1867 * IsWindowVisible32 (USER32.351)
1869 BOOL32 WINAPI IsWindowVisible32( HWND32 hwnd )
1871 WND *wndPtr = WIN_FindWndPtr( hwnd );
1872 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1874 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1875 wndPtr = wndPtr->parent;
1877 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1881 /***********************************************************************
1882 * WIN_IsWindowDrawable
1884 * hwnd is drawable when it is visible, all parents are not
1885 * minimized, and it is itself not minimized unless we are
1886 * trying to draw its default class icon.
1888 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
1890 if( (wnd->dwStyle & WS_MINIMIZE &&
1891 icon && wnd->class->hIcon) ||
1892 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
1893 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
1894 if( wnd->dwStyle & WS_MINIMIZE ||
1895 !(wnd->dwStyle & WS_VISIBLE) ) break;
1896 return (wnd == NULL);
1900 /*******************************************************************
1901 * GetTopWindow16 (USER.229)
1903 HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
1905 return GetTopWindow32(hwnd);
1909 /*******************************************************************
1910 * GetTopWindow32 (USER.229)
1912 HWND32 WINAPI GetTopWindow32( HWND32 hwnd )
1914 WND * wndPtr = WIN_FindWndPtr( hwnd );
1915 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1916 else return 0;
1920 /*******************************************************************
1921 * GetWindow16 (USER.262)
1923 HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
1925 return GetWindow32( hwnd,rel );
1929 /*******************************************************************
1930 * GetWindow32 (USER32.302)
1932 HWND32 WINAPI GetWindow32( HWND32 hwnd, WORD rel )
1934 WND * wndPtr = WIN_FindWndPtr( hwnd );
1935 if (!wndPtr) return 0;
1936 switch(rel)
1938 case GW_HWNDFIRST:
1939 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
1940 else return 0;
1942 case GW_HWNDLAST:
1943 if (!wndPtr->parent) return 0; /* Desktop window */
1944 while (wndPtr->next) wndPtr = wndPtr->next;
1945 return wndPtr->hwndSelf;
1947 case GW_HWNDNEXT:
1948 if (!wndPtr->next) return 0;
1949 return wndPtr->next->hwndSelf;
1951 case GW_HWNDPREV:
1952 if (!wndPtr->parent) return 0; /* Desktop window */
1953 wndPtr = wndPtr->parent->child; /* First sibling */
1954 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
1955 while (wndPtr->next)
1957 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
1958 wndPtr = wndPtr->next;
1960 return 0;
1962 case GW_OWNER:
1963 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
1965 case GW_CHILD:
1966 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
1968 return 0;
1972 /*******************************************************************
1973 * GetNextWindow16 (USER.230)
1975 HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
1977 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1978 return GetWindow16( hwnd, flag );
1981 /*******************************************************************
1982 * ShowOwnedPopups16 (USER.265)
1984 void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
1986 ShowOwnedPopups32( owner, fShow );
1990 /*******************************************************************
1991 * ShowOwnedPopups32 (USER32.531)
1993 BOOL32 WINAPI ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
1995 WND *pWnd = pWndDesktop->child;
1996 while (pWnd)
1998 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
1999 (pWnd->dwStyle & WS_POPUP))
2000 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
2001 pWnd = pWnd->next;
2003 return TRUE;
2007 /*******************************************************************
2008 * GetLastActivePopup16 (USER.287)
2010 HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
2012 return GetLastActivePopup32( hwnd );
2015 /*******************************************************************
2016 * GetLastActivePopup32 (USER32.256)
2018 HWND32 WINAPI GetLastActivePopup32( HWND32 hwnd )
2020 WND *wndPtr;
2021 wndPtr = WIN_FindWndPtr(hwnd);
2022 if (wndPtr == NULL) return hwnd;
2023 return wndPtr->hwndLastActive;
2027 /*******************************************************************
2028 * WIN_BuildWinArray
2030 * Build an array of pointers to the children of a given window.
2031 * The array must be freed with HeapFree(SystemHeap). Return NULL
2032 * when no windows are found.
2034 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
2036 WND **list, **ppWnd;
2037 WND *pWnd;
2038 UINT32 count, skipOwned, skipHidden;
2039 DWORD skipFlags;
2041 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2042 skipOwned = bwaFlags & BWA_SKIPOWNED;
2043 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2044 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
2046 /* First count the windows */
2048 if (!wndPtr) wndPtr = pWndDesktop;
2049 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
2051 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2052 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
2055 if( count )
2057 /* Now build the list of all windows */
2059 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
2061 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
2063 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2064 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2066 *ppWnd++ = pWnd;
2067 count++;
2070 *ppWnd = NULL;
2072 else count = 0;
2073 } else list = NULL;
2075 if( pTotal ) *pTotal = count;
2076 return list;
2080 /*******************************************************************
2081 * EnumWindows16 (USER.54)
2083 BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2085 WND **list, **ppWnd;
2087 /* We have to build a list of all windows first, to avoid */
2088 /* unpleasant side-effects, for instance if the callback */
2089 /* function changes the Z-order of the windows. */
2091 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2093 /* Now call the callback function for every window */
2095 for (ppWnd = list; *ppWnd; ppWnd++)
2097 /* Make sure that the window still exists */
2098 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2099 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2101 HeapFree( SystemHeap, 0, list );
2102 return TRUE;
2106 /*******************************************************************
2107 * EnumWindows32 (USER32.193)
2109 BOOL32 WINAPI EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2111 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2115 /**********************************************************************
2116 * EnumTaskWindows16 (USER.225)
2118 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2119 LPARAM lParam )
2121 WND **list, **ppWnd;
2122 HQUEUE16 hQueue = GetTaskQueue( hTask );
2124 /* This function is the same as EnumWindows(), */
2125 /* except for an added check on the window queue. */
2127 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2129 /* Now call the callback function for every window */
2131 for (ppWnd = list; *ppWnd; ppWnd++)
2133 /* Make sure that the window still exists */
2134 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2135 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
2136 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2138 HeapFree( SystemHeap, 0, list );
2139 return TRUE;
2143 /**********************************************************************
2144 * EnumThreadWindows (USER32.190)
2146 BOOL32 WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2148 THDB *tdb = THREAD_ID_TO_THDB(id);
2150 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2154 /**********************************************************************
2155 * WIN_EnumChildWindows
2157 * Helper function for EnumChildWindows().
2159 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2160 LPARAM lParam )
2162 WND **childList;
2163 BOOL16 ret = FALSE;
2165 for ( ; *ppWnd; ppWnd++)
2167 /* Make sure that the window still exists */
2168 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2169 /* Build children list first */
2170 if (!(childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL )))
2171 return FALSE;
2172 if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
2173 ret = WIN_EnumChildWindows( childList, func, lParam );
2174 HeapFree( SystemHeap, 0, childList );
2175 if (!ret) return FALSE;
2177 return TRUE;
2181 /**********************************************************************
2182 * EnumChildWindows16 (USER.55)
2184 BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2185 LPARAM lParam )
2187 WND **list, *pParent;
2189 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2190 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2191 WIN_EnumChildWindows( list, func, lParam );
2192 HeapFree( SystemHeap, 0, list );
2193 return TRUE;
2197 /**********************************************************************
2198 * EnumChildWindows32 (USER32.178)
2200 BOOL32 WINAPI EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
2201 LPARAM lParam )
2203 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2204 lParam );
2208 /*******************************************************************
2209 * AnyPopup16 (USER.52)
2211 BOOL16 WINAPI AnyPopup16(void)
2213 return AnyPopup32();
2217 /*******************************************************************
2218 * AnyPopup32 (USER32.4)
2220 BOOL32 WINAPI AnyPopup32(void)
2222 WND *wndPtr;
2223 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2224 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2225 return FALSE;
2229 /*******************************************************************
2230 * FlashWindow16 (USER.105)
2232 BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2234 return FlashWindow32( hWnd, bInvert );
2238 /*******************************************************************
2239 * FlashWindow32 (USER32.202)
2241 BOOL32 WINAPI FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2243 WND *wndPtr = WIN_FindWndPtr(hWnd);
2245 TRACE(win,"%04x\n", hWnd);
2247 if (!wndPtr) return FALSE;
2249 if (wndPtr->dwStyle & WS_MINIMIZE)
2251 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2253 HDC32 hDC = GetDC32(hWnd);
2255 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2256 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2258 ReleaseDC32( hWnd, hDC );
2259 wndPtr->flags |= WIN_NCACTIVATED;
2261 else
2263 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2264 RDW_UPDATENOW | RDW_FRAME, 0 );
2265 wndPtr->flags &= ~WIN_NCACTIVATED;
2267 return TRUE;
2269 else
2271 WPARAM16 wparam;
2272 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2273 else wparam = (hWnd == GetActiveWindow32());
2275 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2276 return wparam;
2281 /*******************************************************************
2282 * SetSysModalWindow16 (USER.188)
2284 HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
2286 HWND32 hWndOldModal = hwndSysModal;
2287 hwndSysModal = hWnd;
2288 FIXME(win, "EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2289 return hWndOldModal;
2293 /*******************************************************************
2294 * GetSysModalWindow16 (USER.52)
2296 HWND16 WINAPI GetSysModalWindow16(void)
2298 return hwndSysModal;
2302 /*******************************************************************
2303 * DRAG_QueryUpdate
2305 * recursively find a child that contains spDragInfo->pt point
2306 * and send WM_QUERYDROPOBJECT
2308 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2310 BOOL16 wParam,bResult = 0;
2311 POINT32 pt;
2312 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2313 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2314 RECT32 tempRect;
2316 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2318 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2320 GetWindowRect32(hQueryWnd,&tempRect);
2322 if( !PtInRect32(&tempRect,pt) ||
2323 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2324 return 0;
2326 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2328 tempRect = ptrQueryWnd->rectClient;
2329 if(ptrQueryWnd->dwStyle & WS_CHILD)
2330 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2331 (LPPOINT32)&tempRect, 2 );
2333 if (PtInRect32( &tempRect, pt))
2335 wParam = 0;
2337 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2338 if( ptrWnd->dwStyle & WS_VISIBLE )
2340 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2341 if (PtInRect32( &tempRect, pt )) break;
2344 if(ptrWnd)
2346 TRACE(msg,"hwnd = %04x, %d %d - %d %d\n",
2347 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2348 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2349 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2350 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2353 if(bResult) return bResult;
2355 else wParam = 1;
2357 else wParam = 1;
2359 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2361 ptrDragInfo->hScope = hQueryWnd;
2363 bResult = ( bNoSend )
2364 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2365 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2366 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2367 if( !bResult )
2368 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2370 return bResult;
2374 /*******************************************************************
2375 * DragDetect (USER.465)
2377 BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
2379 POINT32 pt32;
2380 CONV_POINT16TO32( &pt, &pt32 );
2381 return DragDetect32( hWnd, pt32 );
2384 /*******************************************************************
2385 * DragDetect32 (USER32.151)
2387 BOOL32 WINAPI DragDetect32( HWND32 hWnd, POINT32 pt )
2389 MSG16 msg;
2390 RECT16 rect;
2392 rect.left = pt.x - wDragWidth;
2393 rect.right = pt.x + wDragWidth;
2395 rect.top = pt.y - wDragHeight;
2396 rect.bottom = pt.y + wDragHeight;
2398 SetCapture32(hWnd);
2400 while(1)
2402 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2404 if( msg.message == WM_LBUTTONUP )
2406 ReleaseCapture();
2407 return 0;
2409 if( msg.message == WM_MOUSEMOVE )
2411 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2413 ReleaseCapture();
2414 return 1;
2418 WaitMessage();
2420 return 0;
2423 /******************************************************************************
2424 * DragObject16 (USER.464)
2426 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2427 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2429 MSG16 msg;
2430 LPDRAGINFO lpDragInfo;
2431 SEGPTR spDragInfo;
2432 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2433 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2434 WND *wndPtr = WIN_FindWndPtr(hWnd);
2435 HCURSOR16 hCurrentCursor = 0;
2436 HWND16 hCurrentWnd = 0;
2438 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2439 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2441 if( !lpDragInfo || !spDragInfo ) return 0L;
2443 hBummer = LoadCursor16(0, IDC_BUMMER);
2445 if( !hBummer || !wndPtr )
2447 GlobalFree16(hDragInfo);
2448 return 0L;
2451 if(hCursor)
2453 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2455 GlobalFree16(hDragInfo);
2456 return 0L;
2459 if( hDragCursor == hCursor ) hDragCursor = 0;
2460 else hCursor = hDragCursor;
2462 hOldCursor = SetCursor32(hDragCursor);
2465 lpDragInfo->hWnd = hWnd;
2466 lpDragInfo->hScope = 0;
2467 lpDragInfo->wFlags = wObj;
2468 lpDragInfo->hList = szList; /* near pointer! */
2469 lpDragInfo->hOfStruct = hOfStruct;
2470 lpDragInfo->l = 0L;
2472 SetCapture32(hWnd);
2473 ShowCursor32( TRUE );
2477 do{ WaitMessage(); }
2478 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2480 *(lpDragInfo+1) = *lpDragInfo;
2482 lpDragInfo->pt = msg.pt;
2484 /* update DRAGINFO struct */
2485 TRACE(msg,"lpDI->hScope = %04x\n",lpDragInfo->hScope);
2487 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2488 hCurrentCursor = hCursor;
2489 else
2491 hCurrentCursor = hBummer;
2492 lpDragInfo->hScope = 0;
2494 if( hCurrentCursor )
2495 SetCursor32(hCurrentCursor);
2497 /* send WM_DRAGLOOP */
2498 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2499 (LPARAM) spDragInfo );
2500 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2501 if( hCurrentWnd != lpDragInfo->hScope )
2503 if( hCurrentWnd )
2504 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2505 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2506 HIWORD(spDragInfo)) );
2507 hCurrentWnd = lpDragInfo->hScope;
2508 if( hCurrentWnd )
2509 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2511 else
2512 if( hCurrentWnd )
2513 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2515 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2517 ReleaseCapture();
2518 ShowCursor32( FALSE );
2520 if( hCursor )
2522 SetCursor32( hOldCursor );
2523 if (hDragCursor) DestroyCursor32( hDragCursor );
2526 if( hCurrentCursor != hBummer )
2527 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2528 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2529 else
2530 msg.lParam = 0;
2531 GlobalFree16(hDragInfo);
2533 return (DWORD)(msg.lParam);