Release 970329
[wine/multimedia.git] / windows / win.c
blobe5be6f436b854c21d4e66c6893c93091246d26b6
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 HCURSOR16 CURSORICON_IconToCursor(HICON16, BOOL32);
47 extern HWND32 CARET_GetHwnd(void);
48 extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
49 extern void WINPOS_CheckActive(HWND32);
50 extern BOOL32 EVENT_CheckFocus(void);
52 /***********************************************************************
53 * WIN_FindWndPtr
55 * Return a pointer to the WND structure corresponding to a HWND.
57 WND * WIN_FindWndPtr( HWND32 hwnd )
59 WND * ptr;
61 if (!hwnd || HIWORD(hwnd)) return NULL;
62 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
63 if (ptr->dwMagic != WND_MAGIC) return NULL;
64 if (ptr->hwndSelf != hwnd)
66 fprintf( stderr, "Can't happen: hwnd %04x self pointer is %04x\n",
67 hwnd, ptr->hwndSelf );
68 return NULL;
70 return ptr;
74 /***********************************************************************
75 * WIN_DumpWindow
77 * Dump the content of a window structure to stderr.
79 void WIN_DumpWindow( HWND32 hwnd )
81 WND *ptr;
82 char className[80];
83 int i;
85 if (!(ptr = WIN_FindWndPtr( hwnd )))
87 fprintf( stderr, "%04x is not a window handle\n", hwnd );
88 return;
91 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
92 strcpy( className, "#NULL#" );
94 fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
95 fprintf( stderr,
96 "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
97 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%04x\n"
98 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
99 "client=%d,%d-%d,%d window=%d,%d-%d,%d iconpos=%d,%d maxpos=%d,%d\n"
100 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
101 ptr->next, ptr->child, ptr->parent, ptr->owner,
102 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
103 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
104 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
105 ptr->text ? ptr->text : "",
106 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
107 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
108 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x,
109 ptr->ptIconPos.y, ptr->ptMaxPos.x, ptr->ptMaxPos.y, ptr->hSysMenu,
110 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
112 if (ptr->class->cbWndExtra)
114 fprintf( stderr, "extra bytes:" );
115 for (i = 0; i < ptr->class->cbWndExtra; i++)
116 fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
117 fprintf( stderr, "\n" );
119 fprintf( stderr, "\n" );
123 /***********************************************************************
124 * WIN_WalkWindows
126 * Walk the windows tree and print each window on stderr.
128 void WIN_WalkWindows( HWND32 hwnd, int indent )
130 WND *ptr;
131 char className[80];
133 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
134 if (!ptr)
136 fprintf( stderr, "*** Invalid window handle %04x\n", hwnd );
137 return;
140 if (!indent) /* first time around */
141 fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
142 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
144 while (ptr)
146 fprintf(stderr, "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
148 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
150 fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %08x\n",
151 (DWORD)ptr, ptr->hmemTaskQ, className,
152 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc );
154 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
155 ptr = ptr->next;
160 /***********************************************************************
161 * WIN_GetXWindow
163 * Return the X window associated to a window.
165 Window WIN_GetXWindow( HWND32 hwnd )
167 WND *wndPtr = WIN_FindWndPtr( hwnd );
168 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
169 return wndPtr ? wndPtr->window : 0;
173 /***********************************************************************
174 * WIN_UnlinkWindow
176 * Remove a window from the siblings linked list.
178 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
180 WND *wndPtr, **ppWnd;
182 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
183 ppWnd = &wndPtr->parent->child;
184 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
185 *ppWnd = wndPtr->next;
186 return TRUE;
190 /***********************************************************************
191 * WIN_LinkWindow
193 * Insert a window into the siblings linked list.
194 * The window is inserted after the specified window, which can also
195 * be specified as HWND_TOP or HWND_BOTTOM.
197 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
199 WND *wndPtr, **ppWnd;
201 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
203 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
205 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
206 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
207 while (*ppWnd) ppWnd = &(*ppWnd)->next;
209 else /* Normal case */
211 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
212 if (!afterPtr) return FALSE;
213 ppWnd = &afterPtr->next;
215 wndPtr->next = *ppWnd;
216 *ppWnd = wndPtr;
217 return TRUE;
221 /***********************************************************************
222 * WIN_FindWinToRepaint
224 * Find a window that needs repaint.
226 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
228 HWND32 hwndRet;
229 WND *pWnd = pWndDesktop;
231 /* Note: the desktop window never gets WM_PAINT messages
232 * The real reason why is because Windows DesktopWndProc
233 * does ValidateRgn inside WM_ERASEBKGND handler.
236 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
238 for ( ; pWnd ; pWnd = pWnd->next )
240 if (!(pWnd->dwStyle & WS_VISIBLE) || (pWnd->flags & WIN_NO_REDRAW))
242 dprintf_win( stddeb, "FindWinToRepaint: skipping window %04x\n",
243 pWnd->hwndSelf );
244 continue;
246 if ((pWnd->hmemTaskQ == hQueue) &&
247 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
249 if (pWnd->child )
250 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
251 return hwndRet;
254 if (!pWnd) return 0;
256 hwndRet = pWnd->hwndSelf;
258 /* look among siblings if we got a transparent window */
259 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
260 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
262 pWnd = pWnd->next;
264 if (pWnd) hwndRet = pWnd->hwndSelf;
265 dprintf_win(stddeb,"FindWinToRepaint: found %04x\n",hwndRet);
266 return hwndRet;
270 /***********************************************************************
271 * WIN_SendParentNotify
273 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
274 * the window has the WS_EX_NOPARENTNOTIFY style.
276 void WIN_SendParentNotify(HWND32 hwnd, WORD event, WORD idChild, LPARAM lValue)
278 LPPOINT16 lppt = (LPPOINT16)&lValue;
279 WND *wndPtr = WIN_FindWndPtr( hwnd );
280 BOOL32 bMouse = ((event <= WM_MOUSELAST) && (event >= WM_MOUSEFIRST));
282 /* if lValue contains cursor coordinates they have to be
283 * mapped to the client area of parent window */
285 if (bMouse) MapWindowPoints16( 0, hwnd, lppt, 1 );
287 while (wndPtr)
289 if ((wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) ||
290 !(wndPtr->dwStyle & WS_CHILD)) break;
292 if (bMouse)
294 lppt->x += wndPtr->rectClient.left;
295 lppt->y += wndPtr->rectClient.top;
298 wndPtr = wndPtr->parent;
299 SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY,
300 MAKEWPARAM( event, idChild ), lValue );
305 /***********************************************************************
306 * WIN_DestroyWindow
308 * Destroy storage associated to a window. "Internals" p.358
310 static WND* WIN_DestroyWindow( WND* wndPtr )
312 HWND32 hwnd = wndPtr->hwndSelf;
313 WND *pWnd;
315 dprintf_win( stddeb, "WIN_DestroyWindow: %04x\n", wndPtr->hwndSelf );
317 #ifdef CONFIG_IPC
318 if (main_block)
319 DDE_DestroyWindow(wndPtr->hwndSelf);
320 #endif /* CONFIG_IPC */
322 /* free child windows */
324 while ((pWnd = wndPtr->child))
325 wndPtr->child = WIN_DestroyWindow( pWnd );
327 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
329 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
331 WINPOS_CheckActive( hwnd );
332 if( hwnd == GetCapture32()) ReleaseCapture();
334 /* free resources associated with the window */
336 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
337 PROPERTY_RemoveWindowProps( wndPtr );
339 wndPtr->dwMagic = 0; /* Mark it as invalid */
340 wndPtr->hwndSelf = 0;
342 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
344 if (wndPtr->hrgnUpdate) DeleteObject32( wndPtr->hrgnUpdate );
345 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
348 /* toss stale messages from the queue */
350 if( wndPtr->hmemTaskQ )
352 int pos;
353 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
355 while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
356 QUEUE_RemoveMsg(msgQ, pos);
357 wndPtr->hmemTaskQ = 0;
360 if (!(wndPtr->dwStyle & WS_CHILD))
361 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
362 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
363 if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
364 if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->dce );
366 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
368 wndPtr->class->cWindows--;
369 wndPtr->class = NULL;
370 pWnd = wndPtr->next;
372 USER_HEAP_FREE( hwnd );
373 return pWnd;
376 /***********************************************************************
377 * WIN_ResetQueueWindows
379 void WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
381 WND* next;
383 while (wnd)
385 next = wnd->next;
386 if (wnd->hmemTaskQ == hQueue)
387 if( hNew ) wnd->hmemTaskQ = hNew;
388 else DestroyWindow32( wnd->hwndSelf );
389 else WIN_ResetQueueWindows( wnd->child, hQueue, hNew );
390 wnd = next;
394 /***********************************************************************
395 * WIN_CreateDesktopWindow
397 * Create the desktop window.
399 BOOL32 WIN_CreateDesktopWindow(void)
401 CLASS *class;
402 HWND32 hwndDesktop;
404 dprintf_win(stddeb,"Creating desktop window\n");
406 if (!(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
407 return FALSE;
409 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
410 if (!hwndDesktop) return FALSE;
411 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
413 pWndDesktop->next = NULL;
414 pWndDesktop->child = NULL;
415 pWndDesktop->parent = NULL;
416 pWndDesktop->owner = NULL;
417 pWndDesktop->class = class;
418 pWndDesktop->dwMagic = WND_MAGIC;
419 pWndDesktop->hwndSelf = hwndDesktop;
420 pWndDesktop->hInstance = 0;
421 pWndDesktop->rectWindow.left = 0;
422 pWndDesktop->rectWindow.top = 0;
423 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
424 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
425 pWndDesktop->rectClient = pWndDesktop->rectWindow;
426 pWndDesktop->rectNormal = pWndDesktop->rectWindow;
427 pWndDesktop->ptIconPos.x = -1;
428 pWndDesktop->ptIconPos.y = -1;
429 pWndDesktop->ptMaxPos.x = -1;
430 pWndDesktop->ptMaxPos.y = -1;
431 pWndDesktop->text = NULL;
432 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
433 pWndDesktop->hrgnUpdate = 0;
434 pWndDesktop->hwndLastActive = hwndDesktop;
435 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
436 WS_CLIPSIBLINGS;
437 pWndDesktop->dwExStyle = 0;
438 pWndDesktop->dce = NULL;
439 pWndDesktop->pVScroll = NULL;
440 pWndDesktop->pHScroll = NULL;
441 pWndDesktop->pProp = NULL;
442 pWndDesktop->wIDmenu = 0;
443 pWndDesktop->flags = 0;
444 pWndDesktop->window = rootWindow;
445 pWndDesktop->hSysMenu = 0;
446 pWndDesktop->userdata = 0;
448 pWndDesktop->winproc = (WNDPROC16)class->winproc;
450 EVENT_RegisterWindow( pWndDesktop );
451 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
452 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
453 return TRUE;
457 /***********************************************************************
458 * WIN_CreateWindowEx
460 * Implementation of CreateWindowEx().
462 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
463 BOOL32 win32, BOOL32 unicode )
465 CLASS *classPtr;
466 WND *wndPtr;
467 HWND16 hwnd, hwndLinkAfter;
468 POINT16 maxSize, maxPos, minTrack, maxTrack;
469 LRESULT (*localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
471 dprintf_win( stddeb, "CreateWindowEx: " );
472 if (HIWORD(cs->lpszName)) dprintf_win( stddeb, "'%s' ", cs->lpszName );
473 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszName) );
474 if (HIWORD(cs->lpszClass)) dprintf_win( stddeb, "'%s' ", cs->lpszClass );
475 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszClass) );
477 dprintf_win( stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %p\n",
478 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
479 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
481 /* Find the parent window */
483 if (cs->hwndParent)
485 /* Make sure parent is valid */
486 if (!IsWindow32( cs->hwndParent ))
488 fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
489 return 0;
492 else if (cs->style & WS_CHILD)
494 fprintf( stderr, "CreateWindowEx: no parent for child window\n" );
495 return 0; /* WS_CHILD needs a parent */
498 /* Find the window class */
500 if (!(classPtr = CLASS_FindClassByAtom( classAtom,
501 GetExePtr(cs->hInstance) )))
503 char buffer[256];
504 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
505 fprintf( stderr, "CreateWindowEx: bad class '%s'\n", buffer );
506 return 0;
509 /* Fix the coordinates */
511 if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0;
512 if (cs->cx == CW_USEDEFAULT32)
514 /* if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0;
515 else */
517 cs->cx = 600;
518 cs->cy = 400;
522 /* Create the window structure */
524 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
525 - sizeof(wndPtr->wExtra) )))
527 dprintf_win( stddeb, "CreateWindowEx: out of memory\n" );
528 return 0;
531 /* Fill the window structure */
533 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
534 wndPtr->next = NULL;
535 wndPtr->child = NULL;
537 if (cs->style & WS_CHILD)
539 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
540 wndPtr->owner = NULL;
542 else
544 wndPtr->parent = pWndDesktop;
545 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
546 wndPtr->owner = NULL;
547 else
548 wndPtr->owner = WIN_FindWndPtr(WIN_GetTopParent(cs->hwndParent));
551 wndPtr->window = 0;
552 wndPtr->class = classPtr;
553 wndPtr->winproc = classPtr->winproc;
554 wndPtr->dwMagic = WND_MAGIC;
555 wndPtr->hwndSelf = hwnd;
556 wndPtr->hInstance = cs->hInstance;
557 wndPtr->ptIconPos.x = -1;
558 wndPtr->ptIconPos.y = -1;
559 wndPtr->ptMaxPos.x = -1;
560 wndPtr->ptMaxPos.y = -1;
561 wndPtr->text = NULL;
562 wndPtr->hmemTaskQ = GetTaskQueue(0);
563 wndPtr->hrgnUpdate = 0;
564 wndPtr->hwndLastActive = hwnd;
565 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
566 wndPtr->dwExStyle = cs->dwExStyle;
567 wndPtr->wIDmenu = 0;
568 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
569 wndPtr->pVScroll = NULL;
570 wndPtr->pHScroll = NULL;
571 wndPtr->pProp = NULL;
572 wndPtr->hSysMenu = MENU_GetDefSysMenu();
573 wndPtr->userdata = 0;
575 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
577 /* Call the WH_CBT hook */
579 hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
581 if (HOOK_IsHooked( WH_CBT ))
583 CBT_CREATEWND32A cbtc;
585 cbtc.lpcs = cs;
586 cbtc.hwndInsertAfter = hwndLinkAfter;
587 if ( HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc) )
589 dprintf_win(stddeb, "CreateWindowEx: CBT-hook returned 0\n");
590 USER_HEAP_FREE( hwnd );
591 return 0;
595 /* Increment class window counter */
597 classPtr->cWindows++;
599 /* Correct the window style */
601 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
603 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
604 wndPtr->flags |= WIN_NEED_SIZE;
606 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
608 /* Get class or window DC if needed */
610 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
611 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
612 else wndPtr->dce = NULL;
614 /* Insert the window in the linked list */
616 WIN_LinkWindow( hwnd, hwndLinkAfter );
618 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
620 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
622 NC_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack );
623 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
624 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
625 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
626 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
628 if (cs->cx <= 0) cs->cx = 1;
629 if (cs->cy <= 0) cs->cy = 1;
631 wndPtr->rectWindow.left = cs->x;
632 wndPtr->rectWindow.top = cs->y;
633 wndPtr->rectWindow.right = cs->x + cs->cx;
634 wndPtr->rectWindow.bottom = cs->y + cs->cy;
635 wndPtr->rectClient = wndPtr->rectWindow;
636 wndPtr->rectNormal = wndPtr->rectWindow;
638 /* Create the X window (only for top-level windows, and then only */
639 /* when there's no desktop window) */
641 if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
643 XSetWindowAttributes win_attr;
645 if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
646 (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
648 win_attr.event_mask = ExposureMask | KeyPressMask |
649 KeyReleaseMask | PointerMotionMask |
650 ButtonPressMask | ButtonReleaseMask |
651 FocusChangeMask | StructureNotifyMask;
652 win_attr.override_redirect = FALSE;
653 wndPtr->flags |= WIN_MANAGED;
655 else
657 win_attr.event_mask = ExposureMask | KeyPressMask |
658 KeyReleaseMask | PointerMotionMask |
659 ButtonPressMask | ButtonReleaseMask |
660 FocusChangeMask | StructureNotifyMask;
661 win_attr.override_redirect = TRUE;
663 win_attr.colormap = COLOR_GetColormap();
664 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
665 win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
666 win_attr.cursor = CURSORICON_XCursor;
667 wndPtr->window = XCreateWindow( display, rootWindow, cs->x, cs->y,
668 cs->cx, cs->cy, 0, CopyFromParent,
669 InputOutput, CopyFromParent,
670 CWEventMask | CWOverrideRedirect |
671 CWColormap | CWCursor | CWSaveUnder |
672 CWBackingStore, &win_attr );
674 if ((wndPtr->flags & WIN_MANAGED) &&
675 (cs->dwExStyle & WS_EX_DLGMODALFRAME))
677 XSizeHints* size_hints = XAllocSizeHints();
679 if (size_hints)
681 size_hints->min_width = size_hints->max_width = cs->cx;
682 size_hints->min_height = size_hints->max_height = cs->cy;
683 size_hints->flags = (PSize | PMinSize | PMaxSize);
684 XSetWMSizeHints( display, wndPtr->window, size_hints,
685 XA_WM_NORMAL_HINTS );
686 XFree(size_hints);
690 if (cs->hwndParent) /* Get window owner */
692 Window win = WIN_GetXWindow( cs->hwndParent );
693 if (win) XSetTransientForHint( display, wndPtr->window, win );
695 EVENT_RegisterWindow( wndPtr );
698 /* Set the window menu */
700 if ((cs->style & WS_CAPTION) && !(cs->style & WS_CHILD))
702 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
703 else
705 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
706 if (classPtr->menuNameA)
707 cs->hMenu = HIWORD(classPtr->menuNameA) ?
708 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
709 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
710 #else
711 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
712 if (menuName) cs->hMenu = LoadMenu16( cs->hInstance, menuName );
713 #endif
715 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
717 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
719 /* Send the WM_CREATE message
720 * Perhaps we shouldn't allow width/height changes as well.
721 * See p327 in "Internals".
724 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
726 localSend32 = unicode ? SendMessage32W : SendMessage32A;
727 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
729 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
730 NULL, NULL, 0, &wndPtr->rectClient );
731 OffsetRect16(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
732 maxPos.y - wndPtr->rectWindow.top);
733 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
735 /* Send the size messages */
737 if (!(wndPtr->flags & WIN_NEED_SIZE))
739 /* send it anyway */
740 SendMessage16( hwnd, WM_SIZE, SIZE_RESTORED,
741 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
742 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
743 SendMessage16( hwnd, WM_MOVE, 0, MAKELONG( wndPtr->rectClient.left,
744 wndPtr->rectClient.top ));
747 WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LPARAM)hwnd );
748 if (!IsWindow32(hwnd)) return 0;
750 /* Show the window, maximizing or minimizing if needed */
752 if (wndPtr->dwStyle & WS_MINIMIZE)
754 /* MinMaximize(hwnd, SW_SHOWMINNOACTIVE, 1) in "Internals" */
756 wndPtr->dwStyle &= ~WS_MAXIMIZE;
757 WINPOS_FindIconPos( hwnd );
758 SetWindowPos32( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
759 SYSMETRICS_CXICON, SYSMETRICS_CYICON,
760 SWP_FRAMECHANGED | ((GetActiveWindow32())? SWP_NOACTIVATE : 0) );
762 else if (wndPtr->dwStyle & WS_MAXIMIZE)
764 /* MinMaximize(hwnd, SW_SHOWMAXIMIZED, 1) */
766 NC_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack );
767 SetWindowPos32( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
768 ((GetActiveWindow32())? SWP_NOACTIVATE : 0) | SWP_FRAMECHANGED );
771 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
773 /* Call WH_SHELL hook */
775 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
776 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
778 dprintf_win(stddeb, "CreateWindowEx: created window %04x\n", hwnd);
779 return hwnd;
783 /* Abort window creation */
785 dprintf_win(stddeb,"CreateWindowEx: aborted by WM_xxCREATE!\n");
786 WIN_UnlinkWindow( hwnd );
787 WIN_DestroyWindow( wndPtr );
788 return 0;
792 /***********************************************************************
793 * CreateWindow16 (USER.41)
795 HWND16 CreateWindow16( LPCSTR className, LPCSTR windowName,
796 DWORD style, INT16 x, INT16 y, INT16 width,
797 INT16 height, HWND16 parent, HMENU16 menu,
798 HINSTANCE16 instance, LPVOID data )
800 return CreateWindowEx16( 0, className, windowName, style,
801 x, y, width, height, parent, menu, instance, data );
805 /***********************************************************************
806 * CreateWindowEx16 (USER.452)
808 HWND16 CreateWindowEx16( DWORD exStyle, LPCSTR className, LPCSTR windowName,
809 DWORD style, INT16 x, INT16 y, INT16 width,
810 INT16 height, HWND16 parent, HMENU16 menu,
811 HINSTANCE16 instance, LPVOID data )
813 ATOM classAtom;
814 CREATESTRUCT32A cs;
816 /* Find the class atom */
818 if (!(classAtom = GlobalFindAtom32A( className )))
820 fprintf( stderr, "CreateWindowEx16: bad class name " );
821 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
822 else fprintf( stderr, "'%s'\n", className );
823 return 0;
826 /* Fix the coordinates */
828 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
829 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
830 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
831 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
833 /* Create the window */
835 cs.lpCreateParams = data;
836 cs.hInstance = (HINSTANCE32)instance;
837 cs.hMenu = (HMENU32)menu;
838 cs.hwndParent = (HWND32)parent;
839 cs.style = style;
840 cs.lpszName = windowName;
841 cs.lpszClass = className;
842 cs.dwExStyle = exStyle;
843 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
847 /***********************************************************************
848 * CreateWindowEx32A (USER32.82)
850 HWND32 CreateWindowEx32A( DWORD exStyle, LPCSTR className, LPCSTR windowName,
851 DWORD style, INT32 x, INT32 y, INT32 width,
852 INT32 height, HWND32 parent, HMENU32 menu,
853 HINSTANCE32 instance, LPVOID data )
855 ATOM classAtom;
856 CREATESTRUCT32A cs;
858 /* Find the class atom */
860 if (!(classAtom = GlobalFindAtom32A( className )))
862 fprintf( stderr, "CreateWindowEx32A: bad class name " );
863 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
864 else fprintf( stderr, "'%s'\n", className );
865 return 0;
868 /* Create the window */
870 cs.lpCreateParams = data;
871 cs.hInstance = instance;
872 cs.hMenu = menu;
873 cs.hwndParent = parent;
874 cs.x = x;
875 cs.y = y;
876 cs.cx = width;
877 cs.cy = height;
878 cs.style = style;
879 cs.lpszName = windowName;
880 cs.lpszClass = className;
881 cs.dwExStyle = exStyle;
882 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
886 /***********************************************************************
887 * CreateWindowEx32W (USER32.83)
889 HWND32 CreateWindowEx32W( DWORD exStyle, LPCWSTR className, LPCWSTR windowName,
890 DWORD style, INT32 x, INT32 y, INT32 width,
891 INT32 height, HWND32 parent, HMENU32 menu,
892 HINSTANCE32 instance, LPVOID data )
894 ATOM classAtom;
895 CREATESTRUCT32W cs;
897 /* Find the class atom */
899 if (!(classAtom = GlobalFindAtom32W( className )))
901 if (HIWORD(className))
903 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
904 fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
905 HeapFree( GetProcessHeap(), 0, cn );
907 else
908 fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
909 return 0;
912 /* Create the window */
914 cs.lpCreateParams = data;
915 cs.hInstance = instance;
916 cs.hMenu = menu;
917 cs.hwndParent = parent;
918 cs.x = x;
919 cs.y = y;
920 cs.cx = width;
921 cs.cy = height;
922 cs.style = style;
923 cs.lpszName = windowName;
924 cs.lpszClass = className;
925 cs.dwExStyle = exStyle;
926 /* Note: we rely on the fact that CREATESTRUCT32A and */
927 /* CREATESTRUCT32W have the same layout. */
928 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
932 /***********************************************************************
933 * WIN_CheckFocus
935 static void WIN_CheckFocus( WND* pWnd )
937 if( GetFocus16() == pWnd->hwndSelf )
938 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
941 /***********************************************************************
942 * WIN_SendDestroyMsg
944 static void WIN_SendDestroyMsg( WND* pWnd )
946 WND* pChild;
948 WIN_CheckFocus(pWnd);
950 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
951 if( !pWnd->window ) CLIPBOARD_DisOwn( pWnd );
953 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
955 if( !IsWindow32(pWnd->hwndSelf) )
957 dprintf_win(stddeb,"\tdestroyed itself while in WM_DESTROY!\n");
958 return;
961 pChild = pWnd->child;
962 while( pChild )
964 WIN_SendDestroyMsg( pChild );
965 pChild = pChild->next;
967 WIN_CheckFocus(pWnd);
971 /***********************************************************************
972 * DestroyWindow (USER.53)
974 BOOL16 DestroyWindow16( HWND16 hwnd )
976 return DestroyWindow32(hwnd);
978 /***********************************************************************
979 * DestroyWindow (USER32.134)
981 BOOL32 DestroyWindow32( HWND32 hwnd )
983 WND * wndPtr;
985 dprintf_win(stddeb, "DestroyWindow(%04x)\n", hwnd);
987 /* Initialization */
989 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
990 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
992 /* Call hooks */
994 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
995 return FALSE;
997 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
999 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
1000 /* FIXME: clean up palette - see "Internals" p.352 */
1003 if( !QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ) )
1004 WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
1005 if (!IsWindow32(hwnd)) return TRUE;
1007 if( wndPtr->window ) CLIPBOARD_DisOwn( wndPtr ); /* before window is unmapped */
1009 /* Hide the window */
1011 if (wndPtr->dwStyle & WS_VISIBLE)
1013 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
1014 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
1015 ((QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
1016 if (!IsWindow32(hwnd)) return TRUE;
1019 /* Recursively destroy owned windows */
1021 if( !(wndPtr->dwStyle & WS_CHILD) )
1023 for (;;)
1025 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1026 while (siblingPtr)
1028 if (siblingPtr->owner == wndPtr)
1029 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1030 break;
1031 else
1032 siblingPtr->owner = NULL;
1033 siblingPtr = siblingPtr->next;
1035 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1036 else break;
1039 if( !Options.managed || EVENT_CheckFocus() )
1040 WINPOS_ActivateOtherWindow(wndPtr);
1042 if( wndPtr->owner &&
1043 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1044 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1047 /* Send destroy messages */
1049 WIN_SendDestroyMsg( wndPtr );
1050 if (!IsWindow32(hwnd)) return TRUE;
1052 /* Unlink now so we won't bother with the children later on */
1054 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1056 /* Destroy the window storage */
1058 WIN_DestroyWindow( wndPtr );
1059 return TRUE;
1063 /***********************************************************************
1064 * CloseWindow16 (USER.43)
1066 BOOL16 CloseWindow16( HWND16 hwnd )
1068 return CloseWindow32( hwnd );
1072 /***********************************************************************
1073 * CloseWindow32 (USER32.55)
1075 BOOL32 CloseWindow32( HWND32 hwnd )
1077 WND * wndPtr = WIN_FindWndPtr( hwnd );
1078 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1079 ShowWindow32( hwnd, SW_MINIMIZE );
1080 return TRUE;
1084 /***********************************************************************
1085 * OpenIcon16 (USER.44)
1087 BOOL16 OpenIcon16( HWND16 hwnd )
1089 return OpenIcon32( hwnd );
1093 /***********************************************************************
1094 * OpenIcon32 (USER32.409)
1096 BOOL32 OpenIcon32( HWND32 hwnd )
1098 if (!IsIconic32( hwnd )) return FALSE;
1099 ShowWindow32( hwnd, SW_SHOWNORMAL );
1100 return TRUE;
1104 /***********************************************************************
1105 * WIN_FindWindow
1107 * Implementation of FindWindow() and FindWindowEx().
1109 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1110 LPCSTR title )
1112 WND *pWnd;
1113 CLASS *pClass = NULL;
1115 if (child)
1117 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1118 if (parent)
1120 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1122 else if (pWnd->parent != pWndDesktop) return 0;
1123 pWnd = pWnd->next;
1125 else
1127 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1128 pWnd = pWnd->child;
1130 if (!pWnd) return 0;
1132 /* For a child window, all siblings will have the same hInstance, */
1133 /* so we can look for the class once and for all. */
1135 if (className && (pWnd->dwStyle & WS_CHILD))
1137 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1138 return 0;
1141 for ( ; pWnd; pWnd = pWnd->next)
1143 if (className && !(pWnd->dwStyle & WS_CHILD))
1145 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance)))
1146 continue; /* Skip this window */
1148 if (pClass && (pWnd->class != pClass))
1149 continue; /* Not the right class */
1151 /* Now check the title */
1153 if (!title) return pWnd->hwndSelf;
1154 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1156 return 0;
1161 /***********************************************************************
1162 * FindWindow16 (USER.50)
1164 HWND16 FindWindow16( SEGPTR className, LPCSTR title )
1166 return FindWindowEx16( 0, 0, className, title );
1170 /***********************************************************************
1171 * FindWindowEx16 (USER.427)
1173 HWND16 FindWindowEx16( HWND16 parent, HWND16 child,
1174 SEGPTR className, LPCSTR title )
1176 ATOM atom = 0;
1178 if (className)
1180 /* If the atom doesn't exist, then no class */
1181 /* with this name exists either. */
1182 if (!(atom = GlobalFindAtom16( className ))) return 0;
1184 return WIN_FindWindow( parent, child, atom, title );
1188 /***********************************************************************
1189 * FindWindow32A (USER32.197)
1191 HWND32 FindWindow32A( LPCSTR className, LPCSTR title )
1193 return FindWindowEx32A( 0, 0, className, title );
1197 /***********************************************************************
1198 * FindWindowEx32A (USER32.198)
1200 HWND32 FindWindowEx32A( HWND32 parent, HWND32 child,
1201 LPCSTR className, LPCSTR title )
1203 ATOM atom = 0;
1205 if (className)
1207 /* If the atom doesn't exist, then no class */
1208 /* with this name exists either. */
1209 if (!(atom = GlobalFindAtom32A( className ))) return 0;
1211 return WIN_FindWindow( 0, 0, atom, title );
1215 /***********************************************************************
1216 * FindWindowEx32W (USER32.199)
1218 HWND32 FindWindowEx32W( HWND32 parent, HWND32 child,
1219 LPCWSTR className, LPCWSTR title )
1221 ATOM atom = 0;
1222 char *buffer;
1223 HWND32 hwnd;
1225 if (className)
1227 /* If the atom doesn't exist, then no class */
1228 /* with this name exists either. */
1229 if (!(atom = GlobalFindAtom32W( className ))) return 0;
1231 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1232 hwnd = WIN_FindWindow( 0, 0, atom, buffer );
1233 HeapFree( GetProcessHeap(), 0, buffer );
1234 return hwnd;
1238 /***********************************************************************
1239 * FindWindow32W (USER32.200)
1241 HWND32 FindWindow32W( LPCWSTR className, LPCWSTR title )
1243 return FindWindowEx32W( 0, 0, className, title );
1247 /**********************************************************************
1248 * WIN_GetDesktop
1250 WND *WIN_GetDesktop(void)
1252 return pWndDesktop;
1256 /**********************************************************************
1257 * GetDesktopWindow16 (USER.286)
1259 HWND16 GetDesktopWindow16(void)
1261 return (HWND16)pWndDesktop->hwndSelf;
1265 /**********************************************************************
1266 * GetDesktopWindow32 (USER32.231)
1268 HWND32 GetDesktopWindow32(void)
1270 return pWndDesktop->hwndSelf;
1274 /**********************************************************************
1275 * GetDesktopHwnd (USER.278)
1277 * Exactly the same thing as GetDesktopWindow(), but not documented.
1278 * Don't ask me why...
1280 HWND16 GetDesktopHwnd(void)
1282 return (HWND16)pWndDesktop->hwndSelf;
1286 /*******************************************************************
1287 * EnableWindow16 (USER.34)
1289 BOOL16 EnableWindow16( HWND16 hwnd, BOOL16 enable )
1291 return EnableWindow32( hwnd, enable );
1295 /*******************************************************************
1296 * EnableWindow32 (USER32.171)
1298 BOOL32 EnableWindow32( HWND32 hwnd, BOOL32 enable )
1300 WND *wndPtr;
1302 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1303 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1305 /* Enable window */
1306 wndPtr->dwStyle &= ~WS_DISABLED;
1307 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1308 return TRUE;
1310 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1312 /* Disable window */
1313 wndPtr->dwStyle |= WS_DISABLED;
1314 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1315 SetFocus32( 0 ); /* A disabled window can't have the focus */
1316 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1317 ReleaseCapture(); /* A disabled window can't capture the mouse */
1318 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1319 return FALSE;
1321 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1325 /***********************************************************************
1326 * IsWindowEnabled16 (USER.35)
1328 BOOL16 IsWindowEnabled16(HWND16 hWnd)
1330 return IsWindowEnabled32(hWnd);
1334 /***********************************************************************
1335 * IsWindowEnabled32 (USER32.348)
1337 BOOL32 IsWindowEnabled32(HWND32 hWnd)
1339 WND * wndPtr;
1341 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1342 return !(wndPtr->dwStyle & WS_DISABLED);
1346 /***********************************************************************
1347 * IsWindowUnicode (USER32.349)
1349 BOOL32 IsWindowUnicode( HWND32 hwnd )
1351 WND * wndPtr;
1353 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1354 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1358 /**********************************************************************
1359 * GetWindowWord16 (USER.133)
1361 WORD GetWindowWord16( HWND16 hwnd, INT16 offset )
1363 return GetWindowWord32( hwnd, offset );
1367 /**********************************************************************
1368 * GetWindowWord32 (USER32.313)
1370 WORD GetWindowWord32( HWND32 hwnd, INT32 offset )
1372 WND * wndPtr = WIN_FindWndPtr( hwnd );
1373 if (!wndPtr) return 0;
1374 if (offset >= 0)
1376 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1378 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1379 return 0;
1381 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1383 switch(offset)
1385 case GWW_ID: return wndPtr->wIDmenu;
1386 case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
1387 case GWW_HINSTANCE: return (WORD)wndPtr->hInstance;
1388 default:
1389 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1390 return 0;
1395 /**********************************************************************
1396 * WIN_GetWindowInstance
1398 HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd )
1400 WND * wndPtr = WIN_FindWndPtr( hwnd );
1401 if (!wndPtr) return (HINSTANCE16)0;
1402 return wndPtr->hInstance;
1406 /**********************************************************************
1407 * SetWindowWord16 (USER.134)
1409 WORD SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1411 return SetWindowWord32( hwnd, offset, newval );
1415 /**********************************************************************
1416 * SetWindowWord32 (USER32.523)
1418 WORD SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1420 WORD *ptr, retval;
1421 WND * wndPtr = WIN_FindWndPtr( hwnd );
1422 if (!wndPtr) return 0;
1423 if (offset >= 0)
1425 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1427 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1428 return 0;
1430 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1432 else switch(offset)
1434 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1435 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1436 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1437 default:
1438 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1439 return 0;
1441 retval = *ptr;
1442 *ptr = newval;
1443 return retval;
1447 /**********************************************************************
1448 * WIN_GetWindowLong
1450 * Helper function for GetWindowLong().
1452 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1454 LONG retval;
1455 WND * wndPtr = WIN_FindWndPtr( hwnd );
1456 if (!wndPtr) return 0;
1457 if (offset >= 0)
1459 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1461 fprintf( stderr, "GetWindowLong: invalid offset %d\n", offset );
1462 return 0;
1464 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1465 /* Special case for dialog window procedure */
1466 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1467 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1468 return retval;
1470 switch(offset)
1472 case GWL_USERDATA: return wndPtr->userdata;
1473 case GWL_STYLE: return wndPtr->dwStyle;
1474 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1475 case GWL_ID: return wndPtr->wIDmenu;
1476 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1477 type );
1478 case GWL_HWNDPARENT: return wndPtr->parent ?
1479 (HWND32)wndPtr->parent->hwndSelf : 0;
1480 case GWL_HINSTANCE: return (HINSTANCE32)wndPtr->hInstance;
1481 default:
1482 fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
1484 return 0;
1488 /**********************************************************************
1489 * WIN_SetWindowLong
1491 * Helper function for SetWindowLong().
1493 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1494 WINDOWPROCTYPE type )
1496 LONG *ptr, retval;
1497 WND * wndPtr = WIN_FindWndPtr( hwnd );
1498 if (!wndPtr) return 0;
1499 if (offset >= 0)
1501 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1503 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1504 return 0;
1506 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1507 /* Special case for dialog window procedure */
1508 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1510 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1511 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1512 type, WIN_PROC_WINDOW );
1513 return retval;
1516 else switch(offset)
1518 case GWL_ID:
1519 case GWL_HINSTANCE:
1520 return SetWindowWord32( hwnd, offset, (WORD)newval );
1521 case GWL_WNDPROC:
1522 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1523 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1524 type, WIN_PROC_WINDOW );
1525 return retval;
1526 case GWL_STYLE:
1528 /* FIXME: WM_STYLE... messages for WIN_ISWIN32 windows */
1530 ptr = &wndPtr->dwStyle;
1531 /* Some bits can't be changed this way */
1532 newval &= ~(WS_VISIBLE | WS_CHILD);
1533 newval |= (*ptr & (WS_VISIBLE | WS_CHILD));
1534 break;
1535 case GWL_USERDATA: ptr = &wndPtr->userdata; break;
1536 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
1537 default:
1538 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1539 return 0;
1541 retval = *ptr;
1542 *ptr = newval;
1543 return retval;
1547 /**********************************************************************
1548 * GetWindowLong16 (USER.135)
1550 LONG GetWindowLong16( HWND16 hwnd, INT16 offset )
1552 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1556 /**********************************************************************
1557 * GetWindowLong32A (USER32.304)
1559 LONG GetWindowLong32A( HWND32 hwnd, INT32 offset )
1561 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1565 /**********************************************************************
1566 * GetWindowLong32W (USER32.305)
1568 LONG GetWindowLong32W( HWND32 hwnd, INT32 offset )
1570 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1574 /**********************************************************************
1575 * SetWindowLong16 (USER.136)
1577 LONG SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1579 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1583 /**********************************************************************
1584 * SetWindowLong32A (USER32.516)
1586 LONG SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1588 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1592 /**********************************************************************
1593 * SetWindowLong32W (USER32.517)
1595 LONG SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
1597 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1601 /*******************************************************************
1602 * GetWindowText16 (USER.36)
1604 INT16 GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1606 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1610 /*******************************************************************
1611 * GetWindowText32A (USER32.308)
1613 INT32 GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1615 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1616 (LPARAM)lpString );
1620 /*******************************************************************
1621 * GetWindowText32W (USER32.311)
1623 INT32 GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1625 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1626 (LPARAM)lpString );
1630 /*******************************************************************
1631 * SetWindowText16 (USER.37)
1633 void SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1635 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1639 /*******************************************************************
1640 * SetWindowText32A (USER32.)
1642 void SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1644 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1648 /*******************************************************************
1649 * SetWindowText32W (USER32.)
1651 void SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1653 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1657 /*******************************************************************
1658 * GetWindowTextLength16 (USER.38)
1660 INT16 GetWindowTextLength16( HWND16 hwnd )
1662 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1666 /*******************************************************************
1667 * GetWindowTextLength32A (USER32.309)
1669 INT32 GetWindowTextLength32A( HWND32 hwnd )
1671 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1674 /*******************************************************************
1675 * GetWindowTextLength32W (USER32.309)
1677 INT32 GetWindowTextLength32W( HWND32 hwnd )
1679 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1683 /*******************************************************************
1684 * IsWindow16 (USER.47)
1686 BOOL16 IsWindow16( HWND16 hwnd )
1688 return IsWindow32( hwnd );
1692 /*******************************************************************
1693 * IsWindow32 (USER32.347)
1695 BOOL32 IsWindow32( HWND32 hwnd )
1697 WND * wndPtr = WIN_FindWndPtr( hwnd );
1698 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1702 /*****************************************************************
1703 * GetParent16 (USER.46)
1705 HWND16 GetParent16( HWND16 hwnd )
1707 return (HWND16)GetParent32( hwnd );
1711 /*****************************************************************
1712 * GetParent32 (USER32.277)
1714 HWND32 GetParent32( HWND32 hwnd )
1716 WND *wndPtr = WIN_FindWndPtr(hwnd);
1717 if (!wndPtr) return 0;
1718 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1719 return wndPtr ? wndPtr->hwndSelf : 0;
1723 /*****************************************************************
1724 * WIN_GetTopParent
1726 * Get the top-level parent for a child window.
1728 HWND32 WIN_GetTopParent( HWND32 hwnd )
1730 WND *wndPtr = WIN_FindWndPtr( hwnd );
1731 while (wndPtr && (wndPtr->dwStyle & WS_CHILD)) wndPtr = wndPtr->parent;
1732 return wndPtr ? wndPtr->hwndSelf : 0;
1736 /*****************************************************************
1737 * SetParent16 (USER.233)
1739 HWND16 SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1741 return SetParent32( hwndChild, hwndNewParent );
1745 /*****************************************************************
1746 * SetParent32 (USER32.494)
1748 HWND32 SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1750 HWND32 oldParent;
1752 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1753 WND *pWndParent = WIN_FindWndPtr( hwndNewParent );
1754 if (!wndPtr || !pWndParent || !(wndPtr->dwStyle & WS_CHILD)) return 0;
1756 oldParent = wndPtr->parent->hwndSelf;
1758 WIN_UnlinkWindow(hwndChild);
1759 if (hwndNewParent) wndPtr->parent = pWndParent;
1760 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
1762 if (IsWindowVisible32(hwndChild)) UpdateWindow32(hwndChild);
1764 return oldParent;
1768 /*******************************************************************
1769 * IsChild16 (USER.48)
1771 BOOL16 IsChild16( HWND16 parent, HWND16 child )
1773 return IsChild32(parent,child);
1777 /*******************************************************************
1778 * IsChild32 (USER32.338)
1780 BOOL32 IsChild32( HWND32 parent, HWND32 child )
1782 WND * wndPtr = WIN_FindWndPtr( child );
1783 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1785 wndPtr = wndPtr->parent;
1786 if (wndPtr->hwndSelf == parent) return TRUE;
1788 return FALSE;
1792 /***********************************************************************
1793 * IsWindowVisible16 (USER.49)
1795 BOOL16 IsWindowVisible16( HWND16 hwnd )
1797 return IsWindowVisible32(hwnd);
1801 /***********************************************************************
1802 * IsWindowVisible32 (USER32.350)
1804 BOOL32 IsWindowVisible32( HWND32 hwnd )
1806 WND *wndPtr = WIN_FindWndPtr( hwnd );
1807 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1809 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1810 wndPtr = wndPtr->parent;
1812 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1816 /***********************************************************************
1817 * WIN_IsWindowDrawable
1819 * hwnd is drawable when it is visible, all parents are not
1820 * minimized, and it is itself not minimized unless we are
1821 * trying to draw icon and the default class icon is set.
1823 BOOL32 WIN_IsWindowDrawable( WND* wnd , BOOL32 icon )
1825 if( (wnd->dwStyle & WS_MINIMIZE &&
1826 icon && wnd->class->hIcon) ||
1827 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
1828 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
1829 if( wnd->dwStyle & WS_MINIMIZE ||
1830 !(wnd->dwStyle & WS_VISIBLE) ) break;
1831 return (wnd == NULL);
1835 /*******************************************************************
1836 * GetTopWindow16 (USER.229)
1838 HWND16 GetTopWindow16( HWND16 hwnd )
1840 return GetTopWindow32(hwnd);
1844 /*******************************************************************
1845 * GetTopWindow32 (USER.229)
1847 HWND32 GetTopWindow32( HWND32 hwnd )
1849 WND * wndPtr = WIN_FindWndPtr( hwnd );
1850 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1851 else return 0;
1855 /*******************************************************************
1856 * GetWindow16 (USER.262)
1858 HWND16 GetWindow16( HWND16 hwnd, WORD rel )
1860 return GetWindow32( hwnd,rel );
1864 /*******************************************************************
1865 * GetWindow32 (USER32.301)
1867 HWND32 GetWindow32( HWND32 hwnd, WORD rel )
1869 WND * wndPtr = WIN_FindWndPtr( hwnd );
1870 if (!wndPtr) return 0;
1871 switch(rel)
1873 case GW_HWNDFIRST:
1874 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
1875 else return 0;
1877 case GW_HWNDLAST:
1878 if (!wndPtr->parent) return 0; /* Desktop window */
1879 while (wndPtr->next) wndPtr = wndPtr->next;
1880 return wndPtr->hwndSelf;
1882 case GW_HWNDNEXT:
1883 if (!wndPtr->next) return 0;
1884 return wndPtr->next->hwndSelf;
1886 case GW_HWNDPREV:
1887 if (!wndPtr->parent) return 0; /* Desktop window */
1888 wndPtr = wndPtr->parent->child; /* First sibling */
1889 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
1890 while (wndPtr->next)
1892 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
1893 wndPtr = wndPtr->next;
1895 return 0;
1897 case GW_OWNER:
1898 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
1900 case GW_CHILD:
1901 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
1903 return 0;
1907 /*******************************************************************
1908 * GetNextWindow16 (USER.230)
1910 HWND16 GetNextWindow16( HWND16 hwnd, WORD flag )
1912 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1913 return GetWindow16( hwnd, flag );
1916 /*******************************************************************
1917 * ShowOwnedPopups16 (USER.265)
1919 void ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
1921 ShowOwnedPopups32( owner, fShow );
1925 /*******************************************************************
1926 * ShowOwnedPopups32 (USER32.530)
1928 BOOL32 ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
1930 WND *pWnd = pWndDesktop->child;
1931 while (pWnd)
1933 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
1934 (pWnd->dwStyle & WS_POPUP))
1935 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
1936 pWnd = pWnd->next;
1938 return TRUE;
1942 /*******************************************************************
1943 * GetLastActivePopup16 (USER.287)
1945 HWND16 GetLastActivePopup16( HWND16 hwnd )
1947 return GetLastActivePopup32( hwnd );
1950 /*******************************************************************
1951 * GetLastActivePopup32 (USER32.255)
1953 HWND32 GetLastActivePopup32( HWND32 hwnd )
1955 WND *wndPtr;
1956 wndPtr = WIN_FindWndPtr(hwnd);
1957 if (wndPtr == NULL) return hwnd;
1958 return wndPtr->hwndLastActive;
1962 /*******************************************************************
1963 * WIN_BuildWinArray
1965 * Build an array of pointers to all children of a given window.
1966 * The array must be freed with HeapFree(SystemHeap).
1968 WND **WIN_BuildWinArray( WND *wndPtr )
1970 WND **list, **ppWnd;
1971 WND *pWnd;
1972 INT32 count;
1974 /* First count the windows */
1976 if (!wndPtr) wndPtr = pWndDesktop;
1977 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next) count++;
1978 count++; /* For the terminating NULL */
1980 /* Now build the list of all windows */
1982 if (!(list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * count )))
1983 return NULL;
1984 for (pWnd = wndPtr->child, ppWnd = list; pWnd; pWnd = pWnd->next)
1985 *ppWnd++ = pWnd;
1986 *ppWnd = NULL;
1987 return list;
1991 /*******************************************************************
1992 * EnumWindows16 (USER.54)
1994 BOOL16 EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
1996 WND **list, **ppWnd;
1998 /* We have to build a list of all windows first, to avoid */
1999 /* unpleasant side-effects, for instance if the callback */
2000 /* function changes the Z-order of the windows. */
2002 if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
2004 /* Now call the callback function for every window */
2006 for (ppWnd = list; *ppWnd; ppWnd++)
2008 /* Make sure that the window still exists */
2009 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2010 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2012 HeapFree( SystemHeap, 0, list );
2013 return TRUE;
2017 /*******************************************************************
2018 * EnumWindows32 (USER32.192)
2020 BOOL32 EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2022 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2026 /**********************************************************************
2027 * EnumTaskWindows16 (USER.225)
2029 BOOL16 EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func, LPARAM lParam )
2031 WND **list, **ppWnd;
2032 HQUEUE16 hQueue = GetTaskQueue( hTask );
2034 /* This function is the same as EnumWindows(), */
2035 /* except for an added check on the window queue. */
2037 if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
2039 /* Now call the callback function for every window */
2041 for (ppWnd = list; *ppWnd; ppWnd++)
2043 /* Make sure that the window still exists */
2044 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2045 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
2046 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2048 HeapFree( SystemHeap, 0, list );
2049 return TRUE;
2053 /**********************************************************************
2054 * EnumThreadWindows (USER32.189)
2056 BOOL32 EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2058 THDB *tdb = (THDB*)id;
2060 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2064 /**********************************************************************
2065 * WIN_EnumChildWindows
2067 * Helper function for EnumChildWindows().
2069 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2070 LPARAM lParam )
2072 WND **childList;
2073 BOOL16 ret = FALSE;
2075 while (*ppWnd)
2077 /* Make sure that the window still exists */
2078 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2079 /* Build children list first */
2080 if (!(childList = WIN_BuildWinArray( *ppWnd ))) return FALSE;
2081 if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
2082 ret = WIN_EnumChildWindows( childList, func, lParam );
2083 HeapFree( SystemHeap, 0, childList );
2084 if (!ret) return FALSE;
2085 ppWnd++;
2087 return TRUE;
2091 /**********************************************************************
2092 * EnumChildWindows16 (USER.55)
2094 BOOL16 EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func, LPARAM lParam )
2096 WND **list, *pParent;
2098 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2099 if (!(list = WIN_BuildWinArray( pParent ))) return FALSE;
2100 WIN_EnumChildWindows( list, func, lParam );
2101 HeapFree( SystemHeap, 0, list );
2102 return TRUE;
2106 /**********************************************************************
2107 * EnumChildWindows32 (USER32.177)
2109 BOOL32 EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func, LPARAM lParam )
2111 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2112 lParam );
2116 /*******************************************************************
2117 * AnyPopup16 (USER.52)
2119 BOOL16 AnyPopup16(void)
2121 return AnyPopup32();
2125 /*******************************************************************
2126 * AnyPopup32 (USER32.3)
2128 BOOL32 AnyPopup32(void)
2130 WND *wndPtr;
2131 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2132 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2133 return FALSE;
2137 /*******************************************************************
2138 * FlashWindow16 (USER.105)
2140 BOOL16 FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2142 return FlashWindow32( hWnd, bInvert );
2146 /*******************************************************************
2147 * FlashWindow32 (USER32.201)
2149 BOOL32 FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2151 WND *wndPtr = WIN_FindWndPtr(hWnd);
2153 dprintf_win(stddeb,"FlashWindow: %04x\n", hWnd);
2155 if (!wndPtr) return FALSE;
2157 if (wndPtr->dwStyle & WS_MINIMIZE)
2159 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2161 HDC32 hDC = GetDC32(hWnd);
2163 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2164 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2166 ReleaseDC32( hWnd, hDC );
2167 wndPtr->flags |= WIN_NCACTIVATED;
2169 else
2171 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2172 RDW_UPDATENOW | RDW_FRAME, 0 );
2173 wndPtr->flags &= ~WIN_NCACTIVATED;
2175 return TRUE;
2177 else
2179 WPARAM16 wparam;
2180 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2181 else wparam = (hWnd == GetActiveWindow32());
2183 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2184 return wparam;
2189 /*******************************************************************
2190 * SetSysModalWindow16 (USER.188)
2192 HWND16 SetSysModalWindow16( HWND16 hWnd )
2194 HWND32 hWndOldModal = hwndSysModal;
2195 hwndSysModal = hWnd;
2196 dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2197 return hWndOldModal;
2201 /*******************************************************************
2202 * GetSysModalWindow16 (USER.52)
2204 HWND16 GetSysModalWindow16(void)
2206 return hwndSysModal;
2210 /*******************************************************************
2211 * DRAG_QueryUpdate
2213 * recursively find a child that contains spDragInfo->pt point
2214 * and send WM_QUERYDROPOBJECT
2216 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2218 BOOL16 wParam,bResult = 0;
2219 POINT16 pt;
2220 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2221 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2222 RECT16 tempRect;
2224 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2226 pt = ptrDragInfo->pt;
2228 GetWindowRect16(hQueryWnd,&tempRect);
2230 if( !PtInRect16(&tempRect,pt) ||
2231 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2232 return 0;
2234 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2236 tempRect = ptrQueryWnd->rectClient;
2237 if(ptrQueryWnd->dwStyle & WS_CHILD)
2238 MapWindowPoints16(ptrQueryWnd->parent->hwndSelf,0,(LPPOINT16)&tempRect,2);
2240 if( PtInRect16(&tempRect,pt) )
2242 wParam = 0;
2244 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2245 if( ptrWnd->dwStyle & WS_VISIBLE )
2247 GetWindowRect16(ptrWnd->hwndSelf,&tempRect);
2249 if( PtInRect16(&tempRect,pt) )
2250 break;
2253 if(ptrWnd)
2255 dprintf_msg(stddeb,"DragQueryUpdate: hwnd = %04x, %d %d - %d %d\n",
2256 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2257 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2258 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2259 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2262 if(bResult) return bResult;
2264 else wParam = 1;
2266 else wParam = 1;
2268 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2270 ptrDragInfo->hScope = hQueryWnd;
2272 bResult = ( bNoSend )
2273 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2274 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2275 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2276 if( !bResult )
2277 ptrDragInfo->pt = pt;
2279 return bResult;
2283 /*******************************************************************
2284 * DragDetect (USER.465)
2286 BOOL16 DragDetect16( HWND16 hWnd, POINT16 pt )
2288 POINT32 pt32;
2289 CONV_POINT16TO32( &pt, &pt32 );
2290 return DragDetect32( hWnd, pt32 );
2293 /*******************************************************************
2294 * DragDetect32 (USER32.150)
2296 BOOL32 DragDetect32( HWND32 hWnd, POINT32 pt )
2298 MSG16 msg;
2299 RECT16 rect;
2301 rect.left = pt.x - wDragWidth;
2302 rect.right = pt.x + wDragWidth;
2304 rect.top = pt.y - wDragHeight;
2305 rect.bottom = pt.y + wDragHeight;
2307 SetCapture32(hWnd);
2309 while(1)
2311 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2313 if( msg.message == WM_LBUTTONUP )
2315 ReleaseCapture();
2316 return 0;
2318 if( msg.message == WM_MOUSEMOVE )
2320 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2322 ReleaseCapture();
2323 return 1;
2327 WaitMessage();
2330 return 0;
2333 /******************************************************************************
2334 * DragObject16 (USER.464)
2336 DWORD DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2337 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2339 MSG16 msg;
2340 LPDRAGINFO lpDragInfo;
2341 SEGPTR spDragInfo;
2342 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2343 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2344 WND *wndPtr = WIN_FindWndPtr(hWnd);
2345 DWORD dwRet = 0;
2346 short dragDone = 0;
2347 HCURSOR16 hCurrentCursor = 0;
2348 HWND16 hCurrentWnd = 0;
2349 BOOL16 b;
2351 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2352 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2354 if( !lpDragInfo || !spDragInfo ) return 0L;
2356 hBummer = LoadCursor16(0,IDC_BUMMER);
2358 if( !hBummer || !wndPtr )
2360 GlobalFree16(hDragInfo);
2361 return 0L;
2364 if(hCursor)
2366 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2368 GlobalFree16(hDragInfo);
2369 return 0L;
2372 if( hDragCursor == hCursor ) hDragCursor = 0;
2373 else hCursor = hDragCursor;
2375 hOldCursor = SetCursor32(hDragCursor);
2378 lpDragInfo->hWnd = hWnd;
2379 lpDragInfo->hScope = 0;
2380 lpDragInfo->wFlags = wObj;
2381 lpDragInfo->hList = szList; /* near pointer! */
2382 lpDragInfo->hOfStruct = hOfStruct;
2383 lpDragInfo->l = 0L;
2385 SetCapture32(hWnd);
2386 ShowCursor32( TRUE );
2388 while( !dragDone )
2390 WaitMessage();
2392 if( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) )
2393 continue;
2395 *(lpDragInfo+1) = *lpDragInfo;
2397 lpDragInfo->pt = msg.pt;
2399 /* update DRAGINFO struct */
2400 dprintf_msg(stddeb,"drag: lpDI->hScope = %04x\n",lpDragInfo->hScope);
2402 if( (b = DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE)) > 0 )
2403 hCurrentCursor = hCursor;
2404 else
2406 hCurrentCursor = hBummer;
2407 lpDragInfo->hScope = 0;
2409 if( hCurrentCursor )
2410 SetCursor32(hCurrentCursor);
2412 dprintf_msg(stddeb,"drag: got %04x\n", b);
2414 /* send WM_DRAGLOOP */
2415 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer) ,
2416 (LPARAM) spDragInfo );
2417 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2418 if( hCurrentWnd != lpDragInfo->hScope )
2420 if( hCurrentWnd )
2421 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2422 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2423 HIWORD(spDragInfo)) );
2424 hCurrentWnd = lpDragInfo->hScope;
2425 if( hCurrentWnd )
2426 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2428 else
2429 if( hCurrentWnd )
2430 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2433 /* check if we're done */
2434 if( msg.message == WM_LBUTTONUP || msg.message == WM_NCLBUTTONUP )
2435 dragDone = TRUE;
2438 ReleaseCapture();
2439 ShowCursor32( FALSE );
2441 if( hCursor )
2443 SetCursor32( hOldCursor );
2444 if (hDragCursor) DestroyCursor32( hDragCursor );
2447 if( hCurrentCursor != hBummer )
2448 dwRet = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2449 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2450 GlobalFree16(hDragInfo);
2452 return dwRet;