Release 970525
[wine/multimedia.git] / windows / win.c
blobf093af15691c958b596ccdbde8427134d828ac42
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 MENU_PatchResidentPopup( HQUEUE16, WND* );
47 extern HCURSOR16 CURSORICON_IconToCursor(HICON16, BOOL32);
48 extern HWND32 CARET_GetHwnd(void);
49 extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
50 extern void WINPOS_CheckActive(HWND32);
51 extern BOOL32 EVENT_CheckFocus(void);
53 /***********************************************************************
54 * WIN_FindWndPtr
56 * Return a pointer to the WND structure corresponding to a HWND.
58 WND * WIN_FindWndPtr( HWND32 hwnd )
60 WND * ptr;
62 if (!hwnd || HIWORD(hwnd)) return NULL;
63 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
64 if (ptr->dwMagic != WND_MAGIC) return NULL;
65 if (ptr->hwndSelf != hwnd)
67 fprintf( stderr, "Can't happen: hwnd %04x self pointer is %04x\n",
68 hwnd, ptr->hwndSelf );
69 return NULL;
71 return ptr;
75 /***********************************************************************
76 * WIN_DumpWindow
78 * Dump the content of a window structure to stderr.
80 void WIN_DumpWindow( HWND32 hwnd )
82 WND *ptr;
83 char className[80];
84 int i;
86 if (!(ptr = WIN_FindWndPtr( hwnd )))
88 fprintf( stderr, "%04x is not a window handle\n", hwnd );
89 return;
92 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
93 strcpy( className, "#NULL#" );
95 fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
96 fprintf( stderr,
97 "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
98 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%04x\n"
99 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
100 "client=%d,%d-%d,%d window=%d,%d-%d,%d iconpos=%d,%d maxpos=%d,%d\n"
101 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
102 ptr->next, ptr->child, ptr->parent, ptr->owner,
103 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
104 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
105 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
106 ptr->text ? ptr->text : "",
107 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
108 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
109 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x,
110 ptr->ptIconPos.y, ptr->ptMaxPos.x, ptr->ptMaxPos.y, ptr->hSysMenu,
111 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
113 if (ptr->class->cbWndExtra)
115 fprintf( stderr, "extra bytes:" );
116 for (i = 0; i < ptr->class->cbWndExtra; i++)
117 fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
118 fprintf( stderr, "\n" );
120 fprintf( stderr, "\n" );
124 /***********************************************************************
125 * WIN_WalkWindows
127 * Walk the windows tree and print each window on stderr.
129 void WIN_WalkWindows( HWND32 hwnd, int indent )
131 WND *ptr;
132 char className[80];
134 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
135 if (!ptr)
137 fprintf( stderr, "*** Invalid window handle %04x\n", hwnd );
138 return;
141 if (!indent) /* first time around */
142 fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
143 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
145 while (ptr)
147 fprintf(stderr, "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
149 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
151 fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %08x\n",
152 (DWORD)ptr, ptr->hmemTaskQ, className,
153 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc );
155 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
156 ptr = ptr->next;
161 /***********************************************************************
162 * WIN_GetXWindow
164 * Return the X window associated to a window.
166 Window WIN_GetXWindow( HWND32 hwnd )
168 WND *wndPtr = WIN_FindWndPtr( hwnd );
169 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
170 return wndPtr ? wndPtr->window : 0;
174 /***********************************************************************
175 * WIN_UnlinkWindow
177 * Remove a window from the siblings linked list.
179 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
181 WND *wndPtr, **ppWnd;
183 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
184 ppWnd = &wndPtr->parent->child;
185 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
186 *ppWnd = wndPtr->next;
187 return TRUE;
191 /***********************************************************************
192 * WIN_LinkWindow
194 * Insert a window into the siblings linked list.
195 * The window is inserted after the specified window, which can also
196 * be specified as HWND_TOP or HWND_BOTTOM.
198 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
200 WND *wndPtr, **ppWnd;
202 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
204 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
206 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
207 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
208 while (*ppWnd) ppWnd = &(*ppWnd)->next;
210 else /* Normal case */
212 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
213 if (!afterPtr) return FALSE;
214 ppWnd = &afterPtr->next;
216 wndPtr->next = *ppWnd;
217 *ppWnd = wndPtr;
218 return TRUE;
222 /***********************************************************************
223 * WIN_FindWinToRepaint
225 * Find a window that needs repaint.
227 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
229 HWND32 hwndRet;
230 WND *pWnd = pWndDesktop;
232 /* Note: the desktop window never gets WM_PAINT messages
233 * The real reason why is because Windows DesktopWndProc
234 * does ValidateRgn inside WM_ERASEBKGND handler.
237 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
239 for ( ; pWnd ; pWnd = pWnd->next )
241 if (!(pWnd->dwStyle & WS_VISIBLE) || (pWnd->flags & WIN_NO_REDRAW))
243 dprintf_win( stddeb, "FindWinToRepaint: skipping window %04x\n",
244 pWnd->hwndSelf );
245 continue;
247 if ((pWnd->hmemTaskQ == hQueue) &&
248 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
250 if (pWnd->child )
251 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
252 return hwndRet;
255 if (!pWnd) return 0;
257 hwndRet = pWnd->hwndSelf;
259 /* look among siblings if we got a transparent window */
260 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
261 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
263 pWnd = pWnd->next;
265 if (pWnd) hwndRet = pWnd->hwndSelf;
266 dprintf_win(stddeb,"FindWinToRepaint: found %04x\n",hwndRet);
267 return hwndRet;
271 /***********************************************************************
272 * WIN_SendParentNotify
274 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
275 * the window has the WS_EX_NOPARENTNOTIFY style.
277 void WIN_SendParentNotify(HWND32 hwnd, WORD event, WORD idChild, LPARAM lValue)
279 LPPOINT16 lppt = (LPPOINT16)&lValue;
280 WND *wndPtr = WIN_FindWndPtr( hwnd );
281 BOOL32 bMouse = ((event <= WM_MOUSELAST) && (event >= WM_MOUSEFIRST));
283 /* if lValue contains cursor coordinates they have to be
284 * mapped to the client area of parent window */
286 if (bMouse) MapWindowPoints16( 0, hwnd, lppt, 1 );
288 while (wndPtr)
290 if ((wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) ||
291 !(wndPtr->dwStyle & WS_CHILD)) break;
293 if (bMouse)
295 lppt->x += wndPtr->rectClient.left;
296 lppt->y += wndPtr->rectClient.top;
299 wndPtr = wndPtr->parent;
300 SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY,
301 MAKEWPARAM( event, idChild ), lValue );
306 /***********************************************************************
307 * WIN_DestroyWindow
309 * Destroy storage associated to a window. "Internals" p.358
311 static WND* WIN_DestroyWindow( WND* wndPtr )
313 HWND32 hwnd = wndPtr->hwndSelf;
314 WND *pWnd;
316 dprintf_win( stddeb, "WIN_DestroyWindow: %04x\n", wndPtr->hwndSelf );
318 #ifdef CONFIG_IPC
319 if (main_block)
320 DDE_DestroyWindow(wndPtr->hwndSelf);
321 #endif /* CONFIG_IPC */
323 /* free child windows */
325 while ((pWnd = wndPtr->child))
326 wndPtr->child = WIN_DestroyWindow( pWnd );
328 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
330 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
332 WINPOS_CheckActive( hwnd );
333 if( hwnd == GetCapture32()) ReleaseCapture();
335 /* free resources associated with the window */
337 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
338 PROPERTY_RemoveWindowProps( wndPtr );
340 wndPtr->dwMagic = 0; /* Mark it as invalid */
341 wndPtr->hwndSelf = 0;
343 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
345 if (wndPtr->hrgnUpdate) DeleteObject32( wndPtr->hrgnUpdate );
346 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
349 /* toss stale messages from the queue */
351 if( wndPtr->hmemTaskQ )
353 int pos;
354 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
356 while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
357 QUEUE_RemoveMsg(msgQ, pos);
358 wndPtr->hmemTaskQ = 0;
361 if (!(wndPtr->dwStyle & WS_CHILD))
362 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
363 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
364 if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
365 if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->dce );
367 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
369 wndPtr->class->cWindows--;
370 wndPtr->class = NULL;
371 pWnd = wndPtr->next;
373 USER_HEAP_FREE( hwnd );
374 return pWnd;
377 /***********************************************************************
378 * WIN_ResetQueueWindows
380 void WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
382 WND* next;
384 while (wnd)
386 next = wnd->next;
387 if (wnd->hmemTaskQ == hQueue)
388 if( hNew ) wnd->hmemTaskQ = hNew;
389 else DestroyWindow32( wnd->hwndSelf );
390 else WIN_ResetQueueWindows( wnd->child, hQueue, hNew );
391 wnd = next;
395 /***********************************************************************
396 * WIN_CreateDesktopWindow
398 * Create the desktop window.
400 BOOL32 WIN_CreateDesktopWindow(void)
402 CLASS *class;
403 HWND32 hwndDesktop;
405 dprintf_win(stddeb,"Creating desktop window\n");
407 if (!(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
408 return FALSE;
410 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
411 if (!hwndDesktop) return FALSE;
412 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
414 pWndDesktop->next = NULL;
415 pWndDesktop->child = NULL;
416 pWndDesktop->parent = NULL;
417 pWndDesktop->owner = NULL;
418 pWndDesktop->class = class;
419 pWndDesktop->dwMagic = WND_MAGIC;
420 pWndDesktop->hwndSelf = hwndDesktop;
421 pWndDesktop->hInstance = 0;
422 pWndDesktop->rectWindow.left = 0;
423 pWndDesktop->rectWindow.top = 0;
424 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
425 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
426 pWndDesktop->rectClient = pWndDesktop->rectWindow;
427 pWndDesktop->rectNormal = pWndDesktop->rectWindow;
428 pWndDesktop->ptIconPos.x = -1;
429 pWndDesktop->ptIconPos.y = -1;
430 pWndDesktop->ptMaxPos.x = -1;
431 pWndDesktop->ptMaxPos.y = -1;
432 pWndDesktop->text = NULL;
433 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
434 pWndDesktop->hrgnUpdate = 0;
435 pWndDesktop->hwndLastActive = hwndDesktop;
436 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
437 WS_CLIPSIBLINGS;
438 pWndDesktop->dwExStyle = 0;
439 pWndDesktop->dce = NULL;
440 pWndDesktop->pVScroll = NULL;
441 pWndDesktop->pHScroll = NULL;
442 pWndDesktop->pProp = NULL;
443 pWndDesktop->wIDmenu = 0;
444 pWndDesktop->flags = 0;
445 pWndDesktop->window = rootWindow;
446 pWndDesktop->hSysMenu = 0;
447 pWndDesktop->userdata = 0;
449 pWndDesktop->winproc = (WNDPROC16)class->winproc;
451 EVENT_RegisterWindow( pWndDesktop );
452 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
453 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
454 return TRUE;
458 /***********************************************************************
459 * WIN_CreateWindowEx
461 * Implementation of CreateWindowEx().
463 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
464 BOOL32 win32, BOOL32 unicode )
466 CLASS *classPtr;
467 WND *wndPtr;
468 HWND16 hwnd, hwndLinkAfter;
469 POINT16 maxSize, maxPos, minTrack, maxTrack;
470 LRESULT (*localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
472 dprintf_win( stddeb, "CreateWindowEx: " );
473 if (HIWORD(cs->lpszName)) dprintf_win( stddeb, "'%s' ", cs->lpszName );
474 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszName) );
475 if (HIWORD(cs->lpszClass)) dprintf_win( stddeb, "'%s' ", cs->lpszClass );
476 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszClass) );
478 dprintf_win( stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %p\n",
479 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
480 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
482 /* Find the parent window */
484 if (cs->hwndParent)
486 /* Make sure parent is valid */
487 if (!IsWindow32( cs->hwndParent ))
489 fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
490 return 0;
493 else if (cs->style & WS_CHILD)
495 fprintf( stderr, "CreateWindowEx: no parent for child window\n" );
496 return 0; /* WS_CHILD needs a parent */
499 /* Find the window class */
501 if (!(classPtr = CLASS_FindClassByAtom( classAtom,
502 GetExePtr(cs->hInstance) )))
504 char buffer[256];
505 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
506 fprintf( stderr, "CreateWindowEx: bad class '%s'\n", buffer );
507 return 0;
510 /* Fix the coordinates */
512 if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0;
513 if (cs->cx == CW_USEDEFAULT32)
515 /* if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0;
516 else */
518 cs->cx = 600;
519 cs->cy = 400;
523 /* Create the window structure */
525 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
526 - sizeof(wndPtr->wExtra) )))
528 dprintf_win( stddeb, "CreateWindowEx: out of memory\n" );
529 return 0;
532 /* Fill the window structure */
534 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
535 wndPtr->next = NULL;
536 wndPtr->child = NULL;
538 if (cs->style & WS_CHILD)
540 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
541 wndPtr->owner = NULL;
543 else
545 wndPtr->parent = pWndDesktop;
546 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
547 wndPtr->owner = NULL;
548 else
549 wndPtr->owner = WIN_FindWndPtr(WIN_GetTopParent(cs->hwndParent));
552 wndPtr->window = 0;
553 wndPtr->class = classPtr;
554 wndPtr->winproc = classPtr->winproc;
555 wndPtr->dwMagic = WND_MAGIC;
556 wndPtr->hwndSelf = hwnd;
557 wndPtr->hInstance = cs->hInstance;
558 wndPtr->ptIconPos.x = -1;
559 wndPtr->ptIconPos.y = -1;
560 wndPtr->ptMaxPos.x = -1;
561 wndPtr->ptMaxPos.y = -1;
562 wndPtr->text = NULL;
563 wndPtr->hmemTaskQ = GetTaskQueue(0);
564 wndPtr->hrgnUpdate = 0;
565 wndPtr->hwndLastActive = hwnd;
566 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
567 wndPtr->dwExStyle = cs->dwExStyle;
568 wndPtr->wIDmenu = 0;
569 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
570 wndPtr->pVScroll = NULL;
571 wndPtr->pHScroll = NULL;
572 wndPtr->pProp = NULL;
573 wndPtr->userdata = 0;
574 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
575 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
577 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
579 /* Call the WH_CBT hook */
581 hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
583 if (HOOK_IsHooked( WH_CBT ))
585 CBT_CREATEWND32A cbtc;
587 cbtc.lpcs = cs;
588 cbtc.hwndInsertAfter = hwndLinkAfter;
589 if ( HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc) )
591 dprintf_win(stddeb, "CreateWindowEx: CBT-hook returned 0\n");
592 USER_HEAP_FREE( hwnd );
593 return 0;
597 /* Increment class window counter */
599 classPtr->cWindows++;
601 /* Correct the window style */
603 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
605 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
606 wndPtr->flags |= WIN_NEED_SIZE;
608 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
610 /* Get class or window DC if needed */
612 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
613 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
614 else wndPtr->dce = NULL;
616 /* Insert the window in the linked list */
618 WIN_LinkWindow( hwnd, hwndLinkAfter );
620 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
622 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
624 NC_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack );
625 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
626 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
627 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
628 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
630 if (cs->cx <= 0) cs->cx = 1;
631 if (cs->cy <= 0) cs->cy = 1;
633 wndPtr->rectWindow.left = cs->x;
634 wndPtr->rectWindow.top = cs->y;
635 wndPtr->rectWindow.right = cs->x + cs->cx;
636 wndPtr->rectWindow.bottom = cs->y + cs->cy;
637 wndPtr->rectClient = wndPtr->rectWindow;
638 wndPtr->rectNormal = wndPtr->rectWindow;
640 /* Create the X window (only for top-level windows, and then only */
641 /* when there's no desktop window) */
643 if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
645 XSetWindowAttributes win_attr;
647 if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
648 (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
650 win_attr.event_mask = ExposureMask | KeyPressMask |
651 KeyReleaseMask | PointerMotionMask |
652 ButtonPressMask | ButtonReleaseMask |
653 FocusChangeMask | StructureNotifyMask;
654 win_attr.override_redirect = FALSE;
655 wndPtr->flags |= WIN_MANAGED;
657 else
659 win_attr.event_mask = ExposureMask | KeyPressMask |
660 KeyReleaseMask | PointerMotionMask |
661 ButtonPressMask | ButtonReleaseMask |
662 FocusChangeMask | StructureNotifyMask;
663 win_attr.override_redirect = TRUE;
665 win_attr.colormap = COLOR_GetColormap();
666 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
667 win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
668 win_attr.cursor = CURSORICON_XCursor;
669 wndPtr->window = XCreateWindow( display, rootWindow, cs->x, cs->y,
670 cs->cx, cs->cy, 0, CopyFromParent,
671 InputOutput, CopyFromParent,
672 CWEventMask | CWOverrideRedirect |
673 CWColormap | CWCursor | CWSaveUnder |
674 CWBackingStore, &win_attr );
676 if ((wndPtr->flags & WIN_MANAGED) &&
677 (cs->dwExStyle & WS_EX_DLGMODALFRAME))
679 XSizeHints* size_hints = XAllocSizeHints();
681 if (size_hints)
683 size_hints->min_width = size_hints->max_width = cs->cx;
684 size_hints->min_height = size_hints->max_height = cs->cy;
685 size_hints->flags = (PSize | PMinSize | PMaxSize);
686 XSetWMSizeHints( display, wndPtr->window, size_hints,
687 XA_WM_NORMAL_HINTS );
688 XFree(size_hints);
692 if (cs->hwndParent) /* Get window owner */
694 Window win = WIN_GetXWindow( cs->hwndParent );
695 if (win) XSetTransientForHint( display, wndPtr->window, win );
697 EVENT_RegisterWindow( wndPtr );
700 /* Set the window menu */
702 if ((cs->style & WS_CAPTION) && !(cs->style & WS_CHILD))
704 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
705 else
707 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
708 if (classPtr->menuNameA)
709 cs->hMenu = HIWORD(classPtr->menuNameA) ?
710 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
711 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
712 #else
713 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
714 if (menuName) cs->hMenu = LoadMenu16( cs->hInstance, menuName );
715 #endif
717 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
719 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
721 /* Send the WM_CREATE message
722 * Perhaps we shouldn't allow width/height changes as well.
723 * See p327 in "Internals".
726 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
728 localSend32 = unicode ? SendMessage32W : SendMessage32A;
729 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
731 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
732 NULL, NULL, 0, &wndPtr->rectClient );
733 OffsetRect16(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
734 maxPos.y - wndPtr->rectWindow.top);
735 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
737 /* Send the size messages */
739 if (!(wndPtr->flags & WIN_NEED_SIZE))
741 /* send it anyway */
742 SendMessage16( hwnd, WM_SIZE, SIZE_RESTORED,
743 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
744 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
745 SendMessage16( hwnd, WM_MOVE, 0, MAKELONG( wndPtr->rectClient.left,
746 wndPtr->rectClient.top ));
749 WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LPARAM)hwnd );
750 if (!IsWindow32(hwnd)) return 0;
752 /* Show the window, maximizing or minimizing if needed */
754 if (wndPtr->dwStyle & WS_MINIMIZE)
756 /* MinMaximize(hwnd, SW_SHOWMINNOACTIVE, 1) in "Internals" */
758 wndPtr->dwStyle &= ~WS_MAXIMIZE;
759 WINPOS_FindIconPos( hwnd );
760 SetWindowPos32( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
761 SYSMETRICS_CXICON, SYSMETRICS_CYICON,
762 SWP_FRAMECHANGED | ((GetActiveWindow32())? SWP_NOACTIVATE : 0) );
764 else if (wndPtr->dwStyle & WS_MAXIMIZE)
766 /* MinMaximize(hwnd, SW_SHOWMAXIMIZED, 1) */
768 NC_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack );
769 SetWindowPos32( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
770 ((GetActiveWindow32())? SWP_NOACTIVATE : 0) | SWP_FRAMECHANGED );
773 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
775 /* Call WH_SHELL hook */
777 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
778 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
780 dprintf_win(stddeb, "CreateWindowEx: created window %04x\n", hwnd);
781 return hwnd;
785 /* Abort window creation */
787 dprintf_win(stddeb,"CreateWindowEx: aborted by WM_xxCREATE!\n");
788 WIN_UnlinkWindow( hwnd );
789 WIN_DestroyWindow( wndPtr );
790 return 0;
794 /***********************************************************************
795 * CreateWindow16 (USER.41)
797 HWND16 CreateWindow16( LPCSTR className, LPCSTR windowName,
798 DWORD style, INT16 x, INT16 y, INT16 width,
799 INT16 height, HWND16 parent, HMENU16 menu,
800 HINSTANCE16 instance, LPVOID data )
802 return CreateWindowEx16( 0, className, windowName, style,
803 x, y, width, height, parent, menu, instance, data );
807 /***********************************************************************
808 * CreateWindowEx16 (USER.452)
810 HWND16 CreateWindowEx16( DWORD exStyle, LPCSTR className, LPCSTR windowName,
811 DWORD style, INT16 x, INT16 y, INT16 width,
812 INT16 height, HWND16 parent, HMENU16 menu,
813 HINSTANCE16 instance, LPVOID data )
815 ATOM classAtom;
816 CREATESTRUCT32A cs;
818 /* Find the class atom */
820 if (!(classAtom = GlobalFindAtom32A( className )))
822 fprintf( stderr, "CreateWindowEx16: bad class name " );
823 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
824 else fprintf( stderr, "'%s'\n", className );
825 return 0;
828 /* Fix the coordinates */
830 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
831 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
832 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
833 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
835 /* Create the window */
837 cs.lpCreateParams = data;
838 cs.hInstance = (HINSTANCE32)instance;
839 cs.hMenu = (HMENU32)menu;
840 cs.hwndParent = (HWND32)parent;
841 cs.style = style;
842 cs.lpszName = windowName;
843 cs.lpszClass = className;
844 cs.dwExStyle = exStyle;
845 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
849 /***********************************************************************
850 * CreateWindowEx32A (USER32.82)
852 HWND32 CreateWindowEx32A( DWORD exStyle, LPCSTR className, LPCSTR windowName,
853 DWORD style, INT32 x, INT32 y, INT32 width,
854 INT32 height, HWND32 parent, HMENU32 menu,
855 HINSTANCE32 instance, LPVOID data )
857 ATOM classAtom;
858 CREATESTRUCT32A cs;
860 /* Find the class atom */
862 if (!(classAtom = GlobalFindAtom32A( className )))
864 fprintf( stderr, "CreateWindowEx32A: bad class name " );
865 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
866 else fprintf( stderr, "'%s'\n", className );
867 return 0;
870 /* Create the window */
872 cs.lpCreateParams = data;
873 cs.hInstance = instance;
874 cs.hMenu = menu;
875 cs.hwndParent = parent;
876 cs.x = x;
877 cs.y = y;
878 cs.cx = width;
879 cs.cy = height;
880 cs.style = style;
881 cs.lpszName = windowName;
882 cs.lpszClass = className;
883 cs.dwExStyle = exStyle;
884 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
888 /***********************************************************************
889 * CreateWindowEx32W (USER32.83)
891 HWND32 CreateWindowEx32W( DWORD exStyle, LPCWSTR className, LPCWSTR windowName,
892 DWORD style, INT32 x, INT32 y, INT32 width,
893 INT32 height, HWND32 parent, HMENU32 menu,
894 HINSTANCE32 instance, LPVOID data )
896 ATOM classAtom;
897 CREATESTRUCT32W cs;
899 /* Find the class atom */
901 if (!(classAtom = GlobalFindAtom32W( className )))
903 if (HIWORD(className))
905 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
906 fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
907 HeapFree( GetProcessHeap(), 0, cn );
909 else
910 fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
911 return 0;
914 /* Create the window */
916 cs.lpCreateParams = data;
917 cs.hInstance = instance;
918 cs.hMenu = menu;
919 cs.hwndParent = parent;
920 cs.x = x;
921 cs.y = y;
922 cs.cx = width;
923 cs.cy = height;
924 cs.style = style;
925 cs.lpszName = windowName;
926 cs.lpszClass = className;
927 cs.dwExStyle = exStyle;
928 /* Note: we rely on the fact that CREATESTRUCT32A and */
929 /* CREATESTRUCT32W have the same layout. */
930 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
934 /***********************************************************************
935 * WIN_CheckFocus
937 static void WIN_CheckFocus( WND* pWnd )
939 if( GetFocus16() == pWnd->hwndSelf )
940 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
943 /***********************************************************************
944 * WIN_SendDestroyMsg
946 static void WIN_SendDestroyMsg( WND* pWnd )
948 WND* pChild;
950 WIN_CheckFocus(pWnd);
952 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
953 if( !pWnd->window ) CLIPBOARD_DisOwn( pWnd );
955 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
957 if( !IsWindow32(pWnd->hwndSelf) )
959 dprintf_win(stddeb,"\tdestroyed itself while in WM_DESTROY!\n");
960 return;
963 pChild = pWnd->child;
964 while( pChild )
966 WIN_SendDestroyMsg( pChild );
967 pChild = pChild->next;
969 WIN_CheckFocus(pWnd);
973 /***********************************************************************
974 * DestroyWindow (USER.53)
976 BOOL16 DestroyWindow16( HWND16 hwnd )
978 return DestroyWindow32(hwnd);
980 /***********************************************************************
981 * DestroyWindow (USER32.134)
983 BOOL32 DestroyWindow32( HWND32 hwnd )
985 WND * wndPtr;
987 dprintf_win(stddeb, "DestroyWindow(%04x)\n", hwnd);
989 /* Initialization */
991 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
992 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
994 /* Call hooks */
996 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
997 return FALSE;
999 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1001 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
1002 /* FIXME: clean up palette - see "Internals" p.352 */
1005 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
1006 WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
1007 if (!IsWindow32(hwnd)) return TRUE;
1009 if( wndPtr->window ) CLIPBOARD_DisOwn( wndPtr ); /* before window is unmapped */
1011 /* Hide the window */
1013 if (wndPtr->dwStyle & WS_VISIBLE)
1015 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
1016 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
1017 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
1018 if (!IsWindow32(hwnd)) return TRUE;
1021 /* Recursively destroy owned windows */
1023 if( !(wndPtr->dwStyle & WS_CHILD) )
1025 /* make sure top menu popup doesn't get destroyed */
1026 MENU_PatchResidentPopup( TRUE, wndPtr );
1028 for (;;)
1030 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1031 while (siblingPtr)
1033 if (siblingPtr->owner == wndPtr)
1034 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1035 break;
1036 else
1037 siblingPtr->owner = NULL;
1038 siblingPtr = siblingPtr->next;
1040 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1041 else break;
1044 if( !Options.managed || EVENT_CheckFocus() )
1045 WINPOS_ActivateOtherWindow(wndPtr);
1047 if( wndPtr->owner &&
1048 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1049 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1052 /* Send destroy messages */
1054 WIN_SendDestroyMsg( wndPtr );
1055 if (!IsWindow32(hwnd)) return TRUE;
1057 /* Unlink now so we won't bother with the children later on */
1059 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1061 /* Destroy the window storage */
1063 WIN_DestroyWindow( wndPtr );
1064 return TRUE;
1068 /***********************************************************************
1069 * CloseWindow16 (USER.43)
1071 BOOL16 CloseWindow16( HWND16 hwnd )
1073 return CloseWindow32( hwnd );
1077 /***********************************************************************
1078 * CloseWindow32 (USER32.55)
1080 BOOL32 CloseWindow32( HWND32 hwnd )
1082 WND * wndPtr = WIN_FindWndPtr( hwnd );
1083 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1084 ShowWindow32( hwnd, SW_MINIMIZE );
1085 return TRUE;
1089 /***********************************************************************
1090 * OpenIcon16 (USER.44)
1092 BOOL16 OpenIcon16( HWND16 hwnd )
1094 return OpenIcon32( hwnd );
1098 /***********************************************************************
1099 * OpenIcon32 (USER32.409)
1101 BOOL32 OpenIcon32( HWND32 hwnd )
1103 if (!IsIconic32( hwnd )) return FALSE;
1104 ShowWindow32( hwnd, SW_SHOWNORMAL );
1105 return TRUE;
1109 /***********************************************************************
1110 * WIN_FindWindow
1112 * Implementation of FindWindow() and FindWindowEx().
1114 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1115 LPCSTR title )
1117 WND *pWnd;
1118 CLASS *pClass = NULL;
1120 if (child)
1122 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1123 if (parent)
1125 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1127 else if (pWnd->parent != pWndDesktop) return 0;
1128 pWnd = pWnd->next;
1130 else
1132 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1133 pWnd = pWnd->child;
1135 if (!pWnd) return 0;
1137 /* For a child window, all siblings will have the same hInstance, */
1138 /* so we can look for the class once and for all. */
1140 if (className && (pWnd->dwStyle & WS_CHILD))
1142 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1143 return 0;
1146 for ( ; pWnd; pWnd = pWnd->next)
1148 if (className && !(pWnd->dwStyle & WS_CHILD))
1150 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance)))
1151 continue; /* Skip this window */
1153 if (pClass && (pWnd->class != pClass))
1154 continue; /* Not the right class */
1156 /* Now check the title */
1158 if (!title) return pWnd->hwndSelf;
1159 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1161 return 0;
1166 /***********************************************************************
1167 * FindWindow16 (USER.50)
1169 HWND16 FindWindow16( SEGPTR className, LPCSTR title )
1171 return FindWindowEx16( 0, 0, className, title );
1175 /***********************************************************************
1176 * FindWindowEx16 (USER.427)
1178 HWND16 FindWindowEx16( HWND16 parent, HWND16 child,
1179 SEGPTR className, LPCSTR title )
1181 ATOM atom = 0;
1183 if (className)
1185 /* If the atom doesn't exist, then no class */
1186 /* with this name exists either. */
1187 if (!(atom = GlobalFindAtom16( className ))) return 0;
1189 return WIN_FindWindow( parent, child, atom, title );
1193 /***********************************************************************
1194 * FindWindow32A (USER32.197)
1196 HWND32 FindWindow32A( LPCSTR className, LPCSTR title )
1198 return FindWindowEx32A( 0, 0, className, title );
1202 /***********************************************************************
1203 * FindWindowEx32A (USER32.198)
1205 HWND32 FindWindowEx32A( HWND32 parent, HWND32 child,
1206 LPCSTR className, LPCSTR title )
1208 ATOM atom = 0;
1210 if (className)
1212 /* If the atom doesn't exist, then no class */
1213 /* with this name exists either. */
1214 if (!(atom = GlobalFindAtom32A( className ))) return 0;
1216 return WIN_FindWindow( 0, 0, atom, title );
1220 /***********************************************************************
1221 * FindWindowEx32W (USER32.199)
1223 HWND32 FindWindowEx32W( HWND32 parent, HWND32 child,
1224 LPCWSTR className, LPCWSTR title )
1226 ATOM atom = 0;
1227 char *buffer;
1228 HWND32 hwnd;
1230 if (className)
1232 /* If the atom doesn't exist, then no class */
1233 /* with this name exists either. */
1234 if (!(atom = GlobalFindAtom32W( className ))) return 0;
1236 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1237 hwnd = WIN_FindWindow( 0, 0, atom, buffer );
1238 HeapFree( GetProcessHeap(), 0, buffer );
1239 return hwnd;
1243 /***********************************************************************
1244 * FindWindow32W (USER32.200)
1246 HWND32 FindWindow32W( LPCWSTR className, LPCWSTR title )
1248 return FindWindowEx32W( 0, 0, className, title );
1252 /**********************************************************************
1253 * WIN_GetDesktop
1255 WND *WIN_GetDesktop(void)
1257 return pWndDesktop;
1261 /**********************************************************************
1262 * GetDesktopWindow16 (USER.286)
1264 HWND16 GetDesktopWindow16(void)
1266 return (HWND16)pWndDesktop->hwndSelf;
1270 /**********************************************************************
1271 * GetDesktopWindow32 (USER32.231)
1273 HWND32 GetDesktopWindow32(void)
1275 return pWndDesktop->hwndSelf;
1279 /**********************************************************************
1280 * GetDesktopHwnd (USER.278)
1282 * Exactly the same thing as GetDesktopWindow(), but not documented.
1283 * Don't ask me why...
1285 HWND16 GetDesktopHwnd(void)
1287 return (HWND16)pWndDesktop->hwndSelf;
1291 /*******************************************************************
1292 * EnableWindow16 (USER.34)
1294 BOOL16 EnableWindow16( HWND16 hwnd, BOOL16 enable )
1296 return EnableWindow32( hwnd, enable );
1300 /*******************************************************************
1301 * EnableWindow32 (USER32.171)
1303 BOOL32 EnableWindow32( HWND32 hwnd, BOOL32 enable )
1305 WND *wndPtr;
1307 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1308 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1310 /* Enable window */
1311 wndPtr->dwStyle &= ~WS_DISABLED;
1312 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1313 return TRUE;
1315 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1317 /* Disable window */
1318 wndPtr->dwStyle |= WS_DISABLED;
1319 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1320 SetFocus32( 0 ); /* A disabled window can't have the focus */
1321 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1322 ReleaseCapture(); /* A disabled window can't capture the mouse */
1323 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1324 return FALSE;
1326 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1330 /***********************************************************************
1331 * IsWindowEnabled16 (USER.35)
1333 BOOL16 IsWindowEnabled16(HWND16 hWnd)
1335 return IsWindowEnabled32(hWnd);
1339 /***********************************************************************
1340 * IsWindowEnabled32 (USER32.348)
1342 BOOL32 IsWindowEnabled32(HWND32 hWnd)
1344 WND * wndPtr;
1346 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1347 return !(wndPtr->dwStyle & WS_DISABLED);
1351 /***********************************************************************
1352 * IsWindowUnicode (USER32.349)
1354 BOOL32 IsWindowUnicode( HWND32 hwnd )
1356 WND * wndPtr;
1358 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1359 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1363 /**********************************************************************
1364 * GetWindowWord16 (USER.133)
1366 WORD GetWindowWord16( HWND16 hwnd, INT16 offset )
1368 return GetWindowWord32( hwnd, offset );
1372 /**********************************************************************
1373 * GetWindowWord32 (USER32.313)
1375 WORD GetWindowWord32( HWND32 hwnd, INT32 offset )
1377 WND * wndPtr = WIN_FindWndPtr( hwnd );
1378 if (!wndPtr) return 0;
1379 if (offset >= 0)
1381 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1383 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1384 return 0;
1386 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1388 switch(offset)
1390 case GWW_ID: return wndPtr->wIDmenu;
1391 case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
1392 case GWW_HINSTANCE: return (WORD)wndPtr->hInstance;
1393 default:
1394 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1395 return 0;
1400 /**********************************************************************
1401 * WIN_GetWindowInstance
1403 HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd )
1405 WND * wndPtr = WIN_FindWndPtr( hwnd );
1406 if (!wndPtr) return (HINSTANCE16)0;
1407 return wndPtr->hInstance;
1411 /**********************************************************************
1412 * SetWindowWord16 (USER.134)
1414 WORD SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1416 return SetWindowWord32( hwnd, offset, newval );
1420 /**********************************************************************
1421 * SetWindowWord32 (USER32.523)
1423 WORD SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1425 WORD *ptr, retval;
1426 WND * wndPtr = WIN_FindWndPtr( hwnd );
1427 if (!wndPtr) return 0;
1428 if (offset >= 0)
1430 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1432 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1433 return 0;
1435 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1437 else switch(offset)
1439 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1440 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1441 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1442 default:
1443 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1444 return 0;
1446 retval = *ptr;
1447 *ptr = newval;
1448 return retval;
1452 /**********************************************************************
1453 * WIN_GetWindowLong
1455 * Helper function for GetWindowLong().
1457 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1459 LONG retval;
1460 WND * wndPtr = WIN_FindWndPtr( hwnd );
1461 if (!wndPtr) return 0;
1462 if (offset >= 0)
1464 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1466 fprintf( stderr, "GetWindowLong: invalid offset %d\n", offset );
1467 return 0;
1469 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1470 /* Special case for dialog window procedure */
1471 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1472 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1473 return retval;
1475 switch(offset)
1477 case GWL_USERDATA: return wndPtr->userdata;
1478 case GWL_STYLE: return wndPtr->dwStyle;
1479 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1480 case GWL_ID: return wndPtr->wIDmenu;
1481 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1482 type );
1483 case GWL_HWNDPARENT: return wndPtr->parent ?
1484 (HWND32)wndPtr->parent->hwndSelf : 0;
1485 case GWL_HINSTANCE: return (HINSTANCE32)wndPtr->hInstance;
1486 default:
1487 fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
1489 return 0;
1493 /**********************************************************************
1494 * WIN_SetWindowLong
1496 * Helper function for SetWindowLong().
1498 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1499 WINDOWPROCTYPE type )
1501 LONG *ptr, retval;
1502 WND * wndPtr = WIN_FindWndPtr( hwnd );
1503 if (!wndPtr) return 0;
1504 if (offset >= 0)
1506 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1508 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1509 return 0;
1511 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1512 /* Special case for dialog window procedure */
1513 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1515 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1516 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1517 type, WIN_PROC_WINDOW );
1518 return retval;
1521 else switch(offset)
1523 case GWL_ID:
1524 case GWL_HINSTANCE:
1525 return SetWindowWord32( hwnd, offset, (WORD)newval );
1526 case GWL_WNDPROC:
1527 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1528 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1529 type, WIN_PROC_WINDOW );
1530 return retval;
1531 case GWL_STYLE:
1533 /* FIXME: WM_STYLE... messages for WIN_ISWIN32 windows */
1535 ptr = &wndPtr->dwStyle;
1536 /* Some bits can't be changed this way */
1537 newval &= ~(WS_VISIBLE | WS_CHILD);
1538 newval |= (*ptr & (WS_VISIBLE | WS_CHILD));
1539 break;
1540 case GWL_USERDATA: ptr = &wndPtr->userdata; break;
1541 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
1542 default:
1543 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1544 return 0;
1546 retval = *ptr;
1547 *ptr = newval;
1548 return retval;
1552 /**********************************************************************
1553 * GetWindowLong16 (USER.135)
1555 LONG GetWindowLong16( HWND16 hwnd, INT16 offset )
1557 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1561 /**********************************************************************
1562 * GetWindowLong32A (USER32.304)
1564 LONG GetWindowLong32A( HWND32 hwnd, INT32 offset )
1566 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1570 /**********************************************************************
1571 * GetWindowLong32W (USER32.305)
1573 LONG GetWindowLong32W( HWND32 hwnd, INT32 offset )
1575 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1579 /**********************************************************************
1580 * SetWindowLong16 (USER.136)
1582 LONG SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1584 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1588 /**********************************************************************
1589 * SetWindowLong32A (USER32.516)
1591 LONG SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1593 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1597 /**********************************************************************
1598 * SetWindowLong32W (USER32.517)
1600 LONG SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
1602 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1606 /*******************************************************************
1607 * GetWindowText16 (USER.36)
1609 INT16 GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1611 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1615 /*******************************************************************
1616 * GetWindowText32A (USER32.308)
1618 INT32 GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1620 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1621 (LPARAM)lpString );
1625 /*******************************************************************
1626 * GetWindowText32W (USER32.311)
1628 INT32 GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1630 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1631 (LPARAM)lpString );
1635 /*******************************************************************
1636 * SetWindowText16 (USER.37)
1638 void SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1640 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1644 /*******************************************************************
1645 * SetWindowText32A (USER32.)
1647 void SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1649 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1653 /*******************************************************************
1654 * SetWindowText32W (USER32.)
1656 void SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1658 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1662 /*******************************************************************
1663 * GetWindowTextLength16 (USER.38)
1665 INT16 GetWindowTextLength16( HWND16 hwnd )
1667 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1671 /*******************************************************************
1672 * GetWindowTextLength32A (USER32.309)
1674 INT32 GetWindowTextLength32A( HWND32 hwnd )
1676 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1679 /*******************************************************************
1680 * GetWindowTextLength32W (USER32.309)
1682 INT32 GetWindowTextLength32W( HWND32 hwnd )
1684 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1688 /*******************************************************************
1689 * IsWindow16 (USER.47)
1691 BOOL16 IsWindow16( HWND16 hwnd )
1693 return IsWindow32( hwnd );
1697 /*******************************************************************
1698 * IsWindow32 (USER32.347)
1700 BOOL32 IsWindow32( HWND32 hwnd )
1702 WND * wndPtr = WIN_FindWndPtr( hwnd );
1703 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1707 /*****************************************************************
1708 * GetParent16 (USER.46)
1710 HWND16 GetParent16( HWND16 hwnd )
1712 return (HWND16)GetParent32( hwnd );
1716 /*****************************************************************
1717 * GetParent32 (USER32.277)
1719 HWND32 GetParent32( HWND32 hwnd )
1721 WND *wndPtr = WIN_FindWndPtr(hwnd);
1722 if (!wndPtr) return 0;
1723 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1724 return wndPtr ? wndPtr->hwndSelf : 0;
1728 /*****************************************************************
1729 * WIN_GetTopParent
1731 * Get the top-level parent for a child window.
1733 HWND32 WIN_GetTopParent( HWND32 hwnd )
1735 WND *wndPtr = WIN_FindWndPtr( hwnd );
1736 while (wndPtr && (wndPtr->dwStyle & WS_CHILD)) wndPtr = wndPtr->parent;
1737 return wndPtr ? wndPtr->hwndSelf : 0;
1741 /*****************************************************************
1742 * SetParent16 (USER.233)
1744 HWND16 SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1746 return SetParent32( hwndChild, hwndNewParent );
1750 /*****************************************************************
1751 * SetParent32 (USER32.494)
1753 HWND32 SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1755 HWND32 oldParent;
1757 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1758 WND *pWndParent = WIN_FindWndPtr( hwndNewParent );
1759 if (!wndPtr || !pWndParent || !(wndPtr->dwStyle & WS_CHILD)) return 0;
1761 oldParent = wndPtr->parent->hwndSelf;
1763 WIN_UnlinkWindow(hwndChild);
1764 if (hwndNewParent) wndPtr->parent = pWndParent;
1765 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
1767 if (IsWindowVisible32(hwndChild)) UpdateWindow32(hwndChild);
1769 return oldParent;
1773 /*******************************************************************
1774 * IsChild16 (USER.48)
1776 BOOL16 IsChild16( HWND16 parent, HWND16 child )
1778 return IsChild32(parent,child);
1782 /*******************************************************************
1783 * IsChild32 (USER32.338)
1785 BOOL32 IsChild32( HWND32 parent, HWND32 child )
1787 WND * wndPtr = WIN_FindWndPtr( child );
1788 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1790 wndPtr = wndPtr->parent;
1791 if (wndPtr->hwndSelf == parent) return TRUE;
1793 return FALSE;
1797 /***********************************************************************
1798 * IsWindowVisible16 (USER.49)
1800 BOOL16 IsWindowVisible16( HWND16 hwnd )
1802 return IsWindowVisible32(hwnd);
1806 /***********************************************************************
1807 * IsWindowVisible32 (USER32.350)
1809 BOOL32 IsWindowVisible32( HWND32 hwnd )
1811 WND *wndPtr = WIN_FindWndPtr( hwnd );
1812 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1814 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1815 wndPtr = wndPtr->parent;
1817 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1821 /***********************************************************************
1822 * WIN_IsWindowDrawable
1824 * hwnd is drawable when it is visible, all parents are not
1825 * minimized, and it is itself not minimized unless we are
1826 * trying to draw icon and the default class icon is set.
1828 BOOL32 WIN_IsWindowDrawable( WND* wnd , BOOL32 icon )
1830 if( (wnd->dwStyle & WS_MINIMIZE &&
1831 icon && wnd->class->hIcon) ||
1832 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
1833 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
1834 if( wnd->dwStyle & WS_MINIMIZE ||
1835 !(wnd->dwStyle & WS_VISIBLE) ) break;
1836 return (wnd == NULL);
1840 /*******************************************************************
1841 * GetTopWindow16 (USER.229)
1843 HWND16 GetTopWindow16( HWND16 hwnd )
1845 return GetTopWindow32(hwnd);
1849 /*******************************************************************
1850 * GetTopWindow32 (USER.229)
1852 HWND32 GetTopWindow32( HWND32 hwnd )
1854 WND * wndPtr = WIN_FindWndPtr( hwnd );
1855 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1856 else return 0;
1860 /*******************************************************************
1861 * GetWindow16 (USER.262)
1863 HWND16 GetWindow16( HWND16 hwnd, WORD rel )
1865 return GetWindow32( hwnd,rel );
1869 /*******************************************************************
1870 * GetWindow32 (USER32.301)
1872 HWND32 GetWindow32( HWND32 hwnd, WORD rel )
1874 WND * wndPtr = WIN_FindWndPtr( hwnd );
1875 if (!wndPtr) return 0;
1876 switch(rel)
1878 case GW_HWNDFIRST:
1879 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
1880 else return 0;
1882 case GW_HWNDLAST:
1883 if (!wndPtr->parent) return 0; /* Desktop window */
1884 while (wndPtr->next) wndPtr = wndPtr->next;
1885 return wndPtr->hwndSelf;
1887 case GW_HWNDNEXT:
1888 if (!wndPtr->next) return 0;
1889 return wndPtr->next->hwndSelf;
1891 case GW_HWNDPREV:
1892 if (!wndPtr->parent) return 0; /* Desktop window */
1893 wndPtr = wndPtr->parent->child; /* First sibling */
1894 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
1895 while (wndPtr->next)
1897 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
1898 wndPtr = wndPtr->next;
1900 return 0;
1902 case GW_OWNER:
1903 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
1905 case GW_CHILD:
1906 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
1908 return 0;
1912 /*******************************************************************
1913 * GetNextWindow16 (USER.230)
1915 HWND16 GetNextWindow16( HWND16 hwnd, WORD flag )
1917 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1918 return GetWindow16( hwnd, flag );
1921 /*******************************************************************
1922 * ShowOwnedPopups16 (USER.265)
1924 void ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
1926 ShowOwnedPopups32( owner, fShow );
1930 /*******************************************************************
1931 * ShowOwnedPopups32 (USER32.530)
1933 BOOL32 ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
1935 WND *pWnd = pWndDesktop->child;
1936 while (pWnd)
1938 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
1939 (pWnd->dwStyle & WS_POPUP))
1940 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
1941 pWnd = pWnd->next;
1943 return TRUE;
1947 /*******************************************************************
1948 * GetLastActivePopup16 (USER.287)
1950 HWND16 GetLastActivePopup16( HWND16 hwnd )
1952 return GetLastActivePopup32( hwnd );
1955 /*******************************************************************
1956 * GetLastActivePopup32 (USER32.255)
1958 HWND32 GetLastActivePopup32( HWND32 hwnd )
1960 WND *wndPtr;
1961 wndPtr = WIN_FindWndPtr(hwnd);
1962 if (wndPtr == NULL) return hwnd;
1963 return wndPtr->hwndLastActive;
1967 /*******************************************************************
1968 * WIN_BuildWinArray
1970 * Build an array of pointers to all children of a given window.
1971 * The array must be freed with HeapFree(SystemHeap).
1973 WND **WIN_BuildWinArray( WND *wndPtr )
1975 WND **list, **ppWnd;
1976 WND *pWnd;
1977 INT32 count;
1979 /* First count the windows */
1981 if (!wndPtr) wndPtr = pWndDesktop;
1982 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next) count++;
1983 count++; /* For the terminating NULL */
1985 /* Now build the list of all windows */
1987 if (!(list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * count )))
1988 return NULL;
1989 for (pWnd = wndPtr->child, ppWnd = list; pWnd; pWnd = pWnd->next)
1990 *ppWnd++ = pWnd;
1991 *ppWnd = NULL;
1992 return list;
1996 /*******************************************************************
1997 * EnumWindows16 (USER.54)
1999 BOOL16 EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2001 WND **list, **ppWnd;
2003 /* We have to build a list of all windows first, to avoid */
2004 /* unpleasant side-effects, for instance if the callback */
2005 /* function changes the Z-order of the windows. */
2007 if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
2009 /* Now call the callback function for every window */
2011 for (ppWnd = list; *ppWnd; ppWnd++)
2013 /* Make sure that the window still exists */
2014 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2015 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2017 HeapFree( SystemHeap, 0, list );
2018 return TRUE;
2022 /*******************************************************************
2023 * EnumWindows32 (USER32.192)
2025 BOOL32 EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2027 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2031 /**********************************************************************
2032 * EnumTaskWindows16 (USER.225)
2034 BOOL16 EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func, LPARAM lParam )
2036 WND **list, **ppWnd;
2037 HQUEUE16 hQueue = GetTaskQueue( hTask );
2039 /* This function is the same as EnumWindows(), */
2040 /* except for an added check on the window queue. */
2042 if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
2044 /* Now call the callback function for every window */
2046 for (ppWnd = list; *ppWnd; ppWnd++)
2048 /* Make sure that the window still exists */
2049 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2050 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
2051 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2053 HeapFree( SystemHeap, 0, list );
2054 return TRUE;
2058 /**********************************************************************
2059 * EnumThreadWindows (USER32.189)
2061 BOOL32 EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2063 THDB *tdb = (THDB*)id;
2065 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2069 /**********************************************************************
2070 * WIN_EnumChildWindows
2072 * Helper function for EnumChildWindows().
2074 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2075 LPARAM lParam )
2077 WND **childList;
2078 BOOL16 ret = FALSE;
2080 while (*ppWnd)
2082 /* Make sure that the window still exists */
2083 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2084 /* Build children list first */
2085 if (!(childList = WIN_BuildWinArray( *ppWnd ))) return FALSE;
2086 if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
2087 ret = WIN_EnumChildWindows( childList, func, lParam );
2088 HeapFree( SystemHeap, 0, childList );
2089 if (!ret) return FALSE;
2090 ppWnd++;
2092 return TRUE;
2096 /**********************************************************************
2097 * EnumChildWindows16 (USER.55)
2099 BOOL16 EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func, LPARAM lParam )
2101 WND **list, *pParent;
2103 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2104 if (!(list = WIN_BuildWinArray( pParent ))) return FALSE;
2105 WIN_EnumChildWindows( list, func, lParam );
2106 HeapFree( SystemHeap, 0, list );
2107 return TRUE;
2111 /**********************************************************************
2112 * EnumChildWindows32 (USER32.177)
2114 BOOL32 EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func, LPARAM lParam )
2116 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2117 lParam );
2121 /*******************************************************************
2122 * AnyPopup16 (USER.52)
2124 BOOL16 AnyPopup16(void)
2126 return AnyPopup32();
2130 /*******************************************************************
2131 * AnyPopup32 (USER32.3)
2133 BOOL32 AnyPopup32(void)
2135 WND *wndPtr;
2136 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2137 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2138 return FALSE;
2142 /*******************************************************************
2143 * FlashWindow16 (USER.105)
2145 BOOL16 FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2147 return FlashWindow32( hWnd, bInvert );
2151 /*******************************************************************
2152 * FlashWindow32 (USER32.201)
2154 BOOL32 FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2156 WND *wndPtr = WIN_FindWndPtr(hWnd);
2158 dprintf_win(stddeb,"FlashWindow: %04x\n", hWnd);
2160 if (!wndPtr) return FALSE;
2162 if (wndPtr->dwStyle & WS_MINIMIZE)
2164 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2166 HDC32 hDC = GetDC32(hWnd);
2168 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2169 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2171 ReleaseDC32( hWnd, hDC );
2172 wndPtr->flags |= WIN_NCACTIVATED;
2174 else
2176 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2177 RDW_UPDATENOW | RDW_FRAME, 0 );
2178 wndPtr->flags &= ~WIN_NCACTIVATED;
2180 return TRUE;
2182 else
2184 WPARAM16 wparam;
2185 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2186 else wparam = (hWnd == GetActiveWindow32());
2188 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2189 return wparam;
2194 /*******************************************************************
2195 * SetSysModalWindow16 (USER.188)
2197 HWND16 SetSysModalWindow16( HWND16 hWnd )
2199 HWND32 hWndOldModal = hwndSysModal;
2200 hwndSysModal = hWnd;
2201 dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2202 return hWndOldModal;
2206 /*******************************************************************
2207 * GetSysModalWindow16 (USER.52)
2209 HWND16 GetSysModalWindow16(void)
2211 return hwndSysModal;
2215 /*******************************************************************
2216 * DRAG_QueryUpdate
2218 * recursively find a child that contains spDragInfo->pt point
2219 * and send WM_QUERYDROPOBJECT
2221 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2223 BOOL16 wParam,bResult = 0;
2224 POINT16 pt;
2225 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2226 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2227 RECT16 tempRect;
2229 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2231 pt = ptrDragInfo->pt;
2233 GetWindowRect16(hQueryWnd,&tempRect);
2235 if( !PtInRect16(&tempRect,pt) ||
2236 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2237 return 0;
2239 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2241 tempRect = ptrQueryWnd->rectClient;
2242 if(ptrQueryWnd->dwStyle & WS_CHILD)
2243 MapWindowPoints16(ptrQueryWnd->parent->hwndSelf,0,(LPPOINT16)&tempRect,2);
2245 if( PtInRect16(&tempRect,pt) )
2247 wParam = 0;
2249 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2250 if( ptrWnd->dwStyle & WS_VISIBLE )
2252 GetWindowRect16(ptrWnd->hwndSelf,&tempRect);
2254 if( PtInRect16(&tempRect,pt) )
2255 break;
2258 if(ptrWnd)
2260 dprintf_msg(stddeb,"DragQueryUpdate: hwnd = %04x, %d %d - %d %d\n",
2261 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2262 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2263 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2264 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2267 if(bResult) return bResult;
2269 else wParam = 1;
2271 else wParam = 1;
2273 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2275 ptrDragInfo->hScope = hQueryWnd;
2277 bResult = ( bNoSend )
2278 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2279 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2280 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2281 if( !bResult )
2282 ptrDragInfo->pt = pt;
2284 return bResult;
2288 /*******************************************************************
2289 * DragDetect (USER.465)
2291 BOOL16 DragDetect16( HWND16 hWnd, POINT16 pt )
2293 POINT32 pt32;
2294 CONV_POINT16TO32( &pt, &pt32 );
2295 return DragDetect32( hWnd, pt32 );
2298 /*******************************************************************
2299 * DragDetect32 (USER32.150)
2301 BOOL32 DragDetect32( HWND32 hWnd, POINT32 pt )
2303 MSG16 msg;
2304 RECT16 rect;
2306 rect.left = pt.x - wDragWidth;
2307 rect.right = pt.x + wDragWidth;
2309 rect.top = pt.y - wDragHeight;
2310 rect.bottom = pt.y + wDragHeight;
2312 SetCapture32(hWnd);
2314 while(1)
2316 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2318 if( msg.message == WM_LBUTTONUP )
2320 ReleaseCapture();
2321 return 0;
2323 if( msg.message == WM_MOUSEMOVE )
2325 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2327 ReleaseCapture();
2328 return 1;
2332 WaitMessage();
2335 return 0;
2338 /******************************************************************************
2339 * DragObject16 (USER.464)
2341 DWORD DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2342 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2344 MSG16 msg;
2345 LPDRAGINFO lpDragInfo;
2346 SEGPTR spDragInfo;
2347 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2348 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2349 WND *wndPtr = WIN_FindWndPtr(hWnd);
2350 DWORD dwRet = 0;
2351 short dragDone = 0;
2352 HCURSOR16 hCurrentCursor = 0;
2353 HWND16 hCurrentWnd = 0;
2354 BOOL16 b;
2356 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2357 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2359 if( !lpDragInfo || !spDragInfo ) return 0L;
2361 hBummer = LoadCursor16(0,IDC_BUMMER);
2363 if( !hBummer || !wndPtr )
2365 GlobalFree16(hDragInfo);
2366 return 0L;
2369 if(hCursor)
2371 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2373 GlobalFree16(hDragInfo);
2374 return 0L;
2377 if( hDragCursor == hCursor ) hDragCursor = 0;
2378 else hCursor = hDragCursor;
2380 hOldCursor = SetCursor32(hDragCursor);
2383 lpDragInfo->hWnd = hWnd;
2384 lpDragInfo->hScope = 0;
2385 lpDragInfo->wFlags = wObj;
2386 lpDragInfo->hList = szList; /* near pointer! */
2387 lpDragInfo->hOfStruct = hOfStruct;
2388 lpDragInfo->l = 0L;
2390 SetCapture32(hWnd);
2391 ShowCursor32( TRUE );
2393 while( !dragDone )
2395 WaitMessage();
2397 if( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) )
2398 continue;
2400 *(lpDragInfo+1) = *lpDragInfo;
2402 lpDragInfo->pt = msg.pt;
2404 /* update DRAGINFO struct */
2405 dprintf_msg(stddeb,"drag: lpDI->hScope = %04x\n",lpDragInfo->hScope);
2407 if( (b = DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE)) > 0 )
2408 hCurrentCursor = hCursor;
2409 else
2411 hCurrentCursor = hBummer;
2412 lpDragInfo->hScope = 0;
2414 if( hCurrentCursor )
2415 SetCursor32(hCurrentCursor);
2417 dprintf_msg(stddeb,"drag: got %04x\n", b);
2419 /* send WM_DRAGLOOP */
2420 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer) ,
2421 (LPARAM) spDragInfo );
2422 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2423 if( hCurrentWnd != lpDragInfo->hScope )
2425 if( hCurrentWnd )
2426 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2427 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2428 HIWORD(spDragInfo)) );
2429 hCurrentWnd = lpDragInfo->hScope;
2430 if( hCurrentWnd )
2431 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2433 else
2434 if( hCurrentWnd )
2435 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2438 /* check if we're done */
2439 if( msg.message == WM_LBUTTONUP || msg.message == WM_NCLBUTTONUP )
2440 dragDone = TRUE;
2443 ReleaseCapture();
2444 ShowCursor32( FALSE );
2446 if( hCursor )
2448 SetCursor32( hOldCursor );
2449 if (hDragCursor) DestroyCursor32( hDragCursor );
2452 if( hCurrentCursor != hBummer )
2453 dwRet = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2454 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2455 GlobalFree16(hDragInfo);
2457 return dwRet;