Release 980201
[wine/multimedia.git] / windows / win.c
blob74b55eab5b737f7e664b37f2b3e479d1f1d4be3a
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 "stddebug.h"
34 /* #define DEBUG_WIN */
35 /* #define DEBUG_MENU */
36 #include "debug.h"
38 /* Desktop window */
39 static WND *pWndDesktop = NULL;
41 static HWND32 hwndSysModal = 0;
43 static WORD wDragWidth = 4;
44 static WORD wDragHeight= 3;
46 extern BOOL32 ICONTITLE_Init(void);
47 extern BOOL32 MENU_PatchResidentPopup( HQUEUE16, WND* );
48 extern HWND32 CARET_GetHwnd(void);
49 extern BOOL32 EVENT_CheckFocus(void);
51 /***********************************************************************
52 * WIN_FindWndPtr
54 * Return a pointer to the WND structure corresponding to a HWND.
56 WND * WIN_FindWndPtr( HWND32 hwnd )
58 WND * ptr;
60 if (!hwnd || HIWORD(hwnd)) return NULL;
61 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
62 if (ptr->dwMagic != WND_MAGIC) return NULL;
63 if (ptr->hwndSelf != hwnd)
65 fprintf( stderr, "Can't happen: hwnd %04x self pointer is %04x\n",
66 hwnd, ptr->hwndSelf );
67 return NULL;
69 return ptr;
73 /***********************************************************************
74 * WIN_DumpWindow
76 * Dump the content of a window structure to stderr.
78 void WIN_DumpWindow( HWND32 hwnd )
80 WND *ptr;
81 char className[80];
82 int i;
84 if (!(ptr = WIN_FindWndPtr( hwnd )))
86 fprintf( stderr, "%04x is not a window handle\n", hwnd );
87 return;
90 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
91 strcpy( className, "#NULL#" );
93 fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
94 fprintf( stderr,
95 "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
96 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
97 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
98 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
99 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
100 ptr->next, ptr->child, ptr->parent, ptr->owner,
101 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
102 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
103 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
104 ptr->text ? ptr->text : "",
105 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
106 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
107 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
108 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
110 if (ptr->class->cbWndExtra)
112 fprintf( stderr, "extra bytes:" );
113 for (i = 0; i < ptr->class->cbWndExtra; i++)
114 fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
115 fprintf( stderr, "\n" );
117 fprintf( stderr, "\n" );
121 /***********************************************************************
122 * WIN_WalkWindows
124 * Walk the windows tree and print each window on stderr.
126 void WIN_WalkWindows( HWND32 hwnd, int indent )
128 WND *ptr;
129 char className[80];
131 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
132 if (!ptr)
134 fprintf( stderr, "*** Invalid window handle %04x\n", hwnd );
135 return;
138 if (!indent) /* first time around */
139 fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
140 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
142 while (ptr)
144 fprintf(stderr, "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
146 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
148 fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %08x\n",
149 (DWORD)ptr, ptr->hmemTaskQ, className,
150 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc );
152 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
153 ptr = ptr->next;
158 /***********************************************************************
159 * WIN_GetXWindow
161 * Return the X window associated to a window.
163 Window WIN_GetXWindow( HWND32 hwnd )
165 WND *wndPtr = WIN_FindWndPtr( hwnd );
166 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
167 return wndPtr ? wndPtr->window : 0;
171 /***********************************************************************
172 * WIN_UnlinkWindow
174 * Remove a window from the siblings linked list.
176 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
178 WND *wndPtr, **ppWnd;
180 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
181 ppWnd = &wndPtr->parent->child;
182 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
183 *ppWnd = wndPtr->next;
184 return TRUE;
188 /***********************************************************************
189 * WIN_LinkWindow
191 * Insert a window into the siblings linked list.
192 * The window is inserted after the specified window, which can also
193 * be specified as HWND_TOP or HWND_BOTTOM.
195 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
197 WND *wndPtr, **ppWnd;
199 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
201 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
203 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
204 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
205 while (*ppWnd) ppWnd = &(*ppWnd)->next;
207 else /* Normal case */
209 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
210 if (!afterPtr) return FALSE;
211 ppWnd = &afterPtr->next;
213 wndPtr->next = *ppWnd;
214 *ppWnd = wndPtr;
215 return TRUE;
219 /***********************************************************************
220 * WIN_FindWinToRepaint
222 * Find a window that needs repaint.
224 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
226 HWND32 hwndRet;
227 WND *pWnd = pWndDesktop;
229 /* Note: the desktop window never gets WM_PAINT messages
230 * The real reason why is because Windows DesktopWndProc
231 * does ValidateRgn inside WM_ERASEBKGND handler.
234 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
236 for ( ; pWnd ; pWnd = pWnd->next )
238 if (!(pWnd->dwStyle & WS_VISIBLE))
240 dprintf_win( stddeb, "FindWinToRepaint: skipping window %04x\n",
241 pWnd->hwndSelf );
242 continue;
244 if ((pWnd->hmemTaskQ == hQueue) &&
245 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
247 if (pWnd->child )
248 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
249 return hwndRet;
252 if (!pWnd) return 0;
254 hwndRet = pWnd->hwndSelf;
256 /* look among siblings if we got a transparent window */
257 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
258 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
260 pWnd = pWnd->next;
262 if (pWnd) hwndRet = pWnd->hwndSelf;
263 dprintf_win(stddeb,"FindWinToRepaint: found %04x\n",hwndRet);
264 return hwndRet;
268 /***********************************************************************
269 * WIN_DestroyWindow
271 * Destroy storage associated to a window. "Internals" p.358
273 static WND* WIN_DestroyWindow( WND* wndPtr )
275 HWND32 hwnd = wndPtr->hwndSelf;
276 WND *pWnd;
278 dprintf_win( stddeb, "WIN_DestroyWindow: %04x\n", wndPtr->hwndSelf );
280 #ifdef CONFIG_IPC
281 if (main_block)
282 DDE_DestroyWindow(wndPtr->hwndSelf);
283 #endif /* CONFIG_IPC */
285 /* free child windows */
287 while ((pWnd = wndPtr->child))
288 wndPtr->child = WIN_DestroyWindow( pWnd );
290 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
292 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
294 WINPOS_CheckInternalPos( hwnd );
295 if( hwnd == GetCapture32()) ReleaseCapture();
297 /* free resources associated with the window */
299 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
300 PROPERTY_RemoveWindowProps( wndPtr );
302 wndPtr->dwMagic = 0; /* Mark it as invalid */
303 wndPtr->hwndSelf = 0;
305 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
307 if (wndPtr->hrgnUpdate > 1) DeleteObject32( wndPtr->hrgnUpdate );
308 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
311 /* toss stale messages from the queue */
313 if( wndPtr->hmemTaskQ )
315 int pos;
316 BOOL32 bPostQuit = FALSE;
317 WPARAM32 wQuitParam = 0;
318 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
320 while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
322 if( msgQ->messages[pos].msg.message == WM_QUIT )
324 bPostQuit = TRUE;
325 wQuitParam = msgQ->messages[pos].msg.wParam;
327 QUEUE_RemoveMsg(msgQ, pos);
329 /* repost WM_QUIT to make sure this app exits its message loop */
330 if( bPostQuit ) PostQuitMessage32(wQuitParam);
331 wndPtr->hmemTaskQ = 0;
334 if (!(wndPtr->dwStyle & WS_CHILD))
335 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
336 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
337 if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
338 if (wndPtr->class->style & CS_OWNDC) DCE_FreeWindowDCE( wndPtr );
340 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
342 wndPtr->class->cWindows--;
343 wndPtr->class = NULL;
344 pWnd = wndPtr->next;
346 USER_HEAP_FREE( hwnd );
347 return pWnd;
350 /***********************************************************************
351 * WIN_ResetQueueWindows
353 * Reset the queue of all the children of a given window.
354 * Return TRUE if something was done.
356 BOOL32 WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
358 BOOL32 ret = FALSE;
360 if (hNew) /* Set a new queue */
362 for (wnd = wnd->child; (wnd); wnd = wnd->next)
364 if (wnd->hmemTaskQ == hQueue)
366 wnd->hmemTaskQ = hNew;
367 ret = TRUE;
369 if (wnd->child)
370 ret |= WIN_ResetQueueWindows( wnd->child, hQueue, hNew );
373 else /* Queue is being destroyed */
375 while (wnd->child)
377 WND *tmp = wnd->child;
378 ret = FALSE;
379 while (tmp)
381 if (tmp->hmemTaskQ == hQueue)
383 DestroyWindow32( tmp->hwndSelf );
384 ret = TRUE;
385 break;
387 if (tmp->child && WIN_ResetQueueWindows(tmp->child,hQueue,0))
388 ret = TRUE;
389 else
390 tmp = tmp->next;
392 if (!ret) break;
395 return ret;
398 /***********************************************************************
399 * WIN_CreateDesktopWindow
401 * Create the desktop window.
403 BOOL32 WIN_CreateDesktopWindow(void)
405 CLASS *class;
406 HWND32 hwndDesktop;
408 dprintf_win(stddeb,"Creating desktop window\n");
410 if (!ICONTITLE_Init() ||
411 !WINPOS_CreateInternalPosAtom() ||
412 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
413 return FALSE;
415 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
416 if (!hwndDesktop) return FALSE;
417 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
419 pWndDesktop->next = NULL;
420 pWndDesktop->child = NULL;
421 pWndDesktop->parent = NULL;
422 pWndDesktop->owner = NULL;
423 pWndDesktop->class = class;
424 pWndDesktop->dwMagic = WND_MAGIC;
425 pWndDesktop->hwndSelf = hwndDesktop;
426 pWndDesktop->hInstance = 0;
427 pWndDesktop->rectWindow.left = 0;
428 pWndDesktop->rectWindow.top = 0;
429 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
430 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
431 pWndDesktop->rectClient = pWndDesktop->rectWindow;
432 pWndDesktop->text = NULL;
433 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
434 pWndDesktop->hrgnUpdate = 0;
435 pWndDesktop->hwndLastActive = hwndDesktop;
436 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
437 WS_CLIPSIBLINGS;
438 pWndDesktop->dwExStyle = 0;
439 pWndDesktop->dce = NULL;
440 pWndDesktop->pVScroll = NULL;
441 pWndDesktop->pHScroll = NULL;
442 pWndDesktop->pProp = NULL;
443 pWndDesktop->wIDmenu = 0;
444 pWndDesktop->flags = 0;
445 pWndDesktop->window = rootWindow;
446 pWndDesktop->hSysMenu = 0;
447 pWndDesktop->userdata = 0;
449 pWndDesktop->winproc = (WNDPROC16)class->winproc;
451 EVENT_RegisterWindow( pWndDesktop );
452 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
453 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
454 return TRUE;
458 /***********************************************************************
459 * WIN_CreateWindowEx
461 * Implementation of CreateWindowEx().
463 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
464 BOOL32 win32, BOOL32 unicode )
466 CLASS *classPtr;
467 WND *wndPtr;
468 HWND16 hwnd, hwndLinkAfter;
469 POINT32 maxSize, maxPos, minTrack, maxTrack;
470 LRESULT (WINAPI *localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
472 dprintf_win( stddeb, "CreateWindowEx: " );
473 if (HIWORD(cs->lpszName)) dprintf_win( stddeb, "'%s' ", cs->lpszName );
474 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszName) );
475 if (HIWORD(cs->lpszClass)) dprintf_win( stddeb, "'%s' ", cs->lpszClass );
476 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszClass) );
478 dprintf_win( stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
479 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
480 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
482 /* Find the parent window */
484 if (cs->hwndParent)
486 /* Make sure parent is valid */
487 if (!IsWindow32( cs->hwndParent ))
489 fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
490 return 0;
492 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
493 fprintf( stderr, "CreateWindowEx: no parent for child window\n" );
494 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
497 /* Find the window class */
498 if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
500 char buffer[256];
501 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
502 fprintf( stderr, "CreateWindowEx: bad class '%s'\n", buffer );
503 return 0;
506 /* Fix the coordinates */
508 if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0;
509 if (cs->cx == CW_USEDEFAULT32)
511 /* if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0;
512 else */
514 cs->cx = 600;
515 cs->cy = 400;
519 /* Create the window structure */
521 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
522 - sizeof(wndPtr->wExtra) )))
524 dprintf_win( stddeb, "CreateWindowEx: out of memory\n" );
525 return 0;
528 /* Fill the window structure */
530 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
531 wndPtr->next = NULL;
532 wndPtr->child = NULL;
534 if ((cs->style & WS_CHILD) && cs->hwndParent)
536 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
537 wndPtr->owner = NULL;
539 else
541 wndPtr->parent = pWndDesktop;
542 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
543 wndPtr->owner = NULL;
544 else
545 wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
548 wndPtr->window = 0;
549 wndPtr->class = classPtr;
550 wndPtr->winproc = classPtr->winproc;
551 wndPtr->dwMagic = WND_MAGIC;
552 wndPtr->hwndSelf = hwnd;
553 wndPtr->hInstance = cs->hInstance;
554 wndPtr->text = NULL;
555 wndPtr->hmemTaskQ = GetTaskQueue(0);
556 wndPtr->hrgnUpdate = 0;
557 wndPtr->hwndLastActive = hwnd;
558 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
559 wndPtr->dwExStyle = cs->dwExStyle;
560 wndPtr->wIDmenu = 0;
561 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
562 wndPtr->pVScroll = NULL;
563 wndPtr->pHScroll = NULL;
564 wndPtr->pProp = NULL;
565 wndPtr->userdata = 0;
566 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
567 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
569 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
571 /* Call the WH_CBT hook */
573 hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
575 if (HOOK_IsHooked( WH_CBT ))
577 CBT_CREATEWND32A cbtc;
579 cbtc.lpcs = cs;
580 cbtc.hwndInsertAfter = hwndLinkAfter;
581 if ( HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc) )
583 dprintf_win(stddeb, "CreateWindowEx: CBT-hook returned 0\n");
584 USER_HEAP_FREE( hwnd );
585 return 0;
589 /* Increment class window counter */
591 classPtr->cWindows++;
593 /* Correct the window style */
595 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
597 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
598 wndPtr->flags |= WIN_NEED_SIZE;
600 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
602 /* Get class or window DC if needed */
604 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
605 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
606 else wndPtr->dce = NULL;
608 /* Insert the window in the linked list */
610 WIN_LinkWindow( hwnd, hwndLinkAfter );
612 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
614 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
616 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
617 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
618 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
619 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
620 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
623 if(cs->style & WS_CHILD)
625 if(cs->cx < 0) cs->cx = 0;
626 if(cs->cy < 0) cs->cy = 0;
628 else
630 if (cs->cx <= 0) cs->cx = 1;
631 if (cs->cy <= 0) cs->cy = 1;
634 wndPtr->rectWindow.left = cs->x;
635 wndPtr->rectWindow.top = cs->y;
636 wndPtr->rectWindow.right = cs->x + cs->cx;
637 wndPtr->rectWindow.bottom = cs->y + cs->cy;
638 wndPtr->rectClient = wndPtr->rectWindow;
640 /* Create the X window (only for top-level windows, and then only */
641 /* when there's no desktop window) */
643 if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
645 XSetWindowAttributes win_attr;
647 if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
648 (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
650 win_attr.event_mask = ExposureMask | KeyPressMask |
651 KeyReleaseMask | PointerMotionMask |
652 ButtonPressMask | ButtonReleaseMask |
653 FocusChangeMask | StructureNotifyMask;
654 win_attr.override_redirect = FALSE;
655 wndPtr->flags |= WIN_MANAGED;
657 else
659 win_attr.event_mask = ExposureMask | KeyPressMask |
660 KeyReleaseMask | PointerMotionMask |
661 ButtonPressMask | ButtonReleaseMask |
662 FocusChangeMask;
663 win_attr.override_redirect = TRUE;
665 win_attr.colormap = COLOR_GetColormap();
666 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
667 win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
668 win_attr.cursor = CURSORICON_XCursor;
669 wndPtr->window = TSXCreateWindow( display, rootWindow, cs->x, cs->y,
670 cs->cx, cs->cy, 0, CopyFromParent,
671 InputOutput, CopyFromParent,
672 CWEventMask | CWOverrideRedirect |
673 CWColormap | CWCursor | CWSaveUnder |
674 CWBackingStore, &win_attr );
676 if ((wndPtr->flags & WIN_MANAGED) &&
677 (cs->dwExStyle & WS_EX_DLGMODALFRAME))
679 XSizeHints* size_hints = TSXAllocSizeHints();
681 if (size_hints)
683 size_hints->min_width = size_hints->max_width = cs->cx;
684 size_hints->min_height = size_hints->max_height = cs->cy;
685 size_hints->flags = (PSize | PMinSize | PMaxSize);
686 TSXSetWMSizeHints( display, wndPtr->window, size_hints,
687 XA_WM_NORMAL_HINTS );
688 TSXFree(size_hints);
692 if (cs->hwndParent) /* Get window owner */
694 Window win = WIN_GetXWindow( cs->hwndParent );
695 if (win) TSXSetTransientForHint( display, wndPtr->window, win );
697 EVENT_RegisterWindow( wndPtr );
700 /* Set the window menu */
702 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
704 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
705 else
707 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
708 if (classPtr->menuNameA)
709 cs->hMenu = HIWORD(classPtr->menuNameA) ?
710 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
711 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
712 #else
713 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
714 if (HIWORD(cs->hInstance))
715 cs->hMenu = LoadMenu32A(cs->hInstance,PTR_SEG_TO_LIN(menuName));
716 else
717 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
718 #endif
720 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
722 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
724 /* Send the WM_CREATE message
725 * Perhaps we shouldn't allow width/height changes as well.
726 * See p327 in "Internals".
729 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
731 localSend32 = unicode ? SendMessage32W : SendMessage32A;
732 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
734 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
735 NULL, NULL, 0, &wndPtr->rectClient );
736 OffsetRect32(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
737 maxPos.y - wndPtr->rectWindow.top);
738 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
740 /* Send the size messages */
742 if (!(wndPtr->flags & WIN_NEED_SIZE))
744 /* send it anyway */
746 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
747 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
748 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
749 SendMessage32A( hwnd, WM_MOVE, 0,
750 MAKELONG( wndPtr->rectClient.left,
751 wndPtr->rectClient.top ) );
754 /* Show the window, maximizing or minimizing if needed */
756 if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
758 RECT16 newPos;
759 UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
760 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
761 WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
762 swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow32()) ? SWP_NOACTIVATE : 0;
763 SetWindowPos32( hwnd, 0, newPos.left, newPos.top,
764 newPos.right, newPos.bottom, SWP_FRAMECHANGED | swFlag );
767 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
769 /* Notify the parent window only */
771 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
772 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
773 if( !IsWindow32(hwnd) ) return 0;
776 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
778 /* Call WH_SHELL hook */
780 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
781 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
783 dprintf_win(stddeb, "CreateWindowEx: created window %04x\n", hwnd);
784 return hwnd;
788 /* Abort window creation */
790 dprintf_win(stddeb,"CreateWindowEx: aborted by WM_xxCREATE!\n");
791 WIN_UnlinkWindow( hwnd );
792 WIN_DestroyWindow( wndPtr );
793 return 0;
797 /***********************************************************************
798 * CreateWindow16 (USER.41)
800 HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
801 DWORD style, INT16 x, INT16 y, INT16 width,
802 INT16 height, HWND16 parent, HMENU16 menu,
803 HINSTANCE16 instance, LPVOID data )
805 return CreateWindowEx16( 0, className, windowName, style,
806 x, y, width, height, parent, menu, instance, data );
810 /***********************************************************************
811 * CreateWindowEx16 (USER.452)
813 HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
814 LPCSTR windowName, DWORD style, INT16 x,
815 INT16 y, INT16 width, INT16 height,
816 HWND16 parent, HMENU16 menu,
817 HINSTANCE16 instance, LPVOID data )
819 ATOM classAtom;
820 CREATESTRUCT32A cs;
822 /* Find the class atom */
824 if (!(classAtom = GlobalFindAtom32A( className )))
826 fprintf( stderr, "CreateWindowEx16: bad class name " );
827 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
828 else fprintf( stderr, "'%s'\n", className );
829 return 0;
832 /* Fix the coordinates */
834 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
835 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
836 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
837 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
839 /* Create the window */
841 cs.lpCreateParams = data;
842 cs.hInstance = (HINSTANCE32)instance;
843 cs.hMenu = (HMENU32)menu;
844 cs.hwndParent = (HWND32)parent;
845 cs.style = style;
846 cs.lpszName = windowName;
847 cs.lpszClass = className;
848 cs.dwExStyle = exStyle;
849 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
853 /***********************************************************************
854 * CreateWindowEx32A (USER32.82)
856 HWND32 WINAPI CreateWindowEx32A( DWORD exStyle, LPCSTR className,
857 LPCSTR windowName, DWORD style, INT32 x,
858 INT32 y, INT32 width, INT32 height,
859 HWND32 parent, HMENU32 menu,
860 HINSTANCE32 instance, LPVOID data )
862 ATOM classAtom;
863 CREATESTRUCT32A cs;
865 /* Find the class atom */
867 if (!(classAtom = GlobalFindAtom32A( className )))
869 fprintf( stderr, "CreateWindowEx32A: bad class name " );
870 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
871 else fprintf( stderr, "'%s'\n", className );
872 return 0;
875 /* Create the window */
877 cs.lpCreateParams = data;
878 cs.hInstance = instance;
879 cs.hMenu = menu;
880 cs.hwndParent = parent;
881 cs.x = x;
882 cs.y = y;
883 cs.cx = width;
884 cs.cy = height;
885 cs.style = style;
886 cs.lpszName = windowName;
887 cs.lpszClass = className;
888 cs.dwExStyle = exStyle;
889 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
893 /***********************************************************************
894 * CreateWindowEx32W (USER32.83)
896 HWND32 WINAPI CreateWindowEx32W( DWORD exStyle, LPCWSTR className,
897 LPCWSTR windowName, DWORD style, INT32 x,
898 INT32 y, INT32 width, INT32 height,
899 HWND32 parent, HMENU32 menu,
900 HINSTANCE32 instance, LPVOID data )
902 ATOM classAtom;
903 CREATESTRUCT32W cs;
905 /* Find the class atom */
907 if (!(classAtom = GlobalFindAtom32W( className )))
909 if (HIWORD(className))
911 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
912 fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
913 HeapFree( GetProcessHeap(), 0, cn );
915 else
916 fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
917 return 0;
920 /* Create the window */
922 cs.lpCreateParams = data;
923 cs.hInstance = instance;
924 cs.hMenu = menu;
925 cs.hwndParent = parent;
926 cs.x = x;
927 cs.y = y;
928 cs.cx = width;
929 cs.cy = height;
930 cs.style = style;
931 cs.lpszName = windowName;
932 cs.lpszClass = className;
933 cs.dwExStyle = exStyle;
934 /* Note: we rely on the fact that CREATESTRUCT32A and */
935 /* CREATESTRUCT32W have the same layout. */
936 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
940 /***********************************************************************
941 * WIN_CheckFocus
943 static void WIN_CheckFocus( WND* pWnd )
945 if( GetFocus16() == pWnd->hwndSelf )
946 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
949 /***********************************************************************
950 * WIN_SendDestroyMsg
952 static void WIN_SendDestroyMsg( WND* pWnd )
954 WIN_CheckFocus(pWnd);
956 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
957 if( !pWnd->window ) CLIPBOARD_ResetOwner( pWnd );
959 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
961 if( IsWindow32(pWnd->hwndSelf) )
963 WND* pChild = pWnd->child;
964 while( pChild )
966 WIN_SendDestroyMsg( pChild );
967 pChild = pChild->next;
969 WIN_CheckFocus(pWnd);
971 else
972 dprintf_win(stddeb,"\tdestroyed itself while in WM_DESTROY!\n");
976 /***********************************************************************
977 * DestroyWindow16 (USER.53)
979 BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
981 return DestroyWindow32(hwnd);
985 /***********************************************************************
986 * DestroyWindow32 (USER32.134)
988 BOOL32 WINAPI DestroyWindow32( HWND32 hwnd )
990 WND * wndPtr;
992 dprintf_win(stddeb, "DestroyWindow(%04x)\n", hwnd);
994 /* Initialization */
996 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
997 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
999 /* Call hooks */
1001 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
1002 return FALSE;
1004 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1006 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
1007 /* FIXME: clean up palette - see "Internals" p.352 */
1010 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
1011 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
1013 /* Notify the parent window only */
1014 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
1015 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
1016 if( !IsWindow32(hwnd) ) return TRUE;
1019 if( wndPtr->window ) CLIPBOARD_ResetOwner( wndPtr ); /* before the window is unmapped */
1021 /* Hide the window */
1023 if (wndPtr->dwStyle & WS_VISIBLE)
1025 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
1026 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
1027 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
1028 if (!IsWindow32(hwnd)) return TRUE;
1031 /* Recursively destroy owned windows */
1033 if( !(wndPtr->dwStyle & WS_CHILD) )
1035 /* make sure top menu popup doesn't get destroyed */
1036 MENU_PatchResidentPopup( (HQUEUE16)0xFFFF, wndPtr );
1038 for (;;)
1040 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1041 while (siblingPtr)
1043 if (siblingPtr->owner == wndPtr)
1044 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1045 break;
1046 else
1047 siblingPtr->owner = NULL;
1048 siblingPtr = siblingPtr->next;
1050 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1051 else break;
1054 if( !Options.managed || EVENT_CheckFocus() )
1055 WINPOS_ActivateOtherWindow(wndPtr);
1057 if( wndPtr->owner &&
1058 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1059 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1062 /* Send destroy messages */
1064 WIN_SendDestroyMsg( wndPtr );
1065 if (!IsWindow32(hwnd)) return TRUE;
1067 /* Unlink now so we won't bother with the children later on */
1069 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1071 /* Destroy the window storage */
1073 WIN_DestroyWindow( wndPtr );
1074 return TRUE;
1078 /***********************************************************************
1079 * CloseWindow16 (USER.43)
1081 BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
1083 return CloseWindow32( hwnd );
1087 /***********************************************************************
1088 * CloseWindow32 (USER32.55)
1090 BOOL32 WINAPI CloseWindow32( HWND32 hwnd )
1092 WND * wndPtr = WIN_FindWndPtr( hwnd );
1093 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1094 ShowWindow32( hwnd, SW_MINIMIZE );
1095 return TRUE;
1099 /***********************************************************************
1100 * OpenIcon16 (USER.44)
1102 BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
1104 return OpenIcon32( hwnd );
1108 /***********************************************************************
1109 * OpenIcon32 (USER32.409)
1111 BOOL32 WINAPI OpenIcon32( HWND32 hwnd )
1113 if (!IsIconic32( hwnd )) return FALSE;
1114 ShowWindow32( hwnd, SW_SHOWNORMAL );
1115 return TRUE;
1119 /***********************************************************************
1120 * WIN_FindWindow
1122 * Implementation of FindWindow() and FindWindowEx().
1124 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1125 LPCSTR title )
1127 WND *pWnd;
1128 CLASS *pClass = NULL;
1130 if (child)
1132 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1133 if (parent)
1135 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1137 else if (pWnd->parent != pWndDesktop) return 0;
1138 pWnd = pWnd->next;
1140 else
1142 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1143 pWnd = pWnd->child;
1145 if (!pWnd) return 0;
1147 /* For a child window, all siblings will have the same hInstance, */
1148 /* so we can look for the class once and for all. */
1150 if (className && (pWnd->dwStyle & WS_CHILD))
1152 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1153 return 0;
1157 for ( ; pWnd; pWnd = pWnd->next)
1159 if (className && !(pWnd->dwStyle & WS_CHILD))
1161 if (!(pClass = CLASS_FindClassByAtom( className, GetExePtr(pWnd->hInstance))))
1162 continue; /* Skip this window */
1165 if (pClass && (pWnd->class != pClass))
1166 continue; /* Not the right class */
1168 /* Now check the title */
1170 if (!title) return pWnd->hwndSelf;
1171 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1173 return 0;
1178 /***********************************************************************
1179 * FindWindow16 (USER.50)
1181 HWND16 WINAPI FindWindow16( SEGPTR className, LPCSTR title )
1183 return FindWindowEx16( 0, 0, className, title );
1187 /***********************************************************************
1188 * FindWindowEx16 (USER.427)
1190 HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child,
1191 SEGPTR className, LPCSTR title )
1193 ATOM atom = 0;
1195 dprintf_win(stddeb, "FindWindowEx16: %04x %04x '%s' '%s'\n", parent,
1196 child, HIWORD(className)?(char *)PTR_SEG_TO_LIN(className):"",
1197 title ? title : "");
1199 if (className)
1201 /* If the atom doesn't exist, then no class */
1202 /* with this name exists either. */
1203 if (!(atom = GlobalFindAtom16( className ))) return 0;
1205 return WIN_FindWindow( parent, child, atom, title );
1209 /***********************************************************************
1210 * FindWindow32A (USER32.197)
1212 HWND32 WINAPI FindWindow32A( LPCSTR className, LPCSTR title )
1214 return FindWindowEx32A( 0, 0, className, title );
1218 /***********************************************************************
1219 * FindWindowEx32A (USER32.198)
1221 HWND32 WINAPI FindWindowEx32A( HWND32 parent, HWND32 child,
1222 LPCSTR className, LPCSTR title )
1224 ATOM atom = 0;
1226 if (className)
1228 /* If the atom doesn't exist, then no class */
1229 /* with this name exists either. */
1230 if (!(atom = GlobalFindAtom32A( className ))) return 0;
1232 return WIN_FindWindow( parent, child, atom, title );
1236 /***********************************************************************
1237 * FindWindowEx32W (USER32.199)
1239 HWND32 WINAPI FindWindowEx32W( HWND32 parent, HWND32 child,
1240 LPCWSTR className, LPCWSTR title )
1242 ATOM atom = 0;
1243 char *buffer;
1244 HWND32 hwnd;
1246 if (className)
1248 /* If the atom doesn't exist, then no class */
1249 /* with this name exists either. */
1250 if (!(atom = GlobalFindAtom32W( className ))) return 0;
1252 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1253 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1254 HeapFree( GetProcessHeap(), 0, buffer );
1255 return hwnd;
1259 /***********************************************************************
1260 * FindWindow32W (USER32.200)
1262 HWND32 WINAPI FindWindow32W( LPCWSTR className, LPCWSTR title )
1264 return FindWindowEx32W( 0, 0, className, title );
1268 /**********************************************************************
1269 * WIN_GetDesktop
1271 WND *WIN_GetDesktop(void)
1273 return pWndDesktop;
1277 /**********************************************************************
1278 * GetDesktopWindow16 (USER.286)
1280 HWND16 WINAPI GetDesktopWindow16(void)
1282 return (HWND16)pWndDesktop->hwndSelf;
1286 /**********************************************************************
1287 * GetDesktopWindow32 (USER32.231)
1289 HWND32 WINAPI GetDesktopWindow32(void)
1291 return pWndDesktop->hwndSelf;
1295 /**********************************************************************
1296 * GetDesktopHwnd (USER.278)
1298 * Exactly the same thing as GetDesktopWindow(), but not documented.
1299 * Don't ask me why...
1301 HWND16 WINAPI GetDesktopHwnd(void)
1303 return (HWND16)pWndDesktop->hwndSelf;
1307 /*******************************************************************
1308 * EnableWindow16 (USER.34)
1310 BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
1312 return EnableWindow32( hwnd, enable );
1316 /*******************************************************************
1317 * EnableWindow32 (USER32.171)
1319 BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
1321 WND *wndPtr;
1323 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1324 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1326 /* Enable window */
1327 wndPtr->dwStyle &= ~WS_DISABLED;
1328 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1329 return TRUE;
1331 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1333 /* Disable window */
1334 wndPtr->dwStyle |= WS_DISABLED;
1335 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1336 SetFocus32( 0 ); /* A disabled window can't have the focus */
1337 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1338 ReleaseCapture(); /* A disabled window can't capture the mouse */
1339 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1340 return FALSE;
1342 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1346 /***********************************************************************
1347 * IsWindowEnabled16 (USER.35)
1349 BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
1351 return IsWindowEnabled32(hWnd);
1355 /***********************************************************************
1356 * IsWindowEnabled32 (USER32.348)
1358 BOOL32 WINAPI IsWindowEnabled32(HWND32 hWnd)
1360 WND * wndPtr;
1362 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1363 return !(wndPtr->dwStyle & WS_DISABLED);
1367 /***********************************************************************
1368 * IsWindowUnicode (USER32.349)
1370 BOOL32 WINAPI IsWindowUnicode( HWND32 hwnd )
1372 WND * wndPtr;
1374 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1375 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1379 /**********************************************************************
1380 * GetWindowWord16 (USER.133)
1382 WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
1384 return GetWindowWord32( hwnd, offset );
1388 /**********************************************************************
1389 * GetWindowWord32 (USER32.313)
1391 WORD WINAPI GetWindowWord32( HWND32 hwnd, INT32 offset )
1393 WND * wndPtr = WIN_FindWndPtr( hwnd );
1394 if (!wndPtr) return 0;
1395 if (offset >= 0)
1397 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1399 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1400 return 0;
1402 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1404 switch(offset)
1406 case GWW_ID:
1407 if (HIWORD(wndPtr->wIDmenu))
1408 fprintf(stderr,"GetWindowWord32(GWW_ID) discards high bits of 0x%08x!\n",wndPtr->wIDmenu);
1409 return (WORD)wndPtr->wIDmenu;
1410 case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
1411 case GWW_HINSTANCE:
1412 if (HIWORD(wndPtr->hInstance))
1413 fprintf(stderr,"GetWindowWord32(GWW_HINSTANCE) discards high bits of 0x%08x!\n",wndPtr->hInstance);
1414 return (WORD)wndPtr->hInstance;
1415 default:
1416 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1417 return 0;
1422 /**********************************************************************
1423 * WIN_GetWindowInstance
1425 HINSTANCE32 WIN_GetWindowInstance( HWND32 hwnd )
1427 WND * wndPtr = WIN_FindWndPtr( hwnd );
1428 if (!wndPtr) return (HINSTANCE32)0;
1429 return wndPtr->hInstance;
1433 /**********************************************************************
1434 * SetWindowWord16 (USER.134)
1436 WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1438 return SetWindowWord32( hwnd, offset, newval );
1442 /**********************************************************************
1443 * SetWindowWord32 (USER32.523)
1445 WORD WINAPI SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1447 WORD *ptr, retval;
1448 WND * wndPtr = WIN_FindWndPtr( hwnd );
1449 if (!wndPtr) return 0;
1450 if (offset >= 0)
1452 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1454 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1455 return 0;
1457 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1459 else switch(offset)
1461 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1462 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1463 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1464 default:
1465 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1466 return 0;
1468 retval = *ptr;
1469 *ptr = newval;
1470 return retval;
1474 /**********************************************************************
1475 * WIN_GetWindowLong
1477 * Helper function for GetWindowLong().
1479 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1481 LONG retval;
1482 WND * wndPtr = WIN_FindWndPtr( hwnd );
1483 if (!wndPtr) return 0;
1484 if (offset >= 0)
1486 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1488 fprintf( stderr, "GetWindowLong: invalid offset %d\n", offset );
1489 return 0;
1491 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1492 /* Special case for dialog window procedure */
1493 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1494 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1495 return retval;
1497 switch(offset)
1499 case GWL_USERDATA: return wndPtr->userdata;
1500 case GWL_STYLE: return wndPtr->dwStyle;
1501 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1502 case GWL_ID: return (LONG)wndPtr->wIDmenu;
1503 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1504 type );
1505 case GWL_HWNDPARENT: return wndPtr->parent ?
1506 (HWND32)wndPtr->parent->hwndSelf : 0;
1507 case GWL_HINSTANCE: return wndPtr->hInstance;
1508 default:
1509 fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
1511 return 0;
1515 /**********************************************************************
1516 * WIN_SetWindowLong
1518 * Helper function for SetWindowLong().
1520 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1521 WINDOWPROCTYPE type )
1523 LONG *ptr, retval;
1524 WND * wndPtr = WIN_FindWndPtr( hwnd );
1526 if (!wndPtr) return 0;
1527 if (offset >= 0)
1529 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1531 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1532 return 0;
1534 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1535 /* Special case for dialog window procedure */
1536 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1538 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1539 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1540 type, WIN_PROC_WINDOW );
1541 return retval;
1544 else switch(offset)
1546 case GWL_ID:
1547 ptr = (DWORD*)&wndPtr->wIDmenu;
1548 break;
1549 case GWL_HINSTANCE:
1550 return SetWindowWord32( hwnd, offset, newval );
1551 case GWL_WNDPROC:
1552 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1553 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1554 type, WIN_PROC_WINDOW );
1555 return retval;
1556 case GWL_STYLE:
1558 /* FIXME: WM_STYLE... messages for WIN_ISWIN32 windows */
1560 ptr = &wndPtr->dwStyle;
1561 /* Some bits can't be changed this way */
1562 newval &= ~(WS_VISIBLE | WS_CHILD);
1563 newval |= (*ptr & (WS_VISIBLE | WS_CHILD));
1564 break;
1565 case GWL_USERDATA: ptr = &wndPtr->userdata; break;
1566 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
1567 default:
1568 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1569 return 0;
1571 retval = *ptr;
1572 *ptr = newval;
1573 return retval;
1577 /**********************************************************************
1578 * GetWindowLong16 (USER.135)
1580 LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
1582 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1586 /**********************************************************************
1587 * GetWindowLong32A (USER32.304)
1589 LONG WINAPI GetWindowLong32A( HWND32 hwnd, INT32 offset )
1591 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1595 /**********************************************************************
1596 * GetWindowLong32W (USER32.305)
1598 LONG WINAPI GetWindowLong32W( HWND32 hwnd, INT32 offset )
1600 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1604 /**********************************************************************
1605 * SetWindowLong16 (USER.136)
1607 LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1609 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1613 /**********************************************************************
1614 * SetWindowLong32A (USER32.516)
1616 LONG WINAPI SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1618 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1622 /**********************************************************************
1623 * SetWindowLong32W (USER32.517)
1625 LONG WINAPI SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
1627 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1631 /*******************************************************************
1632 * GetWindowText16 (USER.36)
1634 INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1636 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1640 /*******************************************************************
1641 * GetWindowText32A (USER32.308)
1643 INT32 WINAPI GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1645 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1646 (LPARAM)lpString );
1650 /*******************************************************************
1651 * GetWindowText32W (USER32.311)
1653 INT32 WINAPI GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1655 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1656 (LPARAM)lpString );
1660 /*******************************************************************
1661 * SetWindowText16 (USER.37)
1663 void WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1665 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1669 /*******************************************************************
1670 * SetWindowText32A (USER32.521)
1672 void WINAPI SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1674 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1678 /*******************************************************************
1679 * SetWindowText32W (USER32.522)
1681 void WINAPI SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1683 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1687 /*******************************************************************
1688 * GetWindowTextLength16 (USER.38)
1690 INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
1692 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1696 /*******************************************************************
1697 * GetWindowTextLength32A (USER32.309)
1699 INT32 WINAPI GetWindowTextLength32A( HWND32 hwnd )
1701 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1704 /*******************************************************************
1705 * GetWindowTextLength32W (USER32.309)
1707 INT32 WINAPI GetWindowTextLength32W( HWND32 hwnd )
1709 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1713 /*******************************************************************
1714 * IsWindow16 (USER.47)
1716 BOOL16 WINAPI IsWindow16( HWND16 hwnd )
1718 return IsWindow32( hwnd );
1722 /*******************************************************************
1723 * IsWindow32 (USER32.347)
1725 BOOL32 WINAPI IsWindow32( HWND32 hwnd )
1727 WND * wndPtr = WIN_FindWndPtr( hwnd );
1728 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1732 /*****************************************************************
1733 * GetParent16 (USER.46)
1735 HWND16 WINAPI GetParent16( HWND16 hwnd )
1737 return (HWND16)GetParent32( hwnd );
1741 /*****************************************************************
1742 * GetParent32 (USER32.277)
1744 HWND32 WINAPI GetParent32( HWND32 hwnd )
1746 WND *wndPtr = WIN_FindWndPtr(hwnd);
1747 if (!wndPtr) return 0;
1748 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1749 return wndPtr ? wndPtr->hwndSelf : 0;
1752 /*****************************************************************
1753 * WIN_GetTopParent
1755 * Get the top-level parent for a child window.
1757 WND* WIN_GetTopParentPtr( WND* pWnd )
1759 while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
1760 return pWnd;
1763 /*****************************************************************
1764 * WIN_GetTopParent
1766 * Get the top-level parent for a child window.
1768 HWND32 WIN_GetTopParent( HWND32 hwnd )
1770 WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
1771 return wndPtr ? wndPtr->hwndSelf : 0;
1775 /*****************************************************************
1776 * SetParent16 (USER.233)
1778 HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1780 return SetParent32( hwndChild, hwndNewParent );
1784 /*****************************************************************
1785 * SetParent32 (USER32.494)
1787 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1789 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1790 WND *pWndParent = (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent )
1791 : pWndDesktop;
1793 if( wndPtr && pWndParent && (wndPtr != pWndDesktop) )
1795 WND* pWndPrev = wndPtr->parent;
1797 if( pWndParent != pWndPrev )
1799 BOOL32 bFixupDCE = IsWindowVisible32(hwndChild);
1801 if ( wndPtr->window )
1803 /* Toplevel window needs to be reparented. Used by Tk 8.0 */
1805 TSXDestroyWindow( display, wndPtr->window );
1806 wndPtr->window = None;
1808 else if( bFixupDCE )
1809 DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
1811 WIN_UnlinkWindow(hwndChild);
1812 wndPtr->parent = pWndParent;
1814 /* FIXME: Create an X counterpart for reparented top-level windows
1815 * when not in the desktop mode. */
1817 if ( pWndParent == pWndDesktop )
1818 wndPtr->dwStyle &= ~WS_CHILD;
1819 else wndPtr->dwStyle |= WS_CHILD;
1820 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
1822 if( bFixupDCE )
1824 DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
1825 UpdateWindow32(hwndChild);
1828 return pWndPrev->hwndSelf;
1829 } /* failure */
1830 return 0;
1834 /*******************************************************************
1835 * IsChild16 (USER.48)
1837 BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
1839 return IsChild32(parent,child);
1843 /*******************************************************************
1844 * IsChild32 (USER32.338)
1846 BOOL32 WINAPI IsChild32( HWND32 parent, HWND32 child )
1848 WND * wndPtr = WIN_FindWndPtr( child );
1849 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1851 wndPtr = wndPtr->parent;
1852 if (wndPtr->hwndSelf == parent) return TRUE;
1854 return FALSE;
1858 /***********************************************************************
1859 * IsWindowVisible16 (USER.49)
1861 BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
1863 return IsWindowVisible32(hwnd);
1867 /***********************************************************************
1868 * IsWindowVisible32 (USER32.350)
1870 BOOL32 WINAPI IsWindowVisible32( HWND32 hwnd )
1872 WND *wndPtr = WIN_FindWndPtr( hwnd );
1873 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1875 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1876 wndPtr = wndPtr->parent;
1878 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1882 /***********************************************************************
1883 * WIN_IsWindowDrawable
1885 * hwnd is drawable when it is visible, all parents are not
1886 * minimized, and it is itself not minimized unless we are
1887 * trying to draw its default class icon.
1889 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
1891 if( (wnd->dwStyle & WS_MINIMIZE &&
1892 icon && wnd->class->hIcon) ||
1893 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
1894 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
1895 if( wnd->dwStyle & WS_MINIMIZE ||
1896 !(wnd->dwStyle & WS_VISIBLE) ) break;
1897 return (wnd == NULL);
1901 /*******************************************************************
1902 * GetTopWindow16 (USER.229)
1904 HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
1906 return GetTopWindow32(hwnd);
1910 /*******************************************************************
1911 * GetTopWindow32 (USER.229)
1913 HWND32 WINAPI GetTopWindow32( HWND32 hwnd )
1915 WND * wndPtr = WIN_FindWndPtr( hwnd );
1916 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1917 else return 0;
1921 /*******************************************************************
1922 * GetWindow16 (USER.262)
1924 HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
1926 return GetWindow32( hwnd,rel );
1930 /*******************************************************************
1931 * GetWindow32 (USER32.301)
1933 HWND32 WINAPI GetWindow32( HWND32 hwnd, WORD rel )
1935 WND * wndPtr = WIN_FindWndPtr( hwnd );
1936 if (!wndPtr) return 0;
1937 switch(rel)
1939 case GW_HWNDFIRST:
1940 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
1941 else return 0;
1943 case GW_HWNDLAST:
1944 if (!wndPtr->parent) return 0; /* Desktop window */
1945 while (wndPtr->next) wndPtr = wndPtr->next;
1946 return wndPtr->hwndSelf;
1948 case GW_HWNDNEXT:
1949 if (!wndPtr->next) return 0;
1950 return wndPtr->next->hwndSelf;
1952 case GW_HWNDPREV:
1953 if (!wndPtr->parent) return 0; /* Desktop window */
1954 wndPtr = wndPtr->parent->child; /* First sibling */
1955 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
1956 while (wndPtr->next)
1958 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
1959 wndPtr = wndPtr->next;
1961 return 0;
1963 case GW_OWNER:
1964 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
1966 case GW_CHILD:
1967 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
1969 return 0;
1973 /*******************************************************************
1974 * GetNextWindow16 (USER.230)
1976 HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
1978 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1979 return GetWindow16( hwnd, flag );
1982 /*******************************************************************
1983 * ShowOwnedPopups16 (USER.265)
1985 void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
1987 ShowOwnedPopups32( owner, fShow );
1991 /*******************************************************************
1992 * ShowOwnedPopups32 (USER32.530)
1994 BOOL32 WINAPI ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
1996 WND *pWnd = pWndDesktop->child;
1997 while (pWnd)
1999 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
2000 (pWnd->dwStyle & WS_POPUP))
2001 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
2002 pWnd = pWnd->next;
2004 return TRUE;
2008 /*******************************************************************
2009 * GetLastActivePopup16 (USER.287)
2011 HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
2013 return GetLastActivePopup32( hwnd );
2016 /*******************************************************************
2017 * GetLastActivePopup32 (USER32.255)
2019 HWND32 WINAPI GetLastActivePopup32( HWND32 hwnd )
2021 WND *wndPtr;
2022 wndPtr = WIN_FindWndPtr(hwnd);
2023 if (wndPtr == NULL) return hwnd;
2024 return wndPtr->hwndLastActive;
2028 /*******************************************************************
2029 * WIN_BuildWinArray
2031 * Build an array of pointers to the children of a given window.
2032 * The array must be freed with HeapFree(SystemHeap). Return NULL
2033 * when no windows are found.
2035 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
2037 WND **list, **ppWnd;
2038 WND *pWnd;
2039 UINT32 count, skipOwned, skipHidden;
2040 DWORD skipFlags;
2042 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2043 skipOwned = bwaFlags & BWA_SKIPOWNED;
2044 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2045 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
2047 /* First count the windows */
2049 if (!wndPtr) wndPtr = pWndDesktop;
2050 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
2052 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2053 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
2056 if( count )
2058 /* Now build the list of all windows */
2060 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
2062 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
2064 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2065 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2067 *ppWnd++ = pWnd;
2068 count++;
2071 *ppWnd = NULL;
2073 else count = 0;
2074 } else list = NULL;
2076 if( pTotal ) *pTotal = count;
2077 return list;
2081 /*******************************************************************
2082 * EnumWindows16 (USER.54)
2084 BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2086 WND **list, **ppWnd;
2088 /* We have to build a list of all windows first, to avoid */
2089 /* unpleasant side-effects, for instance if the callback */
2090 /* function changes the Z-order of the windows. */
2092 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2094 /* Now call the callback function for every window */
2096 for (ppWnd = list; *ppWnd; ppWnd++)
2098 /* Make sure that the window still exists */
2099 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2100 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2102 HeapFree( SystemHeap, 0, list );
2103 return TRUE;
2107 /*******************************************************************
2108 * EnumWindows32 (USER32.192)
2110 BOOL32 WINAPI EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2112 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2116 /**********************************************************************
2117 * EnumTaskWindows16 (USER.225)
2119 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2120 LPARAM lParam )
2122 WND **list, **ppWnd;
2123 HQUEUE16 hQueue = GetTaskQueue( hTask );
2125 /* This function is the same as EnumWindows(), */
2126 /* except for an added check on the window queue. */
2128 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2130 /* Now call the callback function for every window */
2132 for (ppWnd = list; *ppWnd; ppWnd++)
2134 /* Make sure that the window still exists */
2135 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2136 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
2137 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2139 HeapFree( SystemHeap, 0, list );
2140 return TRUE;
2144 /**********************************************************************
2145 * EnumThreadWindows (USER32.189)
2147 BOOL32 WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2149 THDB *tdb = THREAD_ID_TO_THDB(id);
2151 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2155 /**********************************************************************
2156 * WIN_EnumChildWindows
2158 * Helper function for EnumChildWindows().
2160 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2161 LPARAM lParam )
2163 WND **childList;
2164 BOOL16 ret = FALSE;
2166 for ( ; *ppWnd; ppWnd++)
2168 /* Make sure that the window still exists */
2169 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2170 /* Build children list first */
2171 if (!(childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL )))
2172 return FALSE;
2173 if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
2174 ret = WIN_EnumChildWindows( childList, func, lParam );
2175 HeapFree( SystemHeap, 0, childList );
2176 if (!ret) return FALSE;
2178 return TRUE;
2182 /**********************************************************************
2183 * EnumChildWindows16 (USER.55)
2185 BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2186 LPARAM lParam )
2188 WND **list, *pParent;
2190 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2191 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2192 WIN_EnumChildWindows( list, func, lParam );
2193 HeapFree( SystemHeap, 0, list );
2194 return TRUE;
2198 /**********************************************************************
2199 * EnumChildWindows32 (USER32.177)
2201 BOOL32 WINAPI EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
2202 LPARAM lParam )
2204 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2205 lParam );
2209 /*******************************************************************
2210 * AnyPopup16 (USER.52)
2212 BOOL16 WINAPI AnyPopup16(void)
2214 return AnyPopup32();
2218 /*******************************************************************
2219 * AnyPopup32 (USER32.3)
2221 BOOL32 WINAPI AnyPopup32(void)
2223 WND *wndPtr;
2224 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2225 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2226 return FALSE;
2230 /*******************************************************************
2231 * FlashWindow16 (USER.105)
2233 BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2235 return FlashWindow32( hWnd, bInvert );
2239 /*******************************************************************
2240 * FlashWindow32 (USER32.201)
2242 BOOL32 WINAPI FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2244 WND *wndPtr = WIN_FindWndPtr(hWnd);
2246 dprintf_win(stddeb,"FlashWindow: %04x\n", hWnd);
2248 if (!wndPtr) return FALSE;
2250 if (wndPtr->dwStyle & WS_MINIMIZE)
2252 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2254 HDC32 hDC = GetDC32(hWnd);
2256 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2257 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2259 ReleaseDC32( hWnd, hDC );
2260 wndPtr->flags |= WIN_NCACTIVATED;
2262 else
2264 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2265 RDW_UPDATENOW | RDW_FRAME, 0 );
2266 wndPtr->flags &= ~WIN_NCACTIVATED;
2268 return TRUE;
2270 else
2272 WPARAM16 wparam;
2273 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2274 else wparam = (hWnd == GetActiveWindow32());
2276 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2277 return wparam;
2282 /*******************************************************************
2283 * SetSysModalWindow16 (USER.188)
2285 HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
2287 HWND32 hWndOldModal = hwndSysModal;
2288 hwndSysModal = hWnd;
2289 dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2290 return hWndOldModal;
2294 /*******************************************************************
2295 * GetSysModalWindow16 (USER.52)
2297 HWND16 WINAPI GetSysModalWindow16(void)
2299 return hwndSysModal;
2303 /*******************************************************************
2304 * DRAG_QueryUpdate
2306 * recursively find a child that contains spDragInfo->pt point
2307 * and send WM_QUERYDROPOBJECT
2309 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2311 BOOL16 wParam,bResult = 0;
2312 POINT32 pt;
2313 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2314 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2315 RECT32 tempRect;
2317 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2319 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2321 GetWindowRect32(hQueryWnd,&tempRect);
2323 if( !PtInRect32(&tempRect,pt) ||
2324 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2325 return 0;
2327 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2329 tempRect = ptrQueryWnd->rectClient;
2330 if(ptrQueryWnd->dwStyle & WS_CHILD)
2331 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2332 (LPPOINT32)&tempRect, 2 );
2334 if (PtInRect32( &tempRect, pt))
2336 wParam = 0;
2338 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2339 if( ptrWnd->dwStyle & WS_VISIBLE )
2341 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2342 if (PtInRect32( &tempRect, pt )) break;
2345 if(ptrWnd)
2347 dprintf_msg(stddeb,"DragQueryUpdate: hwnd = %04x, %d %d - %d %d\n",
2348 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2349 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2350 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2351 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2354 if(bResult) return bResult;
2356 else wParam = 1;
2358 else wParam = 1;
2360 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2362 ptrDragInfo->hScope = hQueryWnd;
2364 bResult = ( bNoSend )
2365 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2366 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2367 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2368 if( !bResult )
2369 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2371 return bResult;
2375 /*******************************************************************
2376 * DragDetect (USER.465)
2378 BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
2380 POINT32 pt32;
2381 CONV_POINT16TO32( &pt, &pt32 );
2382 return DragDetect32( hWnd, pt32 );
2385 /*******************************************************************
2386 * DragDetect32 (USER32.150)
2388 BOOL32 WINAPI DragDetect32( HWND32 hWnd, POINT32 pt )
2390 MSG16 msg;
2391 RECT16 rect;
2393 rect.left = pt.x - wDragWidth;
2394 rect.right = pt.x + wDragWidth;
2396 rect.top = pt.y - wDragHeight;
2397 rect.bottom = pt.y + wDragHeight;
2399 SetCapture32(hWnd);
2401 while(1)
2403 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2405 if( msg.message == WM_LBUTTONUP )
2407 ReleaseCapture();
2408 return 0;
2410 if( msg.message == WM_MOUSEMOVE )
2412 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2414 ReleaseCapture();
2415 return 1;
2419 WaitMessage();
2421 return 0;
2424 /******************************************************************************
2425 * DragObject16 (USER.464)
2427 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2428 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2430 MSG16 msg;
2431 LPDRAGINFO lpDragInfo;
2432 SEGPTR spDragInfo;
2433 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2434 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2435 WND *wndPtr = WIN_FindWndPtr(hWnd);
2436 HCURSOR16 hCurrentCursor = 0;
2437 HWND16 hCurrentWnd = 0;
2439 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2440 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2442 if( !lpDragInfo || !spDragInfo ) return 0L;
2444 hBummer = LoadCursor16(0, IDC_BUMMER);
2446 if( !hBummer || !wndPtr )
2448 GlobalFree16(hDragInfo);
2449 return 0L;
2452 if(hCursor)
2454 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2456 GlobalFree16(hDragInfo);
2457 return 0L;
2460 if( hDragCursor == hCursor ) hDragCursor = 0;
2461 else hCursor = hDragCursor;
2463 hOldCursor = SetCursor32(hDragCursor);
2466 lpDragInfo->hWnd = hWnd;
2467 lpDragInfo->hScope = 0;
2468 lpDragInfo->wFlags = wObj;
2469 lpDragInfo->hList = szList; /* near pointer! */
2470 lpDragInfo->hOfStruct = hOfStruct;
2471 lpDragInfo->l = 0L;
2473 SetCapture32(hWnd);
2474 ShowCursor32( TRUE );
2478 do{ WaitMessage(); }
2479 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2481 *(lpDragInfo+1) = *lpDragInfo;
2483 lpDragInfo->pt = msg.pt;
2485 /* update DRAGINFO struct */
2486 dprintf_msg(stddeb,"drag: lpDI->hScope = %04x\n",lpDragInfo->hScope);
2488 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2489 hCurrentCursor = hCursor;
2490 else
2492 hCurrentCursor = hBummer;
2493 lpDragInfo->hScope = 0;
2495 if( hCurrentCursor )
2496 SetCursor32(hCurrentCursor);
2498 /* send WM_DRAGLOOP */
2499 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2500 (LPARAM) spDragInfo );
2501 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2502 if( hCurrentWnd != lpDragInfo->hScope )
2504 if( hCurrentWnd )
2505 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2506 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2507 HIWORD(spDragInfo)) );
2508 hCurrentWnd = lpDragInfo->hScope;
2509 if( hCurrentWnd )
2510 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2512 else
2513 if( hCurrentWnd )
2514 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2516 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2518 ReleaseCapture();
2519 ShowCursor32( FALSE );
2521 if( hCursor )
2523 SetCursor32( hOldCursor );
2524 if (hDragCursor) DestroyCursor32( hDragCursor );
2527 if( hCurrentCursor != hBummer )
2528 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2529 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2530 else
2531 msg.lParam = 0;
2532 GlobalFree16(hDragInfo);
2534 return (DWORD)(msg.lParam);