Release 980503
[wine.git] / windows / win.c
blob5563a76e3f9ea1ebec197b13a98c1db9586ab230
1 /*
2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <X11/Xatom.h>
12 #include "options.h"
13 #include "class.h"
14 #include "win.h"
15 #include "heap.h"
16 #include "user.h"
17 #include "dce.h"
18 #include "sysmetrics.h"
19 #include "cursoricon.h"
20 #include "heap.h"
21 #include "hook.h"
22 #include "menu.h"
23 #include "message.h"
24 #include "nonclient.h"
25 #include "queue.h"
26 #include "winpos.h"
27 #include "color.h"
28 #include "shm_main_blk.h"
29 #include "dde_proc.h"
30 #include "clipboard.h"
31 #include "winproc.h"
32 #include "thread.h"
33 #include "debug.h"
35 /* Desktop window */
36 static WND *pWndDesktop = NULL;
38 static HWND32 hwndSysModal = 0;
40 static WORD wDragWidth = 4;
41 static WORD wDragHeight= 3;
43 extern BOOL32 ICONTITLE_Init(void);
44 extern BOOL32 MENU_PatchResidentPopup( HQUEUE16, WND* );
45 extern HWND32 CARET_GetHwnd(void);
46 extern BOOL32 EVENT_CheckFocus(void);
48 /***********************************************************************
49 * WIN_FindWndPtr
51 * Return a pointer to the WND structure corresponding to a HWND.
53 WND * WIN_FindWndPtr( HWND32 hwnd )
55 WND * ptr;
57 if (!hwnd || HIWORD(hwnd)) return NULL;
58 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
59 if (ptr->dwMagic != WND_MAGIC) return NULL;
60 if (ptr->hwndSelf != hwnd)
62 fprintf( stderr, "Can't happen: hwnd %04x self pointer is %04x\n",
63 hwnd, ptr->hwndSelf );
64 return NULL;
66 return ptr;
70 /***********************************************************************
71 * WIN_DumpWindow
73 * Dump the content of a window structure to stderr.
75 void WIN_DumpWindow( HWND32 hwnd )
77 WND *ptr;
78 char className[80];
79 int i;
81 if (!(ptr = WIN_FindWndPtr( hwnd )))
83 fprintf( stderr, "%04x is not a window handle\n", hwnd );
84 return;
87 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
88 strcpy( className, "#NULL#" );
90 fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
91 fprintf( stderr,
92 "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
93 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
94 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
95 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
96 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
97 ptr->next, ptr->child, ptr->parent, ptr->owner,
98 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
99 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
100 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
101 ptr->text ? ptr->text : "",
102 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
103 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
104 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
105 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
107 if (ptr->class->cbWndExtra)
109 fprintf( stderr, "extra bytes:" );
110 for (i = 0; i < ptr->class->cbWndExtra; i++)
111 fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
112 fprintf( stderr, "\n" );
114 fprintf( stderr, "\n" );
118 /***********************************************************************
119 * WIN_WalkWindows
121 * Walk the windows tree and print each window on stderr.
123 void WIN_WalkWindows( HWND32 hwnd, int indent )
125 WND *ptr;
126 char className[80];
128 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
129 if (!ptr)
131 fprintf( stderr, "*** Invalid window handle %04x\n", hwnd );
132 return;
135 if (!indent) /* first time around */
136 fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
137 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
139 while (ptr)
141 fprintf(stderr, "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
143 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
145 fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %08x\n",
146 (DWORD)ptr, ptr->hmemTaskQ, className,
147 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc );
149 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
150 ptr = ptr->next;
155 /***********************************************************************
156 * WIN_GetXWindow
158 * Return the X window associated to a window.
160 Window WIN_GetXWindow( HWND32 hwnd )
162 WND *wndPtr = WIN_FindWndPtr( hwnd );
163 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
164 return wndPtr ? wndPtr->window : 0;
168 /***********************************************************************
169 * WIN_UnlinkWindow
171 * Remove a window from the siblings linked list.
173 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
175 WND *wndPtr, **ppWnd;
177 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
178 ppWnd = &wndPtr->parent->child;
179 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
180 *ppWnd = wndPtr->next;
181 return TRUE;
185 /***********************************************************************
186 * WIN_LinkWindow
188 * Insert a window into the siblings linked list.
189 * The window is inserted after the specified window, which can also
190 * be specified as HWND_TOP or HWND_BOTTOM.
192 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
194 WND *wndPtr, **ppWnd;
196 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
198 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
200 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
201 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
202 while (*ppWnd) ppWnd = &(*ppWnd)->next;
204 else /* Normal case */
206 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
207 if (!afterPtr) return FALSE;
208 ppWnd = &afterPtr->next;
210 wndPtr->next = *ppWnd;
211 *ppWnd = wndPtr;
212 return TRUE;
216 /***********************************************************************
217 * WIN_FindWinToRepaint
219 * Find a window that needs repaint.
221 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
223 HWND32 hwndRet;
224 WND *pWnd = pWndDesktop;
226 /* Note: the desktop window never gets WM_PAINT messages
227 * The real reason why is because Windows DesktopWndProc
228 * does ValidateRgn inside WM_ERASEBKGND handler.
231 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
233 for ( ; pWnd ; pWnd = pWnd->next )
235 if (!(pWnd->dwStyle & WS_VISIBLE))
237 TRACE(win, "skipping window %04x\n",
238 pWnd->hwndSelf );
239 continue;
241 if ((pWnd->hmemTaskQ == hQueue) &&
242 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
244 if (pWnd->child )
245 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
246 return hwndRet;
249 if (!pWnd) return 0;
251 hwndRet = pWnd->hwndSelf;
253 /* look among siblings if we got a transparent window */
254 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
255 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
257 pWnd = pWnd->next;
259 if (pWnd) hwndRet = pWnd->hwndSelf;
260 TRACE(win,"found %04x\n",hwndRet);
261 return hwndRet;
265 /***********************************************************************
266 * WIN_DestroyWindow
268 * Destroy storage associated to a window. "Internals" p.358
270 static WND* WIN_DestroyWindow( WND* wndPtr )
272 HWND32 hwnd = wndPtr->hwndSelf;
273 WND *pWnd;
275 TRACE(win, "%04x\n", wndPtr->hwndSelf );
277 #ifdef CONFIG_IPC
278 if (main_block)
279 DDE_DestroyWindow(wndPtr->hwndSelf);
280 #endif /* CONFIG_IPC */
282 /* free child windows */
284 while ((pWnd = wndPtr->child))
285 wndPtr->child = WIN_DestroyWindow( pWnd );
287 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
289 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
291 WINPOS_CheckInternalPos( hwnd );
292 if( hwnd == GetCapture32()) ReleaseCapture();
294 /* free resources associated with the window */
296 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
297 PROPERTY_RemoveWindowProps( wndPtr );
299 wndPtr->dwMagic = 0; /* Mark it as invalid */
300 wndPtr->hwndSelf = 0;
302 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
304 if (wndPtr->hrgnUpdate > 1) DeleteObject32( wndPtr->hrgnUpdate );
305 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
308 /* toss stale messages from the queue */
310 if( wndPtr->hmemTaskQ )
312 int pos;
313 BOOL32 bPostQuit = FALSE;
314 WPARAM32 wQuitParam = 0;
315 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
317 while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
319 if( msgQ->messages[pos].msg.message == WM_QUIT )
321 bPostQuit = TRUE;
322 wQuitParam = msgQ->messages[pos].msg.wParam;
324 QUEUE_RemoveMsg(msgQ, pos);
326 /* repost WM_QUIT to make sure this app exits its message loop */
327 if( bPostQuit ) PostQuitMessage32(wQuitParam);
328 wndPtr->hmemTaskQ = 0;
331 if (!(wndPtr->dwStyle & WS_CHILD))
332 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
333 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
334 if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
335 if (wndPtr->class->style & CS_OWNDC) DCE_FreeWindowDCE( wndPtr );
337 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
339 wndPtr->class->cWindows--;
340 wndPtr->class = NULL;
341 pWnd = wndPtr->next;
343 USER_HEAP_FREE( hwnd );
344 return pWnd;
347 /***********************************************************************
348 * WIN_ResetQueueWindows
350 * Reset the queue of all the children of a given window.
351 * Return TRUE if something was done.
353 BOOL32 WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
355 BOOL32 ret = FALSE;
357 if (hNew) /* Set a new queue */
359 for (wnd = wnd->child; (wnd); wnd = wnd->next)
361 if (wnd->hmemTaskQ == hQueue)
363 wnd->hmemTaskQ = hNew;
364 ret = TRUE;
366 if (wnd->child)
367 ret |= WIN_ResetQueueWindows( wnd->child, hQueue, hNew );
370 else /* Queue is being destroyed */
372 while (wnd->child)
374 WND *tmp = wnd->child;
375 ret = FALSE;
376 while (tmp)
378 if (tmp->hmemTaskQ == hQueue)
380 DestroyWindow32( tmp->hwndSelf );
381 ret = TRUE;
382 break;
384 if (tmp->child && WIN_ResetQueueWindows(tmp->child,hQueue,0))
385 ret = TRUE;
386 else
387 tmp = tmp->next;
389 if (!ret) break;
392 return ret;
395 /***********************************************************************
396 * WIN_CreateDesktopWindow
398 * Create the desktop window.
400 BOOL32 WIN_CreateDesktopWindow(void)
402 CLASS *class;
403 HWND32 hwndDesktop;
405 TRACE(win,"Creating desktop window\n");
407 if (!ICONTITLE_Init() ||
408 !WINPOS_CreateInternalPosAtom() ||
409 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
410 return FALSE;
412 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
413 if (!hwndDesktop) return FALSE;
414 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
416 pWndDesktop->next = NULL;
417 pWndDesktop->child = NULL;
418 pWndDesktop->parent = NULL;
419 pWndDesktop->owner = NULL;
420 pWndDesktop->class = class;
421 pWndDesktop->dwMagic = WND_MAGIC;
422 pWndDesktop->hwndSelf = hwndDesktop;
423 pWndDesktop->hInstance = 0;
424 pWndDesktop->rectWindow.left = 0;
425 pWndDesktop->rectWindow.top = 0;
426 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
427 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
428 pWndDesktop->rectClient = pWndDesktop->rectWindow;
429 pWndDesktop->text = NULL;
430 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
431 pWndDesktop->hrgnUpdate = 0;
432 pWndDesktop->hwndLastActive = hwndDesktop;
433 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
434 WS_CLIPSIBLINGS;
435 pWndDesktop->dwExStyle = 0;
436 pWndDesktop->dce = NULL;
437 pWndDesktop->pVScroll = NULL;
438 pWndDesktop->pHScroll = NULL;
439 pWndDesktop->pProp = NULL;
440 pWndDesktop->wIDmenu = 0;
441 pWndDesktop->helpContext = 0;
442 pWndDesktop->flags = 0;
443 pWndDesktop->window = rootWindow;
444 pWndDesktop->hSysMenu = 0;
445 pWndDesktop->userdata = 0;
447 pWndDesktop->winproc = (WNDPROC16)class->winproc;
449 EVENT_RegisterWindow( pWndDesktop );
450 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
451 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
452 return TRUE;
456 /***********************************************************************
457 * WIN_CreateWindowEx
459 * Implementation of CreateWindowEx().
461 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
462 BOOL32 win32, BOOL32 unicode )
464 CLASS *classPtr;
465 WND *wndPtr;
466 HWND16 hwnd, hwndLinkAfter;
467 POINT32 maxSize, maxPos, minTrack, maxTrack;
468 LRESULT (WINAPI *localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
470 TRACE(win, "%s %s %08lx %08lx %d,%d %dx%d "
471 "%04x %04x %08x %p\n", debugres_a(cs->lpszName),
472 debugres_a(cs->lpszClass), cs->dwExStyle,
473 cs->style, cs->x, cs->y, cs->cx, cs->cy,
474 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
476 /* Find the parent window */
478 if (cs->hwndParent)
480 /* Make sure parent is valid */
481 if (!IsWindow32( cs->hwndParent ))
483 fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
484 return 0;
486 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
487 fprintf( stderr, "CreateWindowEx: no parent for child window\n" );
488 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
491 /* Find the window class */
492 if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
494 char buffer[256];
495 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
496 fprintf( stderr, "CreateWindowEx: bad class '%s'\n", buffer );
497 return 0;
500 /* Fix the coordinates */
502 if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0;
503 if (cs->cx == CW_USEDEFAULT32)
505 /* if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0;
506 else */
508 cs->cx = 600;
509 cs->cy = 400;
513 /* Create the window structure */
515 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
516 - sizeof(wndPtr->wExtra) )))
518 TRACE(win, "out of memory\n" );
519 return 0;
522 /* Fill the window structure */
524 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
525 wndPtr->next = NULL;
526 wndPtr->child = NULL;
528 if ((cs->style & WS_CHILD) && cs->hwndParent)
530 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
531 wndPtr->owner = NULL;
533 else
535 wndPtr->parent = pWndDesktop;
536 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
537 wndPtr->owner = NULL;
538 else
539 wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
542 wndPtr->window = 0;
543 wndPtr->class = classPtr;
544 wndPtr->winproc = classPtr->winproc;
545 wndPtr->dwMagic = WND_MAGIC;
546 wndPtr->hwndSelf = hwnd;
547 wndPtr->hInstance = cs->hInstance;
548 wndPtr->text = NULL;
549 wndPtr->hmemTaskQ = GetTaskQueue(0);
550 wndPtr->hrgnUpdate = 0;
551 wndPtr->hwndLastActive = hwnd;
552 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
553 wndPtr->dwExStyle = cs->dwExStyle;
554 wndPtr->wIDmenu = 0;
555 wndPtr->helpContext = 0;
556 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
557 wndPtr->pVScroll = NULL;
558 wndPtr->pHScroll = NULL;
559 wndPtr->pProp = NULL;
560 wndPtr->userdata = 0;
561 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
562 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
564 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
566 /* Call the WH_CBT hook */
568 hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
570 if (HOOK_IsHooked( WH_CBT ))
572 CBT_CREATEWND32A cbtc;
574 cbtc.lpcs = cs;
575 cbtc.hwndInsertAfter = hwndLinkAfter;
576 if ( HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc) )
578 TRACE(win, "CBT-hook returned 0\n");
579 USER_HEAP_FREE( hwnd );
580 return 0;
584 /* Increment class window counter */
586 classPtr->cWindows++;
588 /* Correct the window style */
590 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
592 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
593 wndPtr->flags |= WIN_NEED_SIZE;
595 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
597 /* Get class or window DC if needed */
599 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
600 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
601 else wndPtr->dce = NULL;
603 /* Insert the window in the linked list */
605 WIN_LinkWindow( hwnd, hwndLinkAfter );
607 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
609 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
611 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
612 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
613 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
614 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
615 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
618 if(cs->style & WS_CHILD)
620 if(cs->cx < 0) cs->cx = 0;
621 if(cs->cy < 0) cs->cy = 0;
623 else
625 if (cs->cx <= 0) cs->cx = 1;
626 if (cs->cy <= 0) cs->cy = 1;
629 wndPtr->rectWindow.left = cs->x;
630 wndPtr->rectWindow.top = cs->y;
631 wndPtr->rectWindow.right = cs->x + cs->cx;
632 wndPtr->rectWindow.bottom = cs->y + cs->cy;
633 wndPtr->rectClient = wndPtr->rectWindow;
635 /* Create the X window (only for top-level windows, and then only */
636 /* when there's no desktop window) */
638 if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
640 XSetWindowAttributes win_attr;
642 if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
643 (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
645 win_attr.event_mask = ExposureMask | KeyPressMask |
646 KeyReleaseMask | PointerMotionMask |
647 ButtonPressMask | ButtonReleaseMask |
648 FocusChangeMask | StructureNotifyMask;
649 win_attr.override_redirect = FALSE;
650 wndPtr->flags |= WIN_MANAGED;
652 else
654 win_attr.event_mask = ExposureMask | KeyPressMask |
655 KeyReleaseMask | PointerMotionMask |
656 ButtonPressMask | ButtonReleaseMask |
657 FocusChangeMask;
658 win_attr.override_redirect = TRUE;
660 win_attr.colormap = COLOR_GetColormap();
661 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
662 win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
663 win_attr.cursor = CURSORICON_XCursor;
664 wndPtr->window = TSXCreateWindow( display, rootWindow, cs->x, cs->y,
665 cs->cx, cs->cy, 0, CopyFromParent,
666 InputOutput, CopyFromParent,
667 CWEventMask | CWOverrideRedirect |
668 CWColormap | CWCursor | CWSaveUnder |
669 CWBackingStore, &win_attr );
671 if ((wndPtr->flags & WIN_MANAGED) &&
672 (cs->dwExStyle & WS_EX_DLGMODALFRAME))
674 XSizeHints* size_hints = TSXAllocSizeHints();
676 if (size_hints)
678 size_hints->min_width = size_hints->max_width = cs->cx;
679 size_hints->min_height = size_hints->max_height = cs->cy;
680 size_hints->flags = (PSize | PMinSize | PMaxSize);
681 TSXSetWMSizeHints( display, wndPtr->window, size_hints,
682 XA_WM_NORMAL_HINTS );
683 TSXFree(size_hints);
687 if (cs->hwndParent) /* Get window owner */
689 Window win = WIN_GetXWindow( cs->hwndParent );
690 if (win) TSXSetTransientForHint( display, wndPtr->window, win );
692 EVENT_RegisterWindow( wndPtr );
695 /* Set the window menu */
697 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
699 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
700 else
702 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
703 if (classPtr->menuNameA)
704 cs->hMenu = HIWORD(classPtr->menuNameA) ?
705 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
706 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
707 #else
708 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
709 if (menuName)
711 /* hInstance is still 16-bit in 980215 winelib */
712 if (HIWORD(cs->hInstance) || __winelib)
713 cs->hMenu = LoadMenu32A(cs->hInstance,PTR_SEG_TO_LIN(menuName));
714 else
715 /* doesn't work for winelib, since resources are unicode */
716 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
718 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
720 #endif
723 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
725 /* Send the WM_CREATE message
726 * Perhaps we shouldn't allow width/height changes as well.
727 * See p327 in "Internals".
730 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
732 localSend32 = unicode ? SendMessage32W : SendMessage32A;
733 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
735 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
736 NULL, NULL, 0, &wndPtr->rectClient );
737 OffsetRect32(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
738 maxPos.y - wndPtr->rectWindow.top);
739 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
741 /* Send the size messages */
743 if (!(wndPtr->flags & WIN_NEED_SIZE))
745 /* send it anyway */
746 if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
747 ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
748 WARN(win,"sending bogus WM_SIZE message 0x%08lx\n",
749 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
750 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
751 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
752 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
753 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
754 SendMessage32A( hwnd, WM_MOVE, 0,
755 MAKELONG( wndPtr->rectClient.left,
756 wndPtr->rectClient.top ) );
759 /* Show the window, maximizing or minimizing if needed */
761 if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
763 RECT16 newPos;
764 UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
765 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
766 WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
767 swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow32()) ? SWP_NOACTIVATE : 0;
768 SetWindowPos32( hwnd, 0, newPos.left, newPos.top,
769 newPos.right, newPos.bottom, SWP_FRAMECHANGED | swFlag );
772 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
774 /* Notify the parent window only */
776 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
777 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
778 if( !IsWindow32(hwnd) ) return 0;
781 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
783 /* Call WH_SHELL hook */
785 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
786 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
788 TRACE(win, "created window %04x\n", hwnd);
789 return hwnd;
793 /* Abort window creation */
795 WARN(win, "aborted by WM_xxCREATE!\n");
796 WIN_UnlinkWindow( hwnd );
797 WIN_DestroyWindow( wndPtr );
798 return 0;
802 /***********************************************************************
803 * CreateWindow16 (USER.41)
805 HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
806 DWORD style, INT16 x, INT16 y, INT16 width,
807 INT16 height, HWND16 parent, HMENU16 menu,
808 HINSTANCE16 instance, LPVOID data )
810 return CreateWindowEx16( 0, className, windowName, style,
811 x, y, width, height, parent, menu, instance, data );
815 /***********************************************************************
816 * CreateWindowEx16 (USER.452)
818 HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
819 LPCSTR windowName, DWORD style, INT16 x,
820 INT16 y, INT16 width, INT16 height,
821 HWND16 parent, HMENU16 menu,
822 HINSTANCE16 instance, LPVOID data )
824 ATOM classAtom;
825 CREATESTRUCT32A cs;
827 /* Find the class atom */
829 if (!(classAtom = GlobalFindAtom32A( className )))
831 fprintf( stderr, "CreateWindowEx16: bad class name " );
832 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
833 else fprintf( stderr, "'%s'\n", className );
834 return 0;
837 /* Fix the coordinates */
839 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
840 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
841 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
842 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
844 /* Create the window */
846 cs.lpCreateParams = data;
847 cs.hInstance = (HINSTANCE32)instance;
848 cs.hMenu = (HMENU32)menu;
849 cs.hwndParent = (HWND32)parent;
850 cs.style = style;
851 cs.lpszName = windowName;
852 cs.lpszClass = className;
853 cs.dwExStyle = exStyle;
854 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
858 /***********************************************************************
859 * CreateWindowEx32A (USER32.83)
861 HWND32 WINAPI CreateWindowEx32A( DWORD exStyle, LPCSTR className,
862 LPCSTR windowName, DWORD style, INT32 x,
863 INT32 y, INT32 width, INT32 height,
864 HWND32 parent, HMENU32 menu,
865 HINSTANCE32 instance, LPVOID data )
867 ATOM classAtom;
868 CREATESTRUCT32A cs;
870 /* Find the class atom */
872 if (!(classAtom = GlobalFindAtom32A( className )))
874 fprintf( stderr, "CreateWindowEx32A: bad class name " );
875 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
876 else fprintf( stderr, "'%s'\n", className );
877 return 0;
880 /* Create the window */
882 cs.lpCreateParams = data;
883 cs.hInstance = instance;
884 cs.hMenu = menu;
885 cs.hwndParent = parent;
886 cs.x = x;
887 cs.y = y;
888 cs.cx = width;
889 cs.cy = height;
890 cs.style = style;
891 cs.lpszName = windowName;
892 cs.lpszClass = className;
893 cs.dwExStyle = exStyle;
894 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
898 /***********************************************************************
899 * CreateWindowEx32W (USER32.84)
901 HWND32 WINAPI CreateWindowEx32W( DWORD exStyle, LPCWSTR className,
902 LPCWSTR windowName, DWORD style, INT32 x,
903 INT32 y, INT32 width, INT32 height,
904 HWND32 parent, HMENU32 menu,
905 HINSTANCE32 instance, LPVOID data )
907 ATOM classAtom;
908 CREATESTRUCT32W cs;
910 /* Find the class atom */
912 if (!(classAtom = GlobalFindAtom32W( className )))
914 if (HIWORD(className))
916 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
917 fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
918 HeapFree( GetProcessHeap(), 0, cn );
920 else
921 fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
922 return 0;
925 /* Create the window */
927 cs.lpCreateParams = data;
928 cs.hInstance = instance;
929 cs.hMenu = menu;
930 cs.hwndParent = parent;
931 cs.x = x;
932 cs.y = y;
933 cs.cx = width;
934 cs.cy = height;
935 cs.style = style;
936 cs.lpszName = windowName;
937 cs.lpszClass = className;
938 cs.dwExStyle = exStyle;
939 /* Note: we rely on the fact that CREATESTRUCT32A and */
940 /* CREATESTRUCT32W have the same layout. */
941 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
945 /***********************************************************************
946 * WIN_CheckFocus
948 static void WIN_CheckFocus( WND* pWnd )
950 if( GetFocus16() == pWnd->hwndSelf )
951 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
954 /***********************************************************************
955 * WIN_SendDestroyMsg
957 static void WIN_SendDestroyMsg( WND* pWnd )
959 WIN_CheckFocus(pWnd);
961 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
962 if( !pWnd->window ) CLIPBOARD_ResetOwner( pWnd );
964 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
966 if( IsWindow32(pWnd->hwndSelf) )
968 WND* pChild = pWnd->child;
969 while( pChild )
971 WIN_SendDestroyMsg( pChild );
972 pChild = pChild->next;
974 WIN_CheckFocus(pWnd);
976 else
977 WARN(win, "\tdestroyed itself while in WM_DESTROY!\n");
981 /***********************************************************************
982 * DestroyWindow16 (USER.53)
984 BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
986 return DestroyWindow32(hwnd);
990 /***********************************************************************
991 * DestroyWindow32 (USER32.135)
993 BOOL32 WINAPI DestroyWindow32( HWND32 hwnd )
995 WND * wndPtr;
997 TRACE(win, "(%04x)\n", hwnd);
999 /* Initialization */
1001 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1002 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
1004 /* Call hooks */
1006 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
1007 return FALSE;
1009 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1011 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
1012 /* FIXME: clean up palette - see "Internals" p.352 */
1015 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
1016 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
1018 /* Notify the parent window only */
1019 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
1020 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
1021 if( !IsWindow32(hwnd) ) return TRUE;
1024 if( wndPtr->window ) CLIPBOARD_ResetOwner( wndPtr ); /* before the window is unmapped */
1026 /* Hide the window */
1028 if (wndPtr->dwStyle & WS_VISIBLE)
1030 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
1031 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
1032 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
1033 if (!IsWindow32(hwnd)) return TRUE;
1036 /* Recursively destroy owned windows */
1038 if( !(wndPtr->dwStyle & WS_CHILD) )
1040 /* make sure top menu popup doesn't get destroyed */
1041 MENU_PatchResidentPopup( (HQUEUE16)0xFFFF, wndPtr );
1043 for (;;)
1045 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1046 while (siblingPtr)
1048 if (siblingPtr->owner == wndPtr)
1049 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1050 break;
1051 else
1052 siblingPtr->owner = NULL;
1053 siblingPtr = siblingPtr->next;
1055 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1056 else break;
1059 if( !Options.managed || EVENT_CheckFocus() )
1060 WINPOS_ActivateOtherWindow(wndPtr);
1062 if( wndPtr->owner &&
1063 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1064 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1067 /* Send destroy messages */
1069 WIN_SendDestroyMsg( wndPtr );
1070 if (!IsWindow32(hwnd)) return TRUE;
1072 /* Unlink now so we won't bother with the children later on */
1074 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1076 /* Destroy the window storage */
1078 WIN_DestroyWindow( wndPtr );
1079 return TRUE;
1083 /***********************************************************************
1084 * CloseWindow16 (USER.43)
1086 BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
1088 return CloseWindow32( hwnd );
1092 /***********************************************************************
1093 * CloseWindow32 (USER32.56)
1095 BOOL32 WINAPI CloseWindow32( HWND32 hwnd )
1097 WND * wndPtr = WIN_FindWndPtr( hwnd );
1098 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1099 ShowWindow32( hwnd, SW_MINIMIZE );
1100 return TRUE;
1104 /***********************************************************************
1105 * OpenIcon16 (USER.44)
1107 BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
1109 return OpenIcon32( hwnd );
1113 /***********************************************************************
1114 * OpenIcon32 (USER32.410)
1116 BOOL32 WINAPI OpenIcon32( HWND32 hwnd )
1118 if (!IsIconic32( hwnd )) return FALSE;
1119 ShowWindow32( hwnd, SW_SHOWNORMAL );
1120 return TRUE;
1124 /***********************************************************************
1125 * WIN_FindWindow
1127 * Implementation of FindWindow() and FindWindowEx().
1129 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1130 LPCSTR title )
1132 WND *pWnd;
1133 CLASS *pClass = NULL;
1135 if (child)
1137 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1138 if (parent)
1140 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1142 else if (pWnd->parent != pWndDesktop) return 0;
1143 pWnd = pWnd->next;
1145 else
1147 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1148 pWnd = pWnd->child;
1150 if (!pWnd) return 0;
1152 /* For a child window, all siblings will have the same hInstance, */
1153 /* so we can look for the class once and for all. */
1155 if (className && (pWnd->dwStyle & WS_CHILD))
1157 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1158 return 0;
1162 for ( ; pWnd; pWnd = pWnd->next)
1164 if (className && !(pWnd->dwStyle & WS_CHILD))
1166 if (!(pClass = CLASS_FindClassByAtom( className, GetExePtr(pWnd->hInstance))))
1167 continue; /* Skip this window */
1170 if (pClass && (pWnd->class != pClass))
1171 continue; /* Not the right class */
1173 /* Now check the title */
1175 if (!title) return pWnd->hwndSelf;
1176 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1178 return 0;
1183 /***********************************************************************
1184 * FindWindow16 (USER.50)
1186 HWND16 WINAPI FindWindow16( SEGPTR className, LPCSTR title )
1188 return FindWindowEx16( 0, 0, className, title );
1192 /***********************************************************************
1193 * FindWindowEx16 (USER.427)
1195 HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child,
1196 SEGPTR className, LPCSTR title )
1198 ATOM atom = 0;
1200 TRACE(win, "%04x %04x '%s' '%s'\n", parent,
1201 child, HIWORD(className)?(char *)PTR_SEG_TO_LIN(className):"",
1202 title ? title : "");
1204 if (className)
1206 /* If the atom doesn't exist, then no class */
1207 /* with this name exists either. */
1208 if (!(atom = GlobalFindAtom16( className ))) return 0;
1210 return WIN_FindWindow( parent, child, atom, title );
1214 /***********************************************************************
1215 * FindWindow32A (USER32.198)
1217 HWND32 WINAPI FindWindow32A( LPCSTR className, LPCSTR title )
1219 return FindWindowEx32A( 0, 0, className, title );
1223 /***********************************************************************
1224 * FindWindowEx32A (USER32.199)
1226 HWND32 WINAPI FindWindowEx32A( HWND32 parent, HWND32 child,
1227 LPCSTR className, LPCSTR title )
1229 ATOM atom = 0;
1231 if (className)
1233 /* If the atom doesn't exist, then no class */
1234 /* with this name exists either. */
1235 if (!(atom = GlobalFindAtom32A( className ))) return 0;
1237 return WIN_FindWindow( parent, child, atom, title );
1241 /***********************************************************************
1242 * FindWindowEx32W (USER32.200)
1244 HWND32 WINAPI FindWindowEx32W( HWND32 parent, HWND32 child,
1245 LPCWSTR className, LPCWSTR title )
1247 ATOM atom = 0;
1248 char *buffer;
1249 HWND32 hwnd;
1251 if (className)
1253 /* If the atom doesn't exist, then no class */
1254 /* with this name exists either. */
1255 if (!(atom = GlobalFindAtom32W( className ))) return 0;
1257 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1258 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1259 HeapFree( GetProcessHeap(), 0, buffer );
1260 return hwnd;
1264 /***********************************************************************
1265 * FindWindow32W (USER32.201)
1267 HWND32 WINAPI FindWindow32W( LPCWSTR className, LPCWSTR title )
1269 return FindWindowEx32W( 0, 0, className, title );
1273 /**********************************************************************
1274 * WIN_GetDesktop
1276 WND *WIN_GetDesktop(void)
1278 return pWndDesktop;
1282 /**********************************************************************
1283 * GetDesktopWindow16 (USER.286)
1285 HWND16 WINAPI GetDesktopWindow16(void)
1287 return (HWND16)pWndDesktop->hwndSelf;
1291 /**********************************************************************
1292 * GetDesktopWindow32 (USER32.232)
1294 HWND32 WINAPI GetDesktopWindow32(void)
1296 return pWndDesktop->hwndSelf;
1300 /**********************************************************************
1301 * GetDesktopHwnd (USER.278)
1303 * Exactly the same thing as GetDesktopWindow(), but not documented.
1304 * Don't ask me why...
1306 HWND16 WINAPI GetDesktopHwnd(void)
1308 return (HWND16)pWndDesktop->hwndSelf;
1312 /*******************************************************************
1313 * EnableWindow16 (USER.34)
1315 BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
1317 return EnableWindow32( hwnd, enable );
1321 /*******************************************************************
1322 * EnableWindow32 (USER32.172)
1324 BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
1326 WND *wndPtr;
1328 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1329 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1331 /* Enable window */
1332 wndPtr->dwStyle &= ~WS_DISABLED;
1333 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1334 return TRUE;
1336 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1338 /* Disable window */
1339 wndPtr->dwStyle |= WS_DISABLED;
1340 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1341 SetFocus32( 0 ); /* A disabled window can't have the focus */
1342 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1343 ReleaseCapture(); /* A disabled window can't capture the mouse */
1344 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1345 return FALSE;
1347 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1351 /***********************************************************************
1352 * IsWindowEnabled16 (USER.35)
1354 BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
1356 return IsWindowEnabled32(hWnd);
1360 /***********************************************************************
1361 * IsWindowEnabled32 (USER32.349)
1363 BOOL32 WINAPI IsWindowEnabled32(HWND32 hWnd)
1365 WND * wndPtr;
1367 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1368 return !(wndPtr->dwStyle & WS_DISABLED);
1372 /***********************************************************************
1373 * IsWindowUnicode (USER32.350)
1375 BOOL32 WINAPI IsWindowUnicode( HWND32 hwnd )
1377 WND * wndPtr;
1379 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1380 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1384 /**********************************************************************
1385 * GetWindowWord16 (USER.133)
1387 WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
1389 return GetWindowWord32( hwnd, offset );
1393 /**********************************************************************
1394 * GetWindowWord32 (USER32.314)
1396 WORD WINAPI GetWindowWord32( HWND32 hwnd, INT32 offset )
1398 WND * wndPtr = WIN_FindWndPtr( hwnd );
1399 if (!wndPtr) return 0;
1400 if (offset >= 0)
1402 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1404 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1405 return 0;
1407 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1409 switch(offset)
1411 case GWW_ID:
1412 if (HIWORD(wndPtr->wIDmenu))
1413 fprintf(stderr,"GetWindowWord32(GWW_ID) discards high bits of 0x%08x!\n",wndPtr->wIDmenu);
1414 return (WORD)wndPtr->wIDmenu;
1415 case GWW_HWNDPARENT: return wndPtr->parent ?
1416 wndPtr->parent->hwndSelf : wndPtr->owner->hwndSelf;
1417 case GWW_HINSTANCE:
1418 if (HIWORD(wndPtr->hInstance))
1419 fprintf(stderr,"GetWindowWord32(GWW_HINSTANCE) discards high bits of 0x%08x!\n",wndPtr->hInstance);
1420 return (WORD)wndPtr->hInstance;
1421 default:
1422 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1423 return 0;
1428 /**********************************************************************
1429 * WIN_GetWindowInstance
1431 HINSTANCE32 WIN_GetWindowInstance( HWND32 hwnd )
1433 WND * wndPtr = WIN_FindWndPtr( hwnd );
1434 if (!wndPtr) return (HINSTANCE32)0;
1435 return wndPtr->hInstance;
1439 /**********************************************************************
1440 * SetWindowWord16 (USER.134)
1442 WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1444 return SetWindowWord32( hwnd, offset, newval );
1448 /**********************************************************************
1449 * SetWindowWord32 (USER32.524)
1451 WORD WINAPI SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1453 WORD *ptr, retval;
1454 WND * wndPtr = WIN_FindWndPtr( hwnd );
1455 if (!wndPtr) return 0;
1456 if (offset >= 0)
1458 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1460 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1461 return 0;
1463 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1465 else switch(offset)
1467 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1468 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1469 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1470 default:
1471 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1472 return 0;
1474 retval = *ptr;
1475 *ptr = newval;
1476 return retval;
1480 /**********************************************************************
1481 * WIN_GetWindowLong
1483 * Helper function for GetWindowLong().
1485 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1487 LONG retval;
1488 WND * wndPtr = WIN_FindWndPtr( hwnd );
1489 if (!wndPtr) return 0;
1490 if (offset >= 0)
1492 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1494 fprintf( stderr, "GetWindowLong: invalid offset %d\n", offset );
1495 return 0;
1497 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1498 /* Special case for dialog window procedure */
1499 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1500 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1501 return retval;
1503 switch(offset)
1505 case GWL_USERDATA: return wndPtr->userdata;
1506 case GWL_STYLE: return wndPtr->dwStyle;
1507 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1508 case GWL_ID: return (LONG)wndPtr->wIDmenu;
1509 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1510 type );
1511 case GWL_HWNDPARENT: return wndPtr->parent ?
1512 (HWND32)wndPtr->parent->hwndSelf : 0;
1513 case GWL_HINSTANCE: return wndPtr->hInstance;
1514 default:
1515 fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
1517 return 0;
1521 /**********************************************************************
1522 * WIN_SetWindowLong
1524 * Helper function for SetWindowLong().
1526 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1527 WINDOWPROCTYPE type )
1529 LONG *ptr, retval;
1530 WND * wndPtr = WIN_FindWndPtr( hwnd );
1532 if (!wndPtr) return 0;
1533 if (offset >= 0)
1535 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1537 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1538 return 0;
1540 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1541 /* Special case for dialog window procedure */
1542 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1544 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1545 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1546 type, WIN_PROC_WINDOW );
1547 return retval;
1550 else switch(offset)
1552 case GWL_ID:
1553 ptr = (DWORD*)&wndPtr->wIDmenu;
1554 break;
1555 case GWL_HINSTANCE:
1556 return SetWindowWord32( hwnd, offset, newval );
1557 case GWL_WNDPROC:
1558 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1559 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1560 type, WIN_PROC_WINDOW );
1561 return retval;
1562 case GWL_STYLE:
1564 /* FIXME: WM_STYLE... messages for WIN_ISWIN32 windows */
1566 ptr = &wndPtr->dwStyle;
1567 /* Some bits can't be changed this way */
1568 newval &= ~(WS_VISIBLE | WS_CHILD);
1569 newval |= (*ptr & (WS_VISIBLE | WS_CHILD));
1570 break;
1571 case GWL_USERDATA: ptr = &wndPtr->userdata; break;
1572 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
1573 default:
1574 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1575 return 0;
1577 retval = *ptr;
1578 *ptr = newval;
1579 return retval;
1583 /**********************************************************************
1584 * GetWindowLong16 (USER.135)
1586 LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
1588 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1592 /**********************************************************************
1593 * GetWindowLong32A (USER32.305)
1595 LONG WINAPI GetWindowLong32A( HWND32 hwnd, INT32 offset )
1597 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1601 /**********************************************************************
1602 * GetWindowLong32W (USER32.306)
1604 LONG WINAPI GetWindowLong32W( HWND32 hwnd, INT32 offset )
1606 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1610 /**********************************************************************
1611 * SetWindowLong16 (USER.136)
1613 LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1615 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1619 /**********************************************************************
1620 * SetWindowLong32A (USER32.517)
1622 LONG WINAPI SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1624 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1628 /**********************************************************************
1629 * SetWindowLong32W (USER32.518)
1631 LONG WINAPI SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
1633 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1637 /*******************************************************************
1638 * GetWindowText16 (USER.36)
1640 INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1642 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1646 /*******************************************************************
1647 * GetWindowText32A (USER32.309)
1649 INT32 WINAPI GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1651 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1652 (LPARAM)lpString );
1656 /*******************************************************************
1657 * GetWindowText32W (USER32.312)
1659 INT32 WINAPI GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1661 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1662 (LPARAM)lpString );
1666 /*******************************************************************
1667 * SetWindowText16 (USER.37)
1669 void WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1671 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1675 /*******************************************************************
1676 * SetWindowText32A (USER32.521)
1678 void WINAPI SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1680 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1684 /*******************************************************************
1685 * SetWindowText32W (USER32.523)
1687 void WINAPI SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1689 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1693 /*******************************************************************
1694 * GetWindowTextLength16 (USER.38)
1696 INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
1698 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1702 /*******************************************************************
1703 * GetWindowTextLength32A (USER32.310)
1705 INT32 WINAPI GetWindowTextLength32A( HWND32 hwnd )
1707 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1710 /*******************************************************************
1711 * GetWindowTextLength32W (USER32.311)
1713 INT32 WINAPI GetWindowTextLength32W( HWND32 hwnd )
1715 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1719 /*******************************************************************
1720 * IsWindow16 (USER.47)
1722 BOOL16 WINAPI IsWindow16( HWND16 hwnd )
1724 return IsWindow32( hwnd );
1728 /*******************************************************************
1729 * IsWindow32 (USER32.348)
1731 BOOL32 WINAPI IsWindow32( HWND32 hwnd )
1733 WND * wndPtr = WIN_FindWndPtr( hwnd );
1734 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1738 /*****************************************************************
1739 * GetParent16 (USER.46)
1741 HWND16 WINAPI GetParent16( HWND16 hwnd )
1743 return (HWND16)GetParent32( hwnd );
1747 /*****************************************************************
1748 * GetParent32 (USER32.278)
1750 HWND32 WINAPI GetParent32( HWND32 hwnd )
1752 WND *wndPtr = WIN_FindWndPtr(hwnd);
1753 if ((!wndPtr) || (!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD)))) return 0;
1754 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1755 return wndPtr ? wndPtr->hwndSelf : 0;
1758 /*****************************************************************
1759 * WIN_GetTopParent
1761 * Get the top-level parent for a child window.
1763 WND* WIN_GetTopParentPtr( WND* pWnd )
1765 while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
1766 return pWnd;
1769 /*****************************************************************
1770 * WIN_GetTopParent
1772 * Get the top-level parent for a child window.
1774 HWND32 WIN_GetTopParent( HWND32 hwnd )
1776 WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
1777 return wndPtr ? wndPtr->hwndSelf : 0;
1781 /*****************************************************************
1782 * SetParent16 (USER.233)
1784 HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1786 return SetParent32( hwndChild, hwndNewParent );
1790 /*****************************************************************
1791 * SetParent32 (USER32.495)
1793 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1795 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1796 WND *pWndParent = (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent )
1797 : pWndDesktop;
1799 if( wndPtr && pWndParent && (wndPtr != pWndDesktop) )
1801 WND* pWndPrev = wndPtr->parent;
1803 if( pWndParent != pWndPrev )
1805 BOOL32 bFixupDCE = IsWindowVisible32(hwndChild);
1807 if ( wndPtr->window )
1809 /* Toplevel window needs to be reparented. Used by Tk 8.0 */
1811 TSXDestroyWindow( display, wndPtr->window );
1812 wndPtr->window = None;
1814 else if( bFixupDCE )
1815 DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
1817 WIN_UnlinkWindow(hwndChild);
1818 wndPtr->parent = pWndParent;
1820 /* FIXME: Create an X counterpart for reparented top-level windows
1821 * when not in the desktop mode. */
1823 if ( pWndParent == pWndDesktop )
1824 wndPtr->dwStyle &= ~WS_CHILD;
1825 else wndPtr->dwStyle |= WS_CHILD;
1826 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
1828 if( bFixupDCE )
1830 DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
1831 UpdateWindow32(hwndChild);
1834 return pWndPrev->hwndSelf;
1835 } /* failure */
1836 return 0;
1840 /*******************************************************************
1841 * IsChild16 (USER.48)
1843 BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
1845 return IsChild32(parent,child);
1849 /*******************************************************************
1850 * IsChild32 (USER32.339)
1852 BOOL32 WINAPI IsChild32( HWND32 parent, HWND32 child )
1854 WND * wndPtr = WIN_FindWndPtr( child );
1855 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1857 wndPtr = wndPtr->parent;
1858 if (wndPtr->hwndSelf == parent) return TRUE;
1860 return FALSE;
1864 /***********************************************************************
1865 * IsWindowVisible16 (USER.49)
1867 BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
1869 return IsWindowVisible32(hwnd);
1873 /***********************************************************************
1874 * IsWindowVisible32 (USER32.351)
1876 BOOL32 WINAPI IsWindowVisible32( HWND32 hwnd )
1878 WND *wndPtr = WIN_FindWndPtr( hwnd );
1879 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1881 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1882 wndPtr = wndPtr->parent;
1884 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1888 /***********************************************************************
1889 * WIN_IsWindowDrawable
1891 * hwnd is drawable when it is visible, all parents are not
1892 * minimized, and it is itself not minimized unless we are
1893 * trying to draw its default class icon.
1895 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
1897 if( (wnd->dwStyle & WS_MINIMIZE &&
1898 icon && wnd->class->hIcon) ||
1899 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
1900 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
1901 if( wnd->dwStyle & WS_MINIMIZE ||
1902 !(wnd->dwStyle & WS_VISIBLE) ) break;
1903 return (wnd == NULL);
1907 /*******************************************************************
1908 * GetTopWindow16 (USER.229)
1910 HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
1912 return GetTopWindow32(hwnd);
1916 /*******************************************************************
1917 * GetTopWindow32 (USER.229)
1919 HWND32 WINAPI GetTopWindow32( HWND32 hwnd )
1921 WND * wndPtr = WIN_FindWndPtr( hwnd );
1922 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1923 else return 0;
1927 /*******************************************************************
1928 * GetWindow16 (USER.262)
1930 HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
1932 return GetWindow32( hwnd,rel );
1936 /*******************************************************************
1937 * GetWindow32 (USER32.302)
1939 HWND32 WINAPI GetWindow32( HWND32 hwnd, WORD rel )
1941 WND * wndPtr = WIN_FindWndPtr( hwnd );
1942 if (!wndPtr) return 0;
1943 switch(rel)
1945 case GW_HWNDFIRST:
1946 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
1947 else return 0;
1949 case GW_HWNDLAST:
1950 if (!wndPtr->parent) return 0; /* Desktop window */
1951 while (wndPtr->next) wndPtr = wndPtr->next;
1952 return wndPtr->hwndSelf;
1954 case GW_HWNDNEXT:
1955 if (!wndPtr->next) return 0;
1956 return wndPtr->next->hwndSelf;
1958 case GW_HWNDPREV:
1959 if (!wndPtr->parent) return 0; /* Desktop window */
1960 wndPtr = wndPtr->parent->child; /* First sibling */
1961 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
1962 while (wndPtr->next)
1964 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
1965 wndPtr = wndPtr->next;
1967 return 0;
1969 case GW_OWNER:
1970 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
1972 case GW_CHILD:
1973 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
1975 return 0;
1979 /*******************************************************************
1980 * GetNextWindow16 (USER.230)
1982 HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
1984 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1985 return GetWindow16( hwnd, flag );
1988 /*******************************************************************
1989 * ShowOwnedPopups16 (USER.265)
1991 void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
1993 ShowOwnedPopups32( owner, fShow );
1997 /*******************************************************************
1998 * ShowOwnedPopups32 (USER32.531)
2000 BOOL32 WINAPI ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
2002 WND *pWnd = pWndDesktop->child;
2003 while (pWnd)
2005 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
2006 (pWnd->dwStyle & WS_POPUP))
2007 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
2008 pWnd = pWnd->next;
2010 return TRUE;
2014 /*******************************************************************
2015 * GetLastActivePopup16 (USER.287)
2017 HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
2019 return GetLastActivePopup32( hwnd );
2022 /*******************************************************************
2023 * GetLastActivePopup32 (USER32.256)
2025 HWND32 WINAPI GetLastActivePopup32( HWND32 hwnd )
2027 WND *wndPtr;
2028 wndPtr = WIN_FindWndPtr(hwnd);
2029 if (wndPtr == NULL) return hwnd;
2030 return wndPtr->hwndLastActive;
2034 /*******************************************************************
2035 * WIN_BuildWinArray
2037 * Build an array of pointers to the children of a given window.
2038 * The array must be freed with HeapFree(SystemHeap). Return NULL
2039 * when no windows are found.
2041 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
2043 WND **list, **ppWnd;
2044 WND *pWnd;
2045 UINT32 count, skipOwned, skipHidden;
2046 DWORD skipFlags;
2048 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2049 skipOwned = bwaFlags & BWA_SKIPOWNED;
2050 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2051 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
2053 /* First count the windows */
2055 if (!wndPtr) wndPtr = pWndDesktop;
2056 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
2058 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2059 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
2062 if( count )
2064 /* Now build the list of all windows */
2066 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
2068 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
2070 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2071 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2073 *ppWnd++ = pWnd;
2074 count++;
2077 *ppWnd = NULL;
2079 else count = 0;
2080 } else list = NULL;
2082 if( pTotal ) *pTotal = count;
2083 return list;
2087 /*******************************************************************
2088 * EnumWindows16 (USER.54)
2090 BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2092 WND **list, **ppWnd;
2094 /* We have to build a list of all windows first, to avoid */
2095 /* unpleasant side-effects, for instance if the callback */
2096 /* function changes the Z-order of the windows. */
2098 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2100 /* Now call the callback function for every window */
2102 for (ppWnd = list; *ppWnd; ppWnd++)
2104 /* Make sure that the window still exists */
2105 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2106 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2108 HeapFree( SystemHeap, 0, list );
2109 return TRUE;
2113 /*******************************************************************
2114 * EnumWindows32 (USER32.193)
2116 BOOL32 WINAPI EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2118 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2122 /**********************************************************************
2123 * EnumTaskWindows16 (USER.225)
2125 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2126 LPARAM lParam )
2128 WND **list, **ppWnd;
2129 HQUEUE16 hQueue = GetTaskQueue( hTask );
2131 /* This function is the same as EnumWindows(), */
2132 /* except for an added check on the window queue. */
2134 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2136 /* Now call the callback function for every window */
2138 for (ppWnd = list; *ppWnd; ppWnd++)
2140 /* Make sure that the window still exists */
2141 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2142 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
2143 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2145 HeapFree( SystemHeap, 0, list );
2146 return TRUE;
2150 /**********************************************************************
2151 * EnumThreadWindows (USER32.190)
2153 BOOL32 WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2155 THDB *tdb = THREAD_ID_TO_THDB(id);
2157 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2161 /**********************************************************************
2162 * WIN_EnumChildWindows
2164 * Helper function for EnumChildWindows().
2166 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2167 LPARAM lParam )
2169 WND **childList;
2170 BOOL16 ret = FALSE;
2172 for ( ; *ppWnd; ppWnd++)
2174 /* Make sure that the window still exists */
2175 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2176 /* Build children list first */
2177 if (!(childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL )))
2178 return FALSE;
2179 if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
2180 ret = WIN_EnumChildWindows( childList, func, lParam );
2181 HeapFree( SystemHeap, 0, childList );
2182 if (!ret) return FALSE;
2184 return TRUE;
2188 /**********************************************************************
2189 * EnumChildWindows16 (USER.55)
2191 BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2192 LPARAM lParam )
2194 WND **list, *pParent;
2196 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2197 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2198 WIN_EnumChildWindows( list, func, lParam );
2199 HeapFree( SystemHeap, 0, list );
2200 return TRUE;
2204 /**********************************************************************
2205 * EnumChildWindows32 (USER32.178)
2207 BOOL32 WINAPI EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
2208 LPARAM lParam )
2210 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2211 lParam );
2215 /*******************************************************************
2216 * AnyPopup16 (USER.52)
2218 BOOL16 WINAPI AnyPopup16(void)
2220 return AnyPopup32();
2224 /*******************************************************************
2225 * AnyPopup32 (USER32.4)
2227 BOOL32 WINAPI AnyPopup32(void)
2229 WND *wndPtr;
2230 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2231 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2232 return FALSE;
2236 /*******************************************************************
2237 * FlashWindow16 (USER.105)
2239 BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2241 return FlashWindow32( hWnd, bInvert );
2245 /*******************************************************************
2246 * FlashWindow32 (USER32.202)
2248 BOOL32 WINAPI FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2250 WND *wndPtr = WIN_FindWndPtr(hWnd);
2252 TRACE(win,"%04x\n", hWnd);
2254 if (!wndPtr) return FALSE;
2256 if (wndPtr->dwStyle & WS_MINIMIZE)
2258 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2260 HDC32 hDC = GetDC32(hWnd);
2262 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2263 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2265 ReleaseDC32( hWnd, hDC );
2266 wndPtr->flags |= WIN_NCACTIVATED;
2268 else
2270 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2271 RDW_UPDATENOW | RDW_FRAME, 0 );
2272 wndPtr->flags &= ~WIN_NCACTIVATED;
2274 return TRUE;
2276 else
2278 WPARAM16 wparam;
2279 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2280 else wparam = (hWnd == GetActiveWindow32());
2282 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2283 return wparam;
2288 /*******************************************************************
2289 * SetSysModalWindow16 (USER.188)
2291 HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
2293 HWND32 hWndOldModal = hwndSysModal;
2294 hwndSysModal = hWnd;
2295 FIXME(win, "EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2296 return hWndOldModal;
2300 /*******************************************************************
2301 * GetSysModalWindow16 (USER.52)
2303 HWND16 WINAPI GetSysModalWindow16(void)
2305 return hwndSysModal;
2309 /*******************************************************************
2310 * GetWindowContextHelpId (USER32.303)
2312 DWORD WINAPI GetWindowContextHelpId( HWND32 hwnd )
2314 WND *wnd = WIN_FindWndPtr( hwnd );
2315 if (!wnd) return 0;
2316 return wnd->helpContext;
2320 /*******************************************************************
2321 * SetWindowContextHelpId (USER32.515)
2323 BOOL32 WINAPI SetWindowContextHelpId( HWND32 hwnd, DWORD id )
2325 WND *wnd = WIN_FindWndPtr( hwnd );
2326 if (!wnd) return FALSE;
2327 wnd->helpContext = id;
2328 return TRUE;
2332 /*******************************************************************
2333 * DRAG_QueryUpdate
2335 * recursively find a child that contains spDragInfo->pt point
2336 * and send WM_QUERYDROPOBJECT
2338 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2340 BOOL16 wParam,bResult = 0;
2341 POINT32 pt;
2342 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2343 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2344 RECT32 tempRect;
2346 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2348 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2350 GetWindowRect32(hQueryWnd,&tempRect);
2352 if( !PtInRect32(&tempRect,pt) ||
2353 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2354 return 0;
2356 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2358 tempRect = ptrQueryWnd->rectClient;
2359 if(ptrQueryWnd->dwStyle & WS_CHILD)
2360 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2361 (LPPOINT32)&tempRect, 2 );
2363 if (PtInRect32( &tempRect, pt))
2365 wParam = 0;
2367 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2368 if( ptrWnd->dwStyle & WS_VISIBLE )
2370 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2371 if (PtInRect32( &tempRect, pt )) break;
2374 if(ptrWnd)
2376 TRACE(msg,"hwnd = %04x, %d %d - %d %d\n",
2377 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2378 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2379 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2380 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2383 if(bResult) return bResult;
2385 else wParam = 1;
2387 else wParam = 1;
2389 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2391 ptrDragInfo->hScope = hQueryWnd;
2393 bResult = ( bNoSend )
2394 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2395 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2396 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2397 if( !bResult )
2398 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2400 return bResult;
2404 /*******************************************************************
2405 * DragDetect (USER.465)
2407 BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
2409 POINT32 pt32;
2410 CONV_POINT16TO32( &pt, &pt32 );
2411 return DragDetect32( hWnd, pt32 );
2414 /*******************************************************************
2415 * DragDetect32 (USER32.151)
2417 BOOL32 WINAPI DragDetect32( HWND32 hWnd, POINT32 pt )
2419 MSG16 msg;
2420 RECT16 rect;
2422 rect.left = pt.x - wDragWidth;
2423 rect.right = pt.x + wDragWidth;
2425 rect.top = pt.y - wDragHeight;
2426 rect.bottom = pt.y + wDragHeight;
2428 SetCapture32(hWnd);
2430 while(1)
2432 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2434 if( msg.message == WM_LBUTTONUP )
2436 ReleaseCapture();
2437 return 0;
2439 if( msg.message == WM_MOUSEMOVE )
2441 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2443 ReleaseCapture();
2444 return 1;
2448 WaitMessage();
2450 return 0;
2453 /******************************************************************************
2454 * DragObject16 (USER.464)
2456 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2457 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2459 MSG16 msg;
2460 LPDRAGINFO lpDragInfo;
2461 SEGPTR spDragInfo;
2462 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2463 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2464 WND *wndPtr = WIN_FindWndPtr(hWnd);
2465 HCURSOR16 hCurrentCursor = 0;
2466 HWND16 hCurrentWnd = 0;
2468 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2469 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2471 if( !lpDragInfo || !spDragInfo ) return 0L;
2473 hBummer = LoadCursor16(0, IDC_BUMMER16);
2475 if( !hBummer || !wndPtr )
2477 GlobalFree16(hDragInfo);
2478 return 0L;
2481 if(hCursor)
2483 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2485 GlobalFree16(hDragInfo);
2486 return 0L;
2489 if( hDragCursor == hCursor ) hDragCursor = 0;
2490 else hCursor = hDragCursor;
2492 hOldCursor = SetCursor32(hDragCursor);
2495 lpDragInfo->hWnd = hWnd;
2496 lpDragInfo->hScope = 0;
2497 lpDragInfo->wFlags = wObj;
2498 lpDragInfo->hList = szList; /* near pointer! */
2499 lpDragInfo->hOfStruct = hOfStruct;
2500 lpDragInfo->l = 0L;
2502 SetCapture32(hWnd);
2503 ShowCursor32( TRUE );
2507 do{ WaitMessage(); }
2508 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2510 *(lpDragInfo+1) = *lpDragInfo;
2512 lpDragInfo->pt = msg.pt;
2514 /* update DRAGINFO struct */
2515 TRACE(msg,"lpDI->hScope = %04x\n",lpDragInfo->hScope);
2517 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2518 hCurrentCursor = hCursor;
2519 else
2521 hCurrentCursor = hBummer;
2522 lpDragInfo->hScope = 0;
2524 if( hCurrentCursor )
2525 SetCursor32(hCurrentCursor);
2527 /* send WM_DRAGLOOP */
2528 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2529 (LPARAM) spDragInfo );
2530 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2531 if( hCurrentWnd != lpDragInfo->hScope )
2533 if( hCurrentWnd )
2534 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2535 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2536 HIWORD(spDragInfo)) );
2537 hCurrentWnd = lpDragInfo->hScope;
2538 if( hCurrentWnd )
2539 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2541 else
2542 if( hCurrentWnd )
2543 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2545 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2547 ReleaseCapture();
2548 ShowCursor32( FALSE );
2550 if( hCursor )
2552 SetCursor32( hOldCursor );
2553 if (hDragCursor) DestroyCursor32( hDragCursor );
2556 if( hCurrentCursor != hBummer )
2557 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2558 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2559 else
2560 msg.lParam = 0;
2561 GlobalFree16(hDragInfo);
2563 return (DWORD)(msg.lParam);