Release 970824
[wine/multimedia.git] / windows / win.c
blob9f4375bbc1020f79f99565e07c43b1f901631554
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 HCURSOR16 CURSORICON_IconToCursor(HICON16, BOOL32);
49 extern HWND32 CARET_GetHwnd(void);
50 extern BOOL32 WINPOS_CreateInternalPosAtom(void);
51 extern void WINPOS_CheckInternalPos(HWND32);
52 extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
53 extern BOOL32 EVENT_CheckFocus(void);
55 /***********************************************************************
56 * WIN_FindWndPtr
58 * Return a pointer to the WND structure corresponding to a HWND.
60 WND * WIN_FindWndPtr( HWND32 hwnd )
62 WND * ptr;
64 if (!hwnd || HIWORD(hwnd)) return NULL;
65 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
66 if (ptr->dwMagic != WND_MAGIC) return NULL;
67 if (ptr->hwndSelf != hwnd)
69 fprintf( stderr, "Can't happen: hwnd %04x self pointer is %04x\n",
70 hwnd, ptr->hwndSelf );
71 return NULL;
73 return ptr;
77 /***********************************************************************
78 * WIN_DumpWindow
80 * Dump the content of a window structure to stderr.
82 void WIN_DumpWindow( HWND32 hwnd )
84 WND *ptr;
85 char className[80];
86 int i;
88 if (!(ptr = WIN_FindWndPtr( hwnd )))
90 fprintf( stderr, "%04x is not a window handle\n", hwnd );
91 return;
94 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
95 strcpy( className, "#NULL#" );
97 fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
98 fprintf( stderr,
99 "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
100 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
101 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
102 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
103 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
104 ptr->next, ptr->child, ptr->parent, ptr->owner,
105 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
106 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
107 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
108 ptr->text ? ptr->text : "",
109 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
110 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
111 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
112 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
114 if (ptr->class->cbWndExtra)
116 fprintf( stderr, "extra bytes:" );
117 for (i = 0; i < ptr->class->cbWndExtra; i++)
118 fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
119 fprintf( stderr, "\n" );
121 fprintf( stderr, "\n" );
125 /***********************************************************************
126 * WIN_WalkWindows
128 * Walk the windows tree and print each window on stderr.
130 void WIN_WalkWindows( HWND32 hwnd, int indent )
132 WND *ptr;
133 char className[80];
135 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
136 if (!ptr)
138 fprintf( stderr, "*** Invalid window handle %04x\n", hwnd );
139 return;
142 if (!indent) /* first time around */
143 fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
144 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
146 while (ptr)
148 fprintf(stderr, "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
150 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
152 fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %08x\n",
153 (DWORD)ptr, ptr->hmemTaskQ, className,
154 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc );
156 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
157 ptr = ptr->next;
162 /***********************************************************************
163 * WIN_GetXWindow
165 * Return the X window associated to a window.
167 Window WIN_GetXWindow( HWND32 hwnd )
169 WND *wndPtr = WIN_FindWndPtr( hwnd );
170 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
171 return wndPtr ? wndPtr->window : 0;
175 /***********************************************************************
176 * WIN_UnlinkWindow
178 * Remove a window from the siblings linked list.
180 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
182 WND *wndPtr, **ppWnd;
184 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
185 ppWnd = &wndPtr->parent->child;
186 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
187 *ppWnd = wndPtr->next;
188 return TRUE;
192 /***********************************************************************
193 * WIN_LinkWindow
195 * Insert a window into the siblings linked list.
196 * The window is inserted after the specified window, which can also
197 * be specified as HWND_TOP or HWND_BOTTOM.
199 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
201 WND *wndPtr, **ppWnd;
203 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
205 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
207 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
208 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
209 while (*ppWnd) ppWnd = &(*ppWnd)->next;
211 else /* Normal case */
213 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
214 if (!afterPtr) return FALSE;
215 ppWnd = &afterPtr->next;
217 wndPtr->next = *ppWnd;
218 *ppWnd = wndPtr;
219 return TRUE;
223 /***********************************************************************
224 * WIN_FindWinToRepaint
226 * Find a window that needs repaint.
228 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
230 HWND32 hwndRet;
231 WND *pWnd = pWndDesktop;
233 /* Note: the desktop window never gets WM_PAINT messages
234 * The real reason why is because Windows DesktopWndProc
235 * does ValidateRgn inside WM_ERASEBKGND handler.
238 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
240 for ( ; pWnd ; pWnd = pWnd->next )
242 if (!(pWnd->dwStyle & WS_VISIBLE) || (pWnd->flags & WIN_NO_REDRAW))
244 dprintf_win( stddeb, "FindWinToRepaint: skipping window %04x\n",
245 pWnd->hwndSelf );
246 continue;
248 if ((pWnd->hmemTaskQ == hQueue) &&
249 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
251 if (pWnd->child )
252 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
253 return hwndRet;
256 if (!pWnd) return 0;
258 hwndRet = pWnd->hwndSelf;
260 /* look among siblings if we got a transparent window */
261 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
262 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
264 pWnd = pWnd->next;
266 if (pWnd) hwndRet = pWnd->hwndSelf;
267 dprintf_win(stddeb,"FindWinToRepaint: found %04x\n",hwndRet);
268 return hwndRet;
272 /***********************************************************************
273 * WIN_SendParentNotify
275 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
276 * the window has the WS_EX_NOPARENTNOTIFY style.
278 void WIN_SendParentNotify(HWND32 hwnd, WORD event, WORD idChild, LPARAM lValue)
280 LPPOINT16 lppt = (LPPOINT16)&lValue;
281 WND *wndPtr = WIN_FindWndPtr( hwnd );
282 BOOL32 bMouse = ((event <= WM_MOUSELAST) && (event >= WM_MOUSEFIRST));
284 /* if lValue contains cursor coordinates they have to be
285 * mapped to the client area of parent window */
287 if (bMouse) MapWindowPoints16( 0, hwnd, lppt, 1 );
289 while (wndPtr)
291 if ((wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) ||
292 !(wndPtr->dwStyle & WS_CHILD)) break;
294 if (bMouse)
296 lppt->x += wndPtr->rectClient.left;
297 lppt->y += wndPtr->rectClient.top;
300 wndPtr = wndPtr->parent;
301 SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY,
302 MAKEWPARAM( event, idChild ), lValue );
307 /***********************************************************************
308 * WIN_DestroyWindow
310 * Destroy storage associated to a window. "Internals" p.358
312 static WND* WIN_DestroyWindow( WND* wndPtr )
314 HWND32 hwnd = wndPtr->hwndSelf;
315 WND *pWnd;
317 dprintf_win( stddeb, "WIN_DestroyWindow: %04x\n", wndPtr->hwndSelf );
319 #ifdef CONFIG_IPC
320 if (main_block)
321 DDE_DestroyWindow(wndPtr->hwndSelf);
322 #endif /* CONFIG_IPC */
324 /* free child windows */
326 while ((pWnd = wndPtr->child))
327 wndPtr->child = WIN_DestroyWindow( pWnd );
329 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
331 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
333 WINPOS_CheckInternalPos( hwnd );
334 if( hwnd == GetCapture32()) ReleaseCapture();
336 /* free resources associated with the window */
338 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
339 PROPERTY_RemoveWindowProps( wndPtr );
341 wndPtr->dwMagic = 0; /* Mark it as invalid */
342 wndPtr->hwndSelf = 0;
344 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
346 if (wndPtr->hrgnUpdate) DeleteObject32( wndPtr->hrgnUpdate );
347 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
350 /* toss stale messages from the queue */
352 if( wndPtr->hmemTaskQ )
354 int pos;
355 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
357 while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
358 QUEUE_RemoveMsg(msgQ, pos);
359 wndPtr->hmemTaskQ = 0;
362 if (!(wndPtr->dwStyle & WS_CHILD))
363 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
364 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
365 if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
366 if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->dce );
368 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
370 wndPtr->class->cWindows--;
371 wndPtr->class = NULL;
372 pWnd = wndPtr->next;
374 USER_HEAP_FREE( hwnd );
375 return pWnd;
378 /***********************************************************************
379 * WIN_ResetQueueWindows
381 void WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
383 WND* next;
385 while (wnd)
387 next = wnd->next;
388 if (wnd->hmemTaskQ == hQueue)
389 if( hNew ) wnd->hmemTaskQ = hNew;
390 else DestroyWindow32( wnd->hwndSelf );
391 else WIN_ResetQueueWindows( wnd->child, hQueue, hNew );
392 wnd = next;
396 /***********************************************************************
397 * WIN_CreateDesktopWindow
399 * Create the desktop window.
401 BOOL32 WIN_CreateDesktopWindow(void)
403 CLASS *class;
404 HWND32 hwndDesktop;
406 dprintf_win(stddeb,"Creating desktop window\n");
408 if (!ICONTITLE_Init() ||
409 !WINPOS_CreateInternalPosAtom() ||
410 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
411 return FALSE;
413 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
414 if (!hwndDesktop) return FALSE;
415 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
417 pWndDesktop->next = NULL;
418 pWndDesktop->child = NULL;
419 pWndDesktop->parent = NULL;
420 pWndDesktop->owner = NULL;
421 pWndDesktop->class = class;
422 pWndDesktop->dwMagic = WND_MAGIC;
423 pWndDesktop->hwndSelf = hwndDesktop;
424 pWndDesktop->hInstance = 0;
425 pWndDesktop->rectWindow.left = 0;
426 pWndDesktop->rectWindow.top = 0;
427 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
428 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
429 pWndDesktop->rectClient = pWndDesktop->rectWindow;
430 pWndDesktop->text = NULL;
431 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
432 pWndDesktop->hrgnUpdate = 0;
433 pWndDesktop->hwndLastActive = hwndDesktop;
434 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
435 WS_CLIPSIBLINGS;
436 pWndDesktop->dwExStyle = 0;
437 pWndDesktop->dce = NULL;
438 pWndDesktop->pVScroll = NULL;
439 pWndDesktop->pHScroll = NULL;
440 pWndDesktop->pProp = NULL;
441 pWndDesktop->wIDmenu = 0;
442 pWndDesktop->flags = 0;
443 pWndDesktop->window = rootWindow;
444 pWndDesktop->hSysMenu = 0;
445 pWndDesktop->userdata = 0;
447 pWndDesktop->winproc = (WNDPROC16)class->winproc;
449 EVENT_RegisterWindow( pWndDesktop );
450 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
451 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
452 return TRUE;
456 /***********************************************************************
457 * WIN_CreateWindowEx
459 * Implementation of CreateWindowEx().
461 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
462 BOOL32 win32, BOOL32 unicode )
464 CLASS *classPtr;
465 WND *wndPtr;
466 HWND16 hwnd, hwndLinkAfter;
467 POINT32 maxSize, maxPos, minTrack, maxTrack;
468 LRESULT (*localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
470 dprintf_win( stddeb, "CreateWindowEx: " );
471 if (HIWORD(cs->lpszName)) dprintf_win( stddeb, "'%s' ", cs->lpszName );
472 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszName) );
473 if (HIWORD(cs->lpszClass)) dprintf_win( stddeb, "'%s' ", cs->lpszClass );
474 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszClass) );
476 dprintf_win( stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %p\n",
477 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
478 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
480 /* Find the parent window */
482 if (cs->hwndParent)
484 /* Make sure parent is valid */
485 if (!IsWindow32( cs->hwndParent ))
487 fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
488 return 0;
491 else if (cs->style & WS_CHILD)
493 fprintf( stderr, "CreateWindowEx: no parent for child window\n" );
494 return 0; /* WS_CHILD needs a parent */
497 /* Find the window class */
499 if (!(classPtr = CLASS_FindClassByAtom( classAtom,
500 GetExePtr(cs->hInstance) )))
502 char buffer[256];
503 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
504 fprintf( stderr, "CreateWindowEx: bad class '%s'\n", buffer );
505 return 0;
508 /* Fix the coordinates */
510 if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0;
511 if (cs->cx == CW_USEDEFAULT32)
513 /* if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0;
514 else */
516 cs->cx = 600;
517 cs->cy = 400;
521 /* Create the window structure */
523 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
524 - sizeof(wndPtr->wExtra) )))
526 dprintf_win( stddeb, "CreateWindowEx: out of memory\n" );
527 return 0;
530 /* Fill the window structure */
532 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
533 wndPtr->next = NULL;
534 wndPtr->child = NULL;
536 if (cs->style & WS_CHILD)
538 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
539 wndPtr->owner = NULL;
541 else
543 wndPtr->parent = pWndDesktop;
544 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
545 wndPtr->owner = NULL;
546 else
547 wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
550 wndPtr->window = 0;
551 wndPtr->class = classPtr;
552 wndPtr->winproc = classPtr->winproc;
553 wndPtr->dwMagic = WND_MAGIC;
554 wndPtr->hwndSelf = hwnd;
555 wndPtr->hInstance = cs->hInstance;
556 wndPtr->text = NULL;
557 wndPtr->hmemTaskQ = GetTaskQueue(0);
558 wndPtr->hrgnUpdate = 0;
559 wndPtr->hwndLastActive = hwnd;
560 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
561 wndPtr->dwExStyle = cs->dwExStyle;
562 wndPtr->wIDmenu = 0;
563 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
564 wndPtr->pVScroll = NULL;
565 wndPtr->pHScroll = NULL;
566 wndPtr->pProp = NULL;
567 wndPtr->userdata = 0;
568 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
569 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
571 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
573 /* Call the WH_CBT hook */
575 hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
577 if (HOOK_IsHooked( WH_CBT ))
579 CBT_CREATEWND32A cbtc;
581 cbtc.lpcs = cs;
582 cbtc.hwndInsertAfter = hwndLinkAfter;
583 if ( HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc) )
585 dprintf_win(stddeb, "CreateWindowEx: CBT-hook returned 0\n");
586 USER_HEAP_FREE( hwnd );
587 return 0;
591 /* Increment class window counter */
593 classPtr->cWindows++;
595 /* Correct the window style */
597 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
599 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
600 wndPtr->flags |= WIN_NEED_SIZE;
602 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
604 /* Get class or window DC if needed */
606 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
607 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
608 else wndPtr->dce = NULL;
610 /* Insert the window in the linked list */
612 WIN_LinkWindow( hwnd, hwndLinkAfter );
614 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
616 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
618 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
619 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
620 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
621 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
622 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
624 if (cs->cx <= 0) cs->cx = 1;
625 if (cs->cy <= 0) cs->cy = 1;
627 wndPtr->rectWindow.left = cs->x;
628 wndPtr->rectWindow.top = cs->y;
629 wndPtr->rectWindow.right = cs->x + cs->cx;
630 wndPtr->rectWindow.bottom = cs->y + cs->cy;
631 wndPtr->rectClient = wndPtr->rectWindow;
633 /* Create the X window (only for top-level windows, and then only */
634 /* when there's no desktop window) */
636 if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
638 XSetWindowAttributes win_attr;
640 if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
641 (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
643 win_attr.event_mask = ExposureMask | KeyPressMask |
644 KeyReleaseMask | PointerMotionMask |
645 ButtonPressMask | ButtonReleaseMask |
646 FocusChangeMask | StructureNotifyMask;
647 win_attr.override_redirect = FALSE;
648 wndPtr->flags |= WIN_MANAGED;
650 else
652 win_attr.event_mask = ExposureMask | KeyPressMask |
653 KeyReleaseMask | PointerMotionMask |
654 ButtonPressMask | ButtonReleaseMask |
655 FocusChangeMask | StructureNotifyMask;
656 win_attr.override_redirect = TRUE;
658 win_attr.colormap = COLOR_GetColormap();
659 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
660 win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
661 win_attr.cursor = CURSORICON_XCursor;
662 wndPtr->window = XCreateWindow( display, rootWindow, cs->x, cs->y,
663 cs->cx, cs->cy, 0, CopyFromParent,
664 InputOutput, CopyFromParent,
665 CWEventMask | CWOverrideRedirect |
666 CWColormap | CWCursor | CWSaveUnder |
667 CWBackingStore, &win_attr );
669 if ((wndPtr->flags & WIN_MANAGED) &&
670 (cs->dwExStyle & WS_EX_DLGMODALFRAME))
672 XSizeHints* size_hints = XAllocSizeHints();
674 if (size_hints)
676 size_hints->min_width = size_hints->max_width = cs->cx;
677 size_hints->min_height = size_hints->max_height = cs->cy;
678 size_hints->flags = (PSize | PMinSize | PMaxSize);
679 XSetWMSizeHints( display, wndPtr->window, size_hints,
680 XA_WM_NORMAL_HINTS );
681 XFree(size_hints);
685 if (cs->hwndParent) /* Get window owner */
687 Window win = WIN_GetXWindow( cs->hwndParent );
688 if (win) XSetTransientForHint( display, wndPtr->window, win );
690 EVENT_RegisterWindow( wndPtr );
693 /* Set the window menu */
695 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
697 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
698 else
700 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
701 if (classPtr->menuNameA)
702 cs->hMenu = HIWORD(classPtr->menuNameA) ?
703 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
704 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
705 #else
706 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
707 if (menuName) cs->hMenu = LoadMenu16( cs->hInstance, menuName );
708 #endif
710 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
712 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
714 /* Send the WM_CREATE message
715 * Perhaps we shouldn't allow width/height changes as well.
716 * See p327 in "Internals".
719 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
721 localSend32 = unicode ? SendMessage32W : SendMessage32A;
722 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
724 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
725 NULL, NULL, 0, &wndPtr->rectClient );
726 OffsetRect32(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
727 maxPos.y - wndPtr->rectWindow.top);
728 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
730 /* Send the size messages */
732 if (!(wndPtr->flags & WIN_NEED_SIZE))
734 /* send it anyway */
735 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
736 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
737 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
738 SendMessage32A( hwnd, WM_MOVE, 0,
739 MAKELONG( wndPtr->rectClient.left,
740 wndPtr->rectClient.top ) );
743 WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LPARAM)hwnd );
744 if (!IsWindow32(hwnd)) return 0;
746 /* Show the window, maximizing or minimizing if needed */
748 if (wndPtr->dwStyle & WS_MINIMIZE)
750 RECT16 newPos;
751 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
752 WINPOS_MinMaximize( wndPtr, SW_MINIMIZE, &newPos );
753 SetWindowPos32( hwnd, 0, newPos.left, newPos.top, newPos.right, newPos.bottom,
754 SWP_FRAMECHANGED | ((GetActiveWindow32())? SWP_NOACTIVATE : 0));
756 else if (wndPtr->dwStyle & WS_MAXIMIZE)
758 RECT16 newPos;
759 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
760 WINPOS_MinMaximize( wndPtr, SW_MAXIMIZE, &newPos );
761 SetWindowPos32( hwnd, 0, newPos.left, newPos.top, newPos.right, newPos.bottom,
762 ((GetActiveWindow32())? SWP_NOACTIVATE : 0) | SWP_FRAMECHANGED );
765 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
767 /* Call WH_SHELL hook */
769 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
770 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
772 dprintf_win(stddeb, "CreateWindowEx: created window %04x\n", hwnd);
773 return hwnd;
777 /* Abort window creation */
779 dprintf_win(stddeb,"CreateWindowEx: aborted by WM_xxCREATE!\n");
780 WIN_UnlinkWindow( hwnd );
781 WIN_DestroyWindow( wndPtr );
782 return 0;
786 /***********************************************************************
787 * CreateWindow16 (USER.41)
789 HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
790 DWORD style, INT16 x, INT16 y, INT16 width,
791 INT16 height, HWND16 parent, HMENU16 menu,
792 HINSTANCE16 instance, LPVOID data )
794 return CreateWindowEx16( 0, className, windowName, style,
795 x, y, width, height, parent, menu, instance, data );
799 /***********************************************************************
800 * CreateWindowEx16 (USER.452)
802 HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
803 LPCSTR windowName, DWORD style, INT16 x,
804 INT16 y, INT16 width, INT16 height,
805 HWND16 parent, HMENU16 menu,
806 HINSTANCE16 instance, LPVOID data )
808 ATOM classAtom;
809 CREATESTRUCT32A cs;
811 /* Find the class atom */
813 if (!(classAtom = GlobalFindAtom32A( className )))
815 fprintf( stderr, "CreateWindowEx16: bad class name " );
816 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
817 else fprintf( stderr, "'%s'\n", className );
818 return 0;
821 /* Fix the coordinates */
823 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
824 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
825 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
826 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
828 /* Create the window */
830 cs.lpCreateParams = data;
831 cs.hInstance = (HINSTANCE32)instance;
832 cs.hMenu = (HMENU32)menu;
833 cs.hwndParent = (HWND32)parent;
834 cs.style = style;
835 cs.lpszName = windowName;
836 cs.lpszClass = className;
837 cs.dwExStyle = exStyle;
838 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
842 /***********************************************************************
843 * CreateWindowEx32A (USER32.82)
845 HWND32 WINAPI CreateWindowEx32A( DWORD exStyle, LPCSTR className,
846 LPCSTR windowName, DWORD style, INT32 x,
847 INT32 y, INT32 width, INT32 height,
848 HWND32 parent, HMENU32 menu,
849 HINSTANCE32 instance, LPVOID data )
851 ATOM classAtom;
852 CREATESTRUCT32A cs;
854 /* Find the class atom */
856 if (!(classAtom = GlobalFindAtom32A( className )))
858 fprintf( stderr, "CreateWindowEx32A: bad class name " );
859 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
860 else fprintf( stderr, "'%s'\n", className );
861 return 0;
864 /* Create the window */
866 cs.lpCreateParams = data;
867 cs.hInstance = instance;
868 cs.hMenu = menu;
869 cs.hwndParent = parent;
870 cs.x = x;
871 cs.y = y;
872 cs.cx = width;
873 cs.cy = height;
874 cs.style = style;
875 cs.lpszName = windowName;
876 cs.lpszClass = className;
877 cs.dwExStyle = exStyle;
878 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
882 /***********************************************************************
883 * CreateWindowEx32W (USER32.83)
885 HWND32 WINAPI CreateWindowEx32W( DWORD exStyle, LPCWSTR className,
886 LPCWSTR windowName, DWORD style, INT32 x,
887 INT32 y, INT32 width, INT32 height,
888 HWND32 parent, HMENU32 menu,
889 HINSTANCE32 instance, LPVOID data )
891 ATOM classAtom;
892 CREATESTRUCT32W cs;
894 /* Find the class atom */
896 if (!(classAtom = GlobalFindAtom32W( className )))
898 if (HIWORD(className))
900 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
901 fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
902 HeapFree( GetProcessHeap(), 0, cn );
904 else
905 fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
906 return 0;
909 /* Create the window */
911 cs.lpCreateParams = data;
912 cs.hInstance = instance;
913 cs.hMenu = menu;
914 cs.hwndParent = parent;
915 cs.x = x;
916 cs.y = y;
917 cs.cx = width;
918 cs.cy = height;
919 cs.style = style;
920 cs.lpszName = windowName;
921 cs.lpszClass = className;
922 cs.dwExStyle = exStyle;
923 /* Note: we rely on the fact that CREATESTRUCT32A and */
924 /* CREATESTRUCT32W have the same layout. */
925 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
929 /***********************************************************************
930 * WIN_CheckFocus
932 static void WIN_CheckFocus( WND* pWnd )
934 if( GetFocus16() == pWnd->hwndSelf )
935 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
938 /***********************************************************************
939 * WIN_SendDestroyMsg
941 static void WIN_SendDestroyMsg( WND* pWnd )
943 WND* pChild;
945 WIN_CheckFocus(pWnd);
947 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
948 if( !pWnd->window ) CLIPBOARD_DisOwn( pWnd );
950 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
952 if( !IsWindow32(pWnd->hwndSelf) )
954 dprintf_win(stddeb,"\tdestroyed itself while in WM_DESTROY!\n");
955 return;
958 pChild = pWnd->child;
959 while( pChild )
961 WIN_SendDestroyMsg( pChild );
962 pChild = pChild->next;
964 WIN_CheckFocus(pWnd);
968 /***********************************************************************
969 * DestroyWindow16 (USER.53)
971 BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
973 return DestroyWindow32(hwnd);
977 /***********************************************************************
978 * DestroyWindow32 (USER32.134)
980 BOOL32 WINAPI DestroyWindow32( HWND32 hwnd )
982 WND * wndPtr;
984 dprintf_win(stddeb, "DestroyWindow(%04x)\n", hwnd);
986 /* Initialization */
988 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
989 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
991 /* Call hooks */
993 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
994 return FALSE;
996 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
998 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
999 /* FIXME: clean up palette - see "Internals" p.352 */
1002 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
1003 WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
1004 if (!IsWindow32(hwnd)) return TRUE;
1006 if( wndPtr->window ) CLIPBOARD_DisOwn( wndPtr ); /* before window is unmapped */
1008 /* Hide the window */
1010 if (wndPtr->dwStyle & WS_VISIBLE)
1012 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
1013 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
1014 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
1015 if (!IsWindow32(hwnd)) return TRUE;
1018 /* Recursively destroy owned windows */
1020 if( !(wndPtr->dwStyle & WS_CHILD) )
1022 /* make sure top menu popup doesn't get destroyed */
1023 MENU_PatchResidentPopup( TRUE, wndPtr );
1025 for (;;)
1027 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1028 while (siblingPtr)
1030 if (siblingPtr->owner == wndPtr)
1031 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1032 break;
1033 else
1034 siblingPtr->owner = NULL;
1035 siblingPtr = siblingPtr->next;
1037 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1038 else break;
1041 if( !Options.managed || EVENT_CheckFocus() )
1042 WINPOS_ActivateOtherWindow(wndPtr);
1044 if( wndPtr->owner &&
1045 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1046 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1049 /* Send destroy messages */
1051 WIN_SendDestroyMsg( wndPtr );
1052 if (!IsWindow32(hwnd)) return TRUE;
1054 /* Unlink now so we won't bother with the children later on */
1056 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1058 /* Destroy the window storage */
1060 WIN_DestroyWindow( wndPtr );
1061 return TRUE;
1065 /***********************************************************************
1066 * CloseWindow16 (USER.43)
1068 BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
1070 return CloseWindow32( hwnd );
1074 /***********************************************************************
1075 * CloseWindow32 (USER32.55)
1077 BOOL32 WINAPI CloseWindow32( HWND32 hwnd )
1079 WND * wndPtr = WIN_FindWndPtr( hwnd );
1080 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1081 ShowWindow32( hwnd, SW_MINIMIZE );
1082 return TRUE;
1086 /***********************************************************************
1087 * OpenIcon16 (USER.44)
1089 BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
1091 return OpenIcon32( hwnd );
1095 /***********************************************************************
1096 * OpenIcon32 (USER32.409)
1098 BOOL32 WINAPI OpenIcon32( HWND32 hwnd )
1100 if (!IsIconic32( hwnd )) return FALSE;
1101 ShowWindow32( hwnd, SW_SHOWNORMAL );
1102 return TRUE;
1106 /***********************************************************************
1107 * WIN_FindWindow
1109 * Implementation of FindWindow() and FindWindowEx().
1111 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1112 LPCSTR title )
1114 WND *pWnd;
1115 CLASS *pClass = NULL;
1117 if (child)
1119 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1120 if (parent)
1122 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1124 else if (pWnd->parent != pWndDesktop) return 0;
1125 pWnd = pWnd->next;
1127 else
1129 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1130 pWnd = pWnd->child;
1132 if (!pWnd) return 0;
1134 /* For a child window, all siblings will have the same hInstance, */
1135 /* so we can look for the class once and for all. */
1137 if (className && (pWnd->dwStyle & WS_CHILD))
1139 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1140 return 0;
1143 for ( ; pWnd; pWnd = pWnd->next)
1145 if (className && !(pWnd->dwStyle & WS_CHILD))
1147 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance)))
1148 continue; /* Skip this window */
1150 if (pClass && (pWnd->class != pClass))
1151 continue; /* Not the right class */
1153 /* Now check the title */
1155 if (!title) return pWnd->hwndSelf;
1156 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1158 return 0;
1163 /***********************************************************************
1164 * FindWindow16 (USER.50)
1166 HWND16 WINAPI FindWindow16( SEGPTR className, LPCSTR title )
1168 return FindWindowEx16( 0, 0, className, title );
1172 /***********************************************************************
1173 * FindWindowEx16 (USER.427)
1175 HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child,
1176 SEGPTR className, LPCSTR title )
1178 ATOM atom = 0;
1180 dprintf_win(stddeb, "FindWindowEx16: %04x %04x '%s' '%s'\n", parent,
1181 child, HIWORD(className)?(char *)PTR_SEG_TO_LIN(className):"",
1182 title ? title : "");
1184 if (className)
1186 /* If the atom doesn't exist, then no class */
1187 /* with this name exists either. */
1188 if (!(atom = GlobalFindAtom16( className ))) return 0;
1190 return WIN_FindWindow( parent, child, atom, title );
1194 /***********************************************************************
1195 * FindWindow32A (USER32.197)
1197 HWND32 WINAPI FindWindow32A( LPCSTR className, LPCSTR title )
1199 return FindWindowEx32A( 0, 0, className, title );
1203 /***********************************************************************
1204 * FindWindowEx32A (USER32.198)
1206 HWND32 WINAPI FindWindowEx32A( HWND32 parent, HWND32 child,
1207 LPCSTR className, LPCSTR title )
1209 ATOM atom = 0;
1211 if (className)
1213 /* If the atom doesn't exist, then no class */
1214 /* with this name exists either. */
1215 if (!(atom = GlobalFindAtom32A( className ))) return 0;
1217 return WIN_FindWindow( 0, 0, atom, title );
1221 /***********************************************************************
1222 * FindWindowEx32W (USER32.199)
1224 HWND32 WINAPI FindWindowEx32W( HWND32 parent, HWND32 child,
1225 LPCWSTR className, LPCWSTR title )
1227 ATOM atom = 0;
1228 char *buffer;
1229 HWND32 hwnd;
1231 if (className)
1233 /* If the atom doesn't exist, then no class */
1234 /* with this name exists either. */
1235 if (!(atom = GlobalFindAtom32W( className ))) return 0;
1237 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1238 hwnd = WIN_FindWindow( 0, 0, atom, buffer );
1239 HeapFree( GetProcessHeap(), 0, buffer );
1240 return hwnd;
1244 /***********************************************************************
1245 * FindWindow32W (USER32.200)
1247 HWND32 WINAPI FindWindow32W( LPCWSTR className, LPCWSTR title )
1249 return FindWindowEx32W( 0, 0, className, title );
1253 /**********************************************************************
1254 * WIN_GetDesktop
1256 WND *WIN_GetDesktop(void)
1258 return pWndDesktop;
1262 /**********************************************************************
1263 * GetDesktopWindow16 (USER.286)
1265 HWND16 WINAPI GetDesktopWindow16(void)
1267 return (HWND16)pWndDesktop->hwndSelf;
1271 /**********************************************************************
1272 * GetDesktopWindow32 (USER32.231)
1274 HWND32 WINAPI GetDesktopWindow32(void)
1276 return pWndDesktop->hwndSelf;
1280 /**********************************************************************
1281 * GetDesktopHwnd (USER.278)
1283 * Exactly the same thing as GetDesktopWindow(), but not documented.
1284 * Don't ask me why...
1286 HWND16 WINAPI GetDesktopHwnd(void)
1288 return (HWND16)pWndDesktop->hwndSelf;
1292 /*******************************************************************
1293 * EnableWindow16 (USER.34)
1295 BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
1297 return EnableWindow32( hwnd, enable );
1301 /*******************************************************************
1302 * EnableWindow32 (USER32.171)
1304 BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
1306 WND *wndPtr;
1308 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1309 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1311 /* Enable window */
1312 wndPtr->dwStyle &= ~WS_DISABLED;
1313 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1314 return TRUE;
1316 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1318 /* Disable window */
1319 wndPtr->dwStyle |= WS_DISABLED;
1320 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1321 SetFocus32( 0 ); /* A disabled window can't have the focus */
1322 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1323 ReleaseCapture(); /* A disabled window can't capture the mouse */
1324 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1325 return FALSE;
1327 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1331 /***********************************************************************
1332 * IsWindowEnabled16 (USER.35)
1334 BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
1336 return IsWindowEnabled32(hWnd);
1340 /***********************************************************************
1341 * IsWindowEnabled32 (USER32.348)
1343 BOOL32 WINAPI IsWindowEnabled32(HWND32 hWnd)
1345 WND * wndPtr;
1347 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1348 return !(wndPtr->dwStyle & WS_DISABLED);
1352 /***********************************************************************
1353 * IsWindowUnicode (USER32.349)
1355 BOOL32 WINAPI IsWindowUnicode( HWND32 hwnd )
1357 WND * wndPtr;
1359 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1360 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1364 /**********************************************************************
1365 * GetWindowWord16 (USER.133)
1367 WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
1369 return GetWindowWord32( hwnd, offset );
1373 /**********************************************************************
1374 * GetWindowWord32 (USER32.313)
1376 WORD WINAPI GetWindowWord32( HWND32 hwnd, INT32 offset )
1378 WND * wndPtr = WIN_FindWndPtr( hwnd );
1379 if (!wndPtr) return 0;
1380 if (offset >= 0)
1382 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1384 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1385 return 0;
1387 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1389 switch(offset)
1391 case GWW_ID: return (WORD)wndPtr->wIDmenu;
1392 case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
1393 case GWW_HINSTANCE: return (WORD)wndPtr->hInstance;
1394 default:
1395 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1396 return 0;
1401 /**********************************************************************
1402 * WIN_GetWindowInstance
1404 HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd )
1406 WND * wndPtr = WIN_FindWndPtr( hwnd );
1407 if (!wndPtr) return (HINSTANCE16)0;
1408 return wndPtr->hInstance;
1412 /**********************************************************************
1413 * SetWindowWord16 (USER.134)
1415 WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1417 return SetWindowWord32( hwnd, offset, newval );
1421 /**********************************************************************
1422 * SetWindowWord32 (USER32.523)
1424 WORD WINAPI SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1426 WORD *ptr, retval;
1427 WND * wndPtr = WIN_FindWndPtr( hwnd );
1428 if (!wndPtr) return 0;
1429 if (offset >= 0)
1431 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1433 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1434 return 0;
1436 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1438 else switch(offset)
1440 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1441 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1442 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1443 default:
1444 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1445 return 0;
1447 retval = *ptr;
1448 *ptr = newval;
1449 return retval;
1453 /**********************************************************************
1454 * WIN_GetWindowLong
1456 * Helper function for GetWindowLong().
1458 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1460 LONG retval;
1461 WND * wndPtr = WIN_FindWndPtr( hwnd );
1462 if (!wndPtr) return 0;
1463 if (offset >= 0)
1465 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1467 fprintf( stderr, "GetWindowLong: invalid offset %d\n", offset );
1468 return 0;
1470 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1471 /* Special case for dialog window procedure */
1472 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1473 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1474 return retval;
1476 switch(offset)
1478 case GWL_USERDATA: return wndPtr->userdata;
1479 case GWL_STYLE: return wndPtr->dwStyle;
1480 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1481 case GWL_ID: return (LONG)wndPtr->wIDmenu;
1482 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1483 type );
1484 case GWL_HWNDPARENT: return wndPtr->parent ?
1485 (HWND32)wndPtr->parent->hwndSelf : 0;
1486 case GWL_HINSTANCE: return (HINSTANCE32)wndPtr->hInstance;
1487 default:
1488 fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
1490 return 0;
1494 /**********************************************************************
1495 * WIN_SetWindowLong
1497 * Helper function for SetWindowLong().
1499 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1500 WINDOWPROCTYPE type )
1502 LONG *ptr, retval;
1503 WND * wndPtr = WIN_FindWndPtr( hwnd );
1504 if (!wndPtr) return 0;
1505 if (offset >= 0)
1507 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1509 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1510 return 0;
1512 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1513 /* Special case for dialog window procedure */
1514 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1516 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1517 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1518 type, WIN_PROC_WINDOW );
1519 return retval;
1522 else switch(offset)
1524 case GWL_ID:
1525 case GWL_HINSTANCE:
1526 return SetWindowWord32( hwnd, offset, (WORD)newval );
1527 case GWL_WNDPROC:
1528 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1529 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1530 type, WIN_PROC_WINDOW );
1531 return retval;
1532 case GWL_STYLE:
1534 /* FIXME: WM_STYLE... messages for WIN_ISWIN32 windows */
1536 ptr = &wndPtr->dwStyle;
1537 /* Some bits can't be changed this way */
1538 newval &= ~(WS_VISIBLE | WS_CHILD);
1539 newval |= (*ptr & (WS_VISIBLE | WS_CHILD));
1540 break;
1541 case GWL_USERDATA: ptr = &wndPtr->userdata; break;
1542 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
1543 default:
1544 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1545 return 0;
1547 retval = *ptr;
1548 *ptr = newval;
1549 return retval;
1553 /**********************************************************************
1554 * GetWindowLong16 (USER.135)
1556 LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
1558 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1562 /**********************************************************************
1563 * GetWindowLong32A (USER32.304)
1565 LONG WINAPI GetWindowLong32A( HWND32 hwnd, INT32 offset )
1567 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1571 /**********************************************************************
1572 * GetWindowLong32W (USER32.305)
1574 LONG WINAPI GetWindowLong32W( HWND32 hwnd, INT32 offset )
1576 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1580 /**********************************************************************
1581 * SetWindowLong16 (USER.136)
1583 LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1585 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1589 /**********************************************************************
1590 * SetWindowLong32A (USER32.516)
1592 LONG WINAPI SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1594 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1598 /**********************************************************************
1599 * SetWindowLong32W (USER32.517)
1601 LONG WINAPI SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
1603 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1607 /*******************************************************************
1608 * GetWindowText16 (USER.36)
1610 INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1612 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1616 /*******************************************************************
1617 * GetWindowText32A (USER32.308)
1619 INT32 WINAPI GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1621 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1622 (LPARAM)lpString );
1626 /*******************************************************************
1627 * GetWindowText32W (USER32.311)
1629 INT32 WINAPI GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1631 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1632 (LPARAM)lpString );
1636 /*******************************************************************
1637 * SetWindowText16 (USER.37)
1639 void WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1641 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1645 /*******************************************************************
1646 * SetWindowText32A (USER32.521)
1648 void WINAPI SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1650 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1654 /*******************************************************************
1655 * SetWindowText32W (USER32.522)
1657 void WINAPI SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1659 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1663 /*******************************************************************
1664 * GetWindowTextLength16 (USER.38)
1666 INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
1668 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1672 /*******************************************************************
1673 * GetWindowTextLength32A (USER32.309)
1675 INT32 WINAPI GetWindowTextLength32A( HWND32 hwnd )
1677 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1680 /*******************************************************************
1681 * GetWindowTextLength32W (USER32.309)
1683 INT32 WINAPI GetWindowTextLength32W( HWND32 hwnd )
1685 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1689 /*******************************************************************
1690 * IsWindow16 (USER.47)
1692 BOOL16 WINAPI IsWindow16( HWND16 hwnd )
1694 return IsWindow32( hwnd );
1698 /*******************************************************************
1699 * IsWindow32 (USER32.347)
1701 BOOL32 WINAPI IsWindow32( HWND32 hwnd )
1703 WND * wndPtr = WIN_FindWndPtr( hwnd );
1704 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1708 /*****************************************************************
1709 * GetParent16 (USER.46)
1711 HWND16 WINAPI GetParent16( HWND16 hwnd )
1713 return (HWND16)GetParent32( hwnd );
1717 /*****************************************************************
1718 * GetParent32 (USER32.277)
1720 HWND32 WINAPI GetParent32( HWND32 hwnd )
1722 WND *wndPtr = WIN_FindWndPtr(hwnd);
1723 if (!wndPtr) return 0;
1724 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1725 return wndPtr ? wndPtr->hwndSelf : 0;
1728 /*****************************************************************
1729 * WIN_GetTopParent
1731 * Get the top-level parent for a child window.
1733 WND* WIN_GetTopParentPtr( WND* pWnd )
1735 while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
1736 return pWnd;
1739 /*****************************************************************
1740 * WIN_GetTopParent
1742 * Get the top-level parent for a child window.
1744 HWND32 WIN_GetTopParent( HWND32 hwnd )
1746 WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
1747 return wndPtr ? wndPtr->hwndSelf : 0;
1751 /*****************************************************************
1752 * SetParent16 (USER.233)
1754 HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1756 return SetParent32( hwndChild, hwndNewParent );
1760 /*****************************************************************
1761 * SetParent32 (USER32.494)
1763 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1765 HWND32 oldParent;
1767 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1768 WND *pWndParent = WIN_FindWndPtr( hwndNewParent );
1769 if (!wndPtr || !pWndParent || !(wndPtr->dwStyle & WS_CHILD)) return 0;
1771 oldParent = wndPtr->parent->hwndSelf;
1773 WIN_UnlinkWindow(hwndChild);
1774 if (hwndNewParent) wndPtr->parent = pWndParent;
1775 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
1777 if (IsWindowVisible32(hwndChild)) UpdateWindow32(hwndChild);
1779 return oldParent;
1783 /*******************************************************************
1784 * IsChild16 (USER.48)
1786 BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
1788 return IsChild32(parent,child);
1792 /*******************************************************************
1793 * IsChild32 (USER32.338)
1795 BOOL32 WINAPI IsChild32( HWND32 parent, HWND32 child )
1797 WND * wndPtr = WIN_FindWndPtr( child );
1798 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1800 wndPtr = wndPtr->parent;
1801 if (wndPtr->hwndSelf == parent) return TRUE;
1803 return FALSE;
1807 /***********************************************************************
1808 * IsWindowVisible16 (USER.49)
1810 BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
1812 return IsWindowVisible32(hwnd);
1816 /***********************************************************************
1817 * IsWindowVisible32 (USER32.350)
1819 BOOL32 WINAPI IsWindowVisible32( HWND32 hwnd )
1821 WND *wndPtr = WIN_FindWndPtr( hwnd );
1822 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1824 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1825 wndPtr = wndPtr->parent;
1827 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1831 /***********************************************************************
1832 * WIN_IsWindowDrawable
1834 * hwnd is drawable when it is visible, all parents are not
1835 * minimized, and it is itself not minimized unless we are
1836 * trying to draw its default class icon.
1838 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
1840 if( (wnd->dwStyle & WS_MINIMIZE &&
1841 icon && wnd->class->hIcon) ||
1842 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
1843 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
1844 if( wnd->dwStyle & WS_MINIMIZE ||
1845 !(wnd->dwStyle & WS_VISIBLE) ) break;
1846 return (wnd == NULL);
1850 /*******************************************************************
1851 * GetTopWindow16 (USER.229)
1853 HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
1855 return GetTopWindow32(hwnd);
1859 /*******************************************************************
1860 * GetTopWindow32 (USER.229)
1862 HWND32 WINAPI GetTopWindow32( HWND32 hwnd )
1864 WND * wndPtr = WIN_FindWndPtr( hwnd );
1865 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1866 else return 0;
1870 /*******************************************************************
1871 * GetWindow16 (USER.262)
1873 HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
1875 return GetWindow32( hwnd,rel );
1879 /*******************************************************************
1880 * GetWindow32 (USER32.301)
1882 HWND32 WINAPI GetWindow32( HWND32 hwnd, WORD rel )
1884 WND * wndPtr = WIN_FindWndPtr( hwnd );
1885 if (!wndPtr) return 0;
1886 switch(rel)
1888 case GW_HWNDFIRST:
1889 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
1890 else return 0;
1892 case GW_HWNDLAST:
1893 if (!wndPtr->parent) return 0; /* Desktop window */
1894 while (wndPtr->next) wndPtr = wndPtr->next;
1895 return wndPtr->hwndSelf;
1897 case GW_HWNDNEXT:
1898 if (!wndPtr->next) return 0;
1899 return wndPtr->next->hwndSelf;
1901 case GW_HWNDPREV:
1902 if (!wndPtr->parent) return 0; /* Desktop window */
1903 wndPtr = wndPtr->parent->child; /* First sibling */
1904 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
1905 while (wndPtr->next)
1907 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
1908 wndPtr = wndPtr->next;
1910 return 0;
1912 case GW_OWNER:
1913 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
1915 case GW_CHILD:
1916 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
1918 return 0;
1922 /*******************************************************************
1923 * GetNextWindow16 (USER.230)
1925 HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
1927 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1928 return GetWindow16( hwnd, flag );
1931 /*******************************************************************
1932 * ShowOwnedPopups16 (USER.265)
1934 void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
1936 ShowOwnedPopups32( owner, fShow );
1940 /*******************************************************************
1941 * ShowOwnedPopups32 (USER32.530)
1943 BOOL32 WINAPI ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
1945 WND *pWnd = pWndDesktop->child;
1946 while (pWnd)
1948 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
1949 (pWnd->dwStyle & WS_POPUP))
1950 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
1951 pWnd = pWnd->next;
1953 return TRUE;
1957 /*******************************************************************
1958 * GetLastActivePopup16 (USER.287)
1960 HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
1962 return GetLastActivePopup32( hwnd );
1965 /*******************************************************************
1966 * GetLastActivePopup32 (USER32.255)
1968 HWND32 WINAPI GetLastActivePopup32( HWND32 hwnd )
1970 WND *wndPtr;
1971 wndPtr = WIN_FindWndPtr(hwnd);
1972 if (wndPtr == NULL) return hwnd;
1973 return wndPtr->hwndLastActive;
1977 /*******************************************************************
1978 * WIN_BuildWinArray
1980 * Build an array of pointers to the children of a given window.
1981 * The array must be freed with HeapFree(SystemHeap). Return NULL
1982 * when no windows are found.
1984 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
1986 WND **list, **ppWnd;
1987 WND *pWnd;
1988 UINT32 count, skipOwned, skipHidden;
1989 DWORD skipFlags;
1991 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
1992 skipOwned = bwaFlags & BWA_SKIPOWNED;
1993 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
1994 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
1996 /* First count the windows */
1998 if (!wndPtr) wndPtr = pWndDesktop;
1999 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
2001 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2002 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
2005 if( count )
2007 /* Now build the list of all windows */
2009 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
2011 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
2013 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2014 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2016 *ppWnd++ = pWnd;
2017 count++;
2020 *ppWnd = NULL;
2022 else count = 0;
2023 } else list = NULL;
2025 if( pTotal ) *pTotal = count;
2026 return list;
2030 /*******************************************************************
2031 * EnumWindows16 (USER.54)
2033 BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2035 WND **list, **ppWnd;
2037 /* We have to build a list of all windows first, to avoid */
2038 /* unpleasant side-effects, for instance if the callback */
2039 /* function changes the Z-order of the windows. */
2041 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2043 /* Now call the callback function for every window */
2045 for (ppWnd = list; *ppWnd; ppWnd++)
2047 /* Make sure that the window still exists */
2048 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2049 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2051 HeapFree( SystemHeap, 0, list );
2052 return TRUE;
2056 /*******************************************************************
2057 * EnumWindows32 (USER32.192)
2059 BOOL32 WINAPI EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2061 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2065 /**********************************************************************
2066 * EnumTaskWindows16 (USER.225)
2068 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2069 LPARAM lParam )
2071 WND **list, **ppWnd;
2072 HQUEUE16 hQueue = GetTaskQueue( hTask );
2074 /* This function is the same as EnumWindows(), */
2075 /* except for an added check on the window queue. */
2077 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2079 /* Now call the callback function for every window */
2081 for (ppWnd = list; *ppWnd; ppWnd++)
2083 /* Make sure that the window still exists */
2084 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2085 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
2086 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2088 HeapFree( SystemHeap, 0, list );
2089 return TRUE;
2093 /**********************************************************************
2094 * EnumThreadWindows (USER32.189)
2096 BOOL32 WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2098 THDB *tdb = (THDB*)id;
2100 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2104 /**********************************************************************
2105 * WIN_EnumChildWindows
2107 * Helper function for EnumChildWindows().
2109 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2110 LPARAM lParam )
2112 WND **childList;
2113 BOOL16 ret = FALSE;
2115 for ( ; *ppWnd; ppWnd++)
2117 /* Make sure that the window still exists */
2118 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2119 /* Build children list first */
2120 if (!(childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL )))
2121 return FALSE;
2122 if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
2123 ret = WIN_EnumChildWindows( childList, func, lParam );
2124 HeapFree( SystemHeap, 0, childList );
2125 if (!ret) return FALSE;
2127 return TRUE;
2131 /**********************************************************************
2132 * EnumChildWindows16 (USER.55)
2134 BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2135 LPARAM lParam )
2137 WND **list, *pParent;
2139 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2140 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2141 WIN_EnumChildWindows( list, func, lParam );
2142 HeapFree( SystemHeap, 0, list );
2143 return TRUE;
2147 /**********************************************************************
2148 * EnumChildWindows32 (USER32.177)
2150 BOOL32 WINAPI EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
2151 LPARAM lParam )
2153 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2154 lParam );
2158 /*******************************************************************
2159 * AnyPopup16 (USER.52)
2161 BOOL16 WINAPI AnyPopup16(void)
2163 return AnyPopup32();
2167 /*******************************************************************
2168 * AnyPopup32 (USER32.3)
2170 BOOL32 WINAPI AnyPopup32(void)
2172 WND *wndPtr;
2173 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2174 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2175 return FALSE;
2179 /*******************************************************************
2180 * FlashWindow16 (USER.105)
2182 BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2184 return FlashWindow32( hWnd, bInvert );
2188 /*******************************************************************
2189 * FlashWindow32 (USER32.201)
2191 BOOL32 WINAPI FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2193 WND *wndPtr = WIN_FindWndPtr(hWnd);
2195 dprintf_win(stddeb,"FlashWindow: %04x\n", hWnd);
2197 if (!wndPtr) return FALSE;
2199 if (wndPtr->dwStyle & WS_MINIMIZE)
2201 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2203 HDC32 hDC = GetDC32(hWnd);
2205 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2206 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2208 ReleaseDC32( hWnd, hDC );
2209 wndPtr->flags |= WIN_NCACTIVATED;
2211 else
2213 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2214 RDW_UPDATENOW | RDW_FRAME, 0 );
2215 wndPtr->flags &= ~WIN_NCACTIVATED;
2217 return TRUE;
2219 else
2221 WPARAM16 wparam;
2222 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2223 else wparam = (hWnd == GetActiveWindow32());
2225 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2226 return wparam;
2231 /*******************************************************************
2232 * SetSysModalWindow16 (USER.188)
2234 HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
2236 HWND32 hWndOldModal = hwndSysModal;
2237 hwndSysModal = hWnd;
2238 dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2239 return hWndOldModal;
2243 /*******************************************************************
2244 * GetSysModalWindow16 (USER.52)
2246 HWND16 WINAPI GetSysModalWindow16(void)
2248 return hwndSysModal;
2252 /*******************************************************************
2253 * DRAG_QueryUpdate
2255 * recursively find a child that contains spDragInfo->pt point
2256 * and send WM_QUERYDROPOBJECT
2258 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2260 BOOL16 wParam,bResult = 0;
2261 POINT32 pt;
2262 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2263 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2264 RECT32 tempRect;
2266 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2268 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2270 GetWindowRect32(hQueryWnd,&tempRect);
2272 if( !PtInRect32(&tempRect,pt) ||
2273 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2274 return 0;
2276 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2278 tempRect = ptrQueryWnd->rectClient;
2279 if(ptrQueryWnd->dwStyle & WS_CHILD)
2280 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2281 (LPPOINT32)&tempRect, 2 );
2283 if (PtInRect32( &tempRect, pt))
2285 wParam = 0;
2287 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2288 if( ptrWnd->dwStyle & WS_VISIBLE )
2290 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2291 if (PtInRect32( &tempRect, pt )) break;
2294 if(ptrWnd)
2296 dprintf_msg(stddeb,"DragQueryUpdate: hwnd = %04x, %d %d - %d %d\n",
2297 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2298 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2299 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2300 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2303 if(bResult) return bResult;
2305 else wParam = 1;
2307 else wParam = 1;
2309 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2311 ptrDragInfo->hScope = hQueryWnd;
2313 bResult = ( bNoSend )
2314 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2315 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2316 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2317 if( !bResult )
2318 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2320 return bResult;
2324 /*******************************************************************
2325 * DragDetect (USER.465)
2327 BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
2329 POINT32 pt32;
2330 CONV_POINT16TO32( &pt, &pt32 );
2331 return DragDetect32( hWnd, pt32 );
2334 /*******************************************************************
2335 * DragDetect32 (USER32.150)
2337 BOOL32 WINAPI DragDetect32( HWND32 hWnd, POINT32 pt )
2339 MSG16 msg;
2340 RECT16 rect;
2342 rect.left = pt.x - wDragWidth;
2343 rect.right = pt.x + wDragWidth;
2345 rect.top = pt.y - wDragHeight;
2346 rect.bottom = pt.y + wDragHeight;
2348 SetCapture32(hWnd);
2350 while(1)
2352 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2354 if( msg.message == WM_LBUTTONUP )
2356 ReleaseCapture();
2357 return 0;
2359 if( msg.message == WM_MOUSEMOVE )
2361 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2363 ReleaseCapture();
2364 return 1;
2368 WaitMessage();
2370 return 0;
2373 /******************************************************************************
2374 * DragObject16 (USER.464)
2376 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2377 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2379 MSG16 msg;
2380 LPDRAGINFO lpDragInfo;
2381 SEGPTR spDragInfo;
2382 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2383 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2384 WND *wndPtr = WIN_FindWndPtr(hWnd);
2385 HCURSOR16 hCurrentCursor = 0;
2386 HWND16 hCurrentWnd = 0;
2388 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2389 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2391 if( !lpDragInfo || !spDragInfo ) return 0L;
2393 hBummer = LoadCursor16(0, IDC_BUMMER);
2395 if( !hBummer || !wndPtr )
2397 GlobalFree16(hDragInfo);
2398 return 0L;
2401 if(hCursor)
2403 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2405 GlobalFree16(hDragInfo);
2406 return 0L;
2409 if( hDragCursor == hCursor ) hDragCursor = 0;
2410 else hCursor = hDragCursor;
2412 hOldCursor = SetCursor32(hDragCursor);
2415 lpDragInfo->hWnd = hWnd;
2416 lpDragInfo->hScope = 0;
2417 lpDragInfo->wFlags = wObj;
2418 lpDragInfo->hList = szList; /* near pointer! */
2419 lpDragInfo->hOfStruct = hOfStruct;
2420 lpDragInfo->l = 0L;
2422 SetCapture32(hWnd);
2423 ShowCursor32( TRUE );
2427 do{ WaitMessage(); }
2428 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2430 *(lpDragInfo+1) = *lpDragInfo;
2432 lpDragInfo->pt = msg.pt;
2434 /* update DRAGINFO struct */
2435 dprintf_msg(stddeb,"drag: lpDI->hScope = %04x\n",lpDragInfo->hScope);
2437 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2438 hCurrentCursor = hCursor;
2439 else
2441 hCurrentCursor = hBummer;
2442 lpDragInfo->hScope = 0;
2444 if( hCurrentCursor )
2445 SetCursor32(hCurrentCursor);
2447 /* send WM_DRAGLOOP */
2448 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2449 (LPARAM) spDragInfo );
2450 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2451 if( hCurrentWnd != lpDragInfo->hScope )
2453 if( hCurrentWnd )
2454 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2455 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2456 HIWORD(spDragInfo)) );
2457 hCurrentWnd = lpDragInfo->hScope;
2458 if( hCurrentWnd )
2459 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2461 else
2462 if( hCurrentWnd )
2463 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2465 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2467 ReleaseCapture();
2468 ShowCursor32( FALSE );
2470 if( hCursor )
2472 SetCursor32( hOldCursor );
2473 if (hDragCursor) DestroyCursor32( hDragCursor );
2476 if( hCurrentCursor != hBummer )
2477 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2478 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2479 else
2480 msg.lParam = 0;
2481 GlobalFree16(hDragInfo);
2483 return (DWORD)(msg.lParam);