2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
17 #include "sysmetrics.h"
18 #include "cursoricon.h"
23 #include "nonclient.h"
26 #include "shm_main_blk.h"
28 #include "clipboard.h"
39 #ifndef X_DISPLAY_MISSING
40 extern DESKTOP_DRIVER X11DRV_DESKTOP_Driver;
41 extern WND_DRIVER X11DRV_WND_Driver;
42 #else /* X_DISPLAY_MISSING */
43 extern DESKTOP_DRIVER TTYDRV_DESKTOP_Driver;
44 extern WND_DRIVER TTYDRV_WND_Driver;
45 #endif /* X_DISPLAY_MISSING */
48 static WND *pWndDesktop = NULL;
50 static HWND32 hwndSysModal = 0;
52 static WORD wDragWidth = 4;
53 static WORD wDragHeight= 3;
55 /***********************************************************************
58 * Return a pointer to the WND structure corresponding to a HWND.
60 WND * WIN_FindWndPtr( HWND32 hwnd )
64 if (!hwnd || HIWORD(hwnd)) return NULL;
65 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
66 if (ptr->dwMagic != WND_MAGIC) return NULL;
67 if (ptr->hwndSelf != hwnd)
69 ERR( win, "Can't happen: hwnd %04x self pointer is %04x\n",
70 hwnd, ptr->hwndSelf );
77 /***********************************************************************
80 * Dump the content of a window structure to stderr.
82 void WIN_DumpWindow( HWND32 hwnd )
88 if (!(ptr = WIN_FindWndPtr( hwnd )))
90 WARN( win, "%04x is not a window handle\n", hwnd );
94 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
95 strcpy( className, "#NULL#" );
97 TRACE( win, "Window %04x (%p):\n", hwnd, ptr );
98 DUMP( "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
99 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
100 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
101 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
102 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
103 ptr->next, ptr->child, ptr->parent, ptr->owner,
104 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
105 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
106 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
107 ptr->text ? ptr->text : "",
108 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
109 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
110 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
111 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
113 if (ptr->class->cbWndExtra)
115 DUMP( "extra bytes:" );
116 for (i = 0; i < ptr->class->cbWndExtra; i++)
117 DUMP( " %02x", *((BYTE*)ptr->wExtra+i) );
124 /***********************************************************************
127 * Walk the windows tree and print each window on stderr.
129 void WIN_WalkWindows( HWND32 hwnd, int indent )
134 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
137 WARN( win, "Invalid window handle %04x\n", hwnd );
141 if (!indent) /* first time around */
142 DUMP( "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
143 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc"
148 DUMP( "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
150 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
152 DUMP( "%08lx %-6.4x %-17.17s %08x %08x %.14s\n",
153 (DWORD)ptr, ptr->hmemTaskQ, className,
154 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc,
155 ptr->text?ptr->text:"<null>");
157 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
162 /***********************************************************************
165 * Remove a window from the siblings linked list.
167 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
169 WND *wndPtr, **ppWnd;
171 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
172 ppWnd = &wndPtr->parent->child;
173 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
174 *ppWnd = wndPtr->next;
179 /***********************************************************************
182 * Insert a window into the siblings linked list.
183 * The window is inserted after the specified window, which can also
184 * be specified as HWND_TOP or HWND_BOTTOM.
186 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
188 WND *wndPtr, **ppWnd;
190 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
192 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
194 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
195 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
196 while (*ppWnd) ppWnd = &(*ppWnd)->next;
198 else /* Normal case */
200 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
201 if (!afterPtr) return FALSE;
202 ppWnd = &afterPtr->next;
204 wndPtr->next = *ppWnd;
210 /***********************************************************************
211 * WIN_FindWinToRepaint
213 * Find a window that needs repaint.
215 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
218 WND *pWnd = pWndDesktop;
220 /* Note: the desktop window never gets WM_PAINT messages
221 * The real reason why is because Windows DesktopWndProc
222 * does ValidateRgn inside WM_ERASEBKGND handler.
225 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
227 for ( ; pWnd ; pWnd = pWnd->next )
229 if (!(pWnd->dwStyle & WS_VISIBLE))
231 TRACE(win, "skipping window %04x\n",
235 if ((pWnd->hmemTaskQ == hQueue) &&
236 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
239 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
245 hwndRet = pWnd->hwndSelf;
247 /* look among siblings if we got a transparent window */
248 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
249 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
253 if (pWnd) hwndRet = pWnd->hwndSelf;
254 TRACE(win,"found %04x\n",hwndRet);
259 /***********************************************************************
262 * Destroy storage associated to a window. "Internals" p.358
264 static WND* WIN_DestroyWindow( WND* wndPtr )
266 HWND32 hwnd = wndPtr->hwndSelf;
269 TRACE(win, "%04x\n", wndPtr->hwndSelf );
273 DDE_DestroyWindow(wndPtr->hwndSelf);
274 #endif /* CONFIG_IPC */
276 /* free child windows */
278 while ((pWnd = wndPtr->child))
279 wndPtr->child = WIN_DestroyWindow( pWnd );
281 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
283 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
285 WINPOS_CheckInternalPos( hwnd );
286 if( hwnd == GetCapture32()) ReleaseCapture();
288 /* free resources associated with the window */
290 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
291 PROPERTY_RemoveWindowProps( wndPtr );
293 wndPtr->dwMagic = 0; /* Mark it as invalid */
295 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
297 if (wndPtr->hrgnUpdate > 1) DeleteObject32( wndPtr->hrgnUpdate );
298 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
301 /* toss stale messages from the queue */
303 if( wndPtr->hmemTaskQ )
305 BOOL32 bPostQuit = FALSE;
306 WPARAM32 wQuitParam = 0;
307 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) QUEUE_Lock(wndPtr->hmemTaskQ);
310 while( (qmsg = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != 0 )
312 if( qmsg->msg.message == WM_QUIT )
315 wQuitParam = qmsg->msg.wParam;
317 QUEUE_RemoveMsg(msgQ, qmsg);
322 /* repost WM_QUIT to make sure this app exits its message loop */
323 if( bPostQuit ) PostQuitMessage32(wQuitParam);
324 wndPtr->hmemTaskQ = 0;
327 if (!(wndPtr->dwStyle & WS_CHILD))
328 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
329 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
330 wndPtr->pDriver->pDestroyWindow( wndPtr );
331 DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */
332 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
333 wndPtr->hwndSelf = 0;
334 wndPtr->class->cWindows--;
335 wndPtr->class = NULL;
338 wndPtr->pDriver->pFinalize(wndPtr);
339 USER_HEAP_FREE( hwnd );
343 /***********************************************************************
344 * WIN_ResetQueueWindows
346 * Reset the queue of all the children of a given window.
347 * Return TRUE if something was done.
349 BOOL32 WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
353 if (hNew) /* Set a new queue */
355 for (wnd = wnd->child; (wnd); wnd = wnd->next)
357 if (wnd->hmemTaskQ == hQueue)
359 wnd->hmemTaskQ = hNew;
363 ret |= WIN_ResetQueueWindows( wnd, hQueue, hNew );
366 else /* Queue is being destroyed */
370 WND *tmp = wnd->child;
374 if (tmp->hmemTaskQ == hQueue)
376 DestroyWindow32( tmp->hwndSelf );
380 if (tmp->child && WIN_ResetQueueWindows(tmp->child,hQueue,0))
391 /***********************************************************************
392 * WIN_CreateDesktopWindow
394 * Create the desktop window.
396 BOOL32 WIN_CreateDesktopWindow(void)
402 TRACE(win,"Creating desktop window\n");
404 if (!ICONTITLE_Init() ||
405 !WINPOS_CreateInternalPosAtom() ||
406 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
409 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
410 if (!hwndDesktop) return FALSE;
411 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
413 pDesktop = (DESKTOP *) pWndDesktop->wExtra;
414 #ifndef X_DISPLAY_MISSING
415 pDesktop->pDriver = &X11DRV_DESKTOP_Driver;
416 pWndDesktop->pDriver = &X11DRV_WND_Driver;
417 #else /* X_DISPLAY_MISSING */
418 pDesktop->pDriver = &TTYDRV_DESKTOP_Driver;
419 pWndDesktop->pDriver = &TTYDRV_WND_Driver;
420 #endif /* X_DISPLAY_MISSING */
422 pDesktop->pDriver->pInitialize(pDesktop);
423 pWndDesktop->pDriver->pInitialize(pWndDesktop);
425 pWndDesktop->next = NULL;
426 pWndDesktop->child = NULL;
427 pWndDesktop->parent = NULL;
428 pWndDesktop->owner = NULL;
429 pWndDesktop->class = class;
430 pWndDesktop->dwMagic = WND_MAGIC;
431 pWndDesktop->hwndSelf = hwndDesktop;
432 pWndDesktop->hInstance = 0;
433 pWndDesktop->rectWindow.left = 0;
434 pWndDesktop->rectWindow.top = 0;
435 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
436 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
437 pWndDesktop->rectClient = pWndDesktop->rectWindow;
438 pWndDesktop->text = NULL;
439 pWndDesktop->hmemTaskQ = GetFastQueue();
440 pWndDesktop->hrgnUpdate = 0;
441 pWndDesktop->hwndLastActive = hwndDesktop;
442 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
444 pWndDesktop->dwExStyle = 0;
445 pWndDesktop->dce = NULL;
446 pWndDesktop->pVScroll = NULL;
447 pWndDesktop->pHScroll = NULL;
448 pWndDesktop->pProp = NULL;
449 pWndDesktop->wIDmenu = 0;
450 pWndDesktop->helpContext = 0;
451 pWndDesktop->flags = 0;
452 pWndDesktop->hSysMenu = 0;
453 pWndDesktop->userdata = 0;
454 pWndDesktop->winproc = (WNDPROC16)class->winproc;
456 /* FIXME: How do we know if it should be Unicode or not */
457 if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop, class, FALSE))
460 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
461 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
466 /***********************************************************************
469 * Implementation of CreateWindowEx().
471 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
472 BOOL32 win32, BOOL32 unicode )
476 HWND16 hwnd, hwndLinkAfter;
477 POINT32 maxSize, maxPos, minTrack, maxTrack;
478 LRESULT (CALLBACK *localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
480 TRACE(win, "%s %s %08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
481 unicode ? debugres_w((LPWSTR)cs->lpszName) : debugres_a(cs->lpszName),
482 unicode ? debugres_w((LPWSTR)cs->lpszClass) : debugres_a(cs->lpszClass),
483 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
484 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
486 /* Find the parent window */
490 /* Make sure parent is valid */
491 if (!IsWindow32( cs->hwndParent ))
493 WARN( win, "Bad parent %04x\n", cs->hwndParent );
496 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
497 WARN( win, "No parent for child window\n" );
498 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
501 /* Find the window class */
502 if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
505 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
506 WARN( win, "Bad class '%s'\n", buffer );
510 /* Fix the coordinates */
512 if (cs->x == CW_USEDEFAULT32)
514 PDB32 *pdb = PROCESS_Current();
515 if ( !(cs->style & (WS_CHILD | WS_POPUP))
516 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
518 cs->x = pdb->env_db->startup_info->dwX;
519 cs->y = pdb->env_db->startup_info->dwY;
527 if (cs->cx == CW_USEDEFAULT32)
529 PDB32 *pdb = PROCESS_Current();
530 if ( !(cs->style & (WS_CHILD | WS_POPUP))
531 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
533 cs->cx = pdb->env_db->startup_info->dwXSize;
534 cs->cy = pdb->env_db->startup_info->dwYSize;
538 cs->cx = 600; /* FIXME */
543 /* Create the window structure */
545 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
546 - sizeof(wndPtr->wExtra) )))
548 TRACE(win, "out of memory\n" );
552 /* Fill the window structure */
554 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
556 wndPtr->child = NULL;
558 if ((cs->style & WS_CHILD) && cs->hwndParent)
560 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
561 wndPtr->owner = NULL;
565 wndPtr->parent = pWndDesktop;
566 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
567 wndPtr->owner = NULL;
569 wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
572 wndPtr->pDriver = wndPtr->parent->pDriver;
573 wndPtr->pDriver->pInitialize(wndPtr);
575 wndPtr->class = classPtr;
576 wndPtr->winproc = classPtr->winproc;
577 wndPtr->dwMagic = WND_MAGIC;
578 wndPtr->hwndSelf = hwnd;
579 wndPtr->hInstance = cs->hInstance;
581 wndPtr->hmemTaskQ = GetFastQueue();
582 wndPtr->hrgnUpdate = 0;
583 wndPtr->hwndLastActive = hwnd;
584 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
585 wndPtr->dwExStyle = cs->dwExStyle;
587 wndPtr->helpContext = 0;
588 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
589 wndPtr->pVScroll = NULL;
590 wndPtr->pHScroll = NULL;
591 wndPtr->pProp = NULL;
592 wndPtr->userdata = 0;
593 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
594 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
596 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
598 /* Call the WH_CBT hook */
600 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
601 ? HWND_BOTTOM : HWND_TOP;
603 if (HOOK_IsHooked( WH_CBT ))
605 CBT_CREATEWND32A cbtc;
609 cbtc.hwndInsertAfter = hwndLinkAfter;
610 ret = unicode ? HOOK_CallHooks32W(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc)
611 : HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc);
614 TRACE(win, "CBT-hook returned 0\n");
615 wndPtr->pDriver->pFinalize(wndPtr);
616 USER_HEAP_FREE( hwnd );
621 /* Increment class window counter */
623 classPtr->cWindows++;
625 /* Correct the window style */
627 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
629 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
630 wndPtr->flags |= WIN_NEED_SIZE;
632 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
634 /* Get class or window DC if needed */
636 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
637 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
638 else wndPtr->dce = NULL;
640 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
642 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
644 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
645 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
646 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
647 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
648 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
651 if(cs->style & WS_CHILD)
653 if(cs->cx < 0) cs->cx = 0;
654 if(cs->cy < 0) cs->cy = 0;
658 if (cs->cx <= 0) cs->cx = 1;
659 if (cs->cy <= 0) cs->cy = 1;
662 wndPtr->rectWindow.left = cs->x;
663 wndPtr->rectWindow.top = cs->y;
664 wndPtr->rectWindow.right = cs->x + cs->cx;
665 wndPtr->rectWindow.bottom = cs->y + cs->cy;
666 wndPtr->rectClient = wndPtr->rectWindow;
668 if(!wndPtr->pDriver->pCreateWindow(wndPtr, classPtr, cs, unicode))
671 /* Set the window menu */
673 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
675 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
678 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
679 if (classPtr->menuNameA)
680 cs->hMenu = HIWORD(classPtr->menuNameA) ?
681 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
682 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
684 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
687 if (HIWORD(cs->hInstance))
688 cs->hMenu = LoadMenu32A(cs->hInstance,PTR_SEG_TO_LIN(menuName));
690 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
692 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
697 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
699 /* Send the WM_CREATE message
700 * Perhaps we shouldn't allow width/height changes as well.
701 * See p327 in "Internals".
704 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
706 localSend32 = unicode ? SendMessage32W : SendMessage32A;
707 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
709 /* Insert the window in the linked list */
711 WIN_LinkWindow( hwnd, hwndLinkAfter );
713 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
714 NULL, NULL, 0, &wndPtr->rectClient );
715 OffsetRect32(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
716 maxPos.y - wndPtr->rectWindow.top);
717 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
719 /* Send the size messages */
721 if (!(wndPtr->flags & WIN_NEED_SIZE))
724 if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
725 ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
726 WARN(win,"sending bogus WM_SIZE message 0x%08lx\n",
727 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
728 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
729 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
730 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
731 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
732 SendMessage32A( hwnd, WM_MOVE, 0,
733 MAKELONG( wndPtr->rectClient.left,
734 wndPtr->rectClient.top ) );
737 /* Show the window, maximizing or minimizing if needed */
739 if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
742 UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
743 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
744 WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
745 swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow32())
746 ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
747 : SWP_NOZORDER | SWP_FRAMECHANGED;
748 SetWindowPos32( hwnd, 0, newPos.left, newPos.top,
749 newPos.right, newPos.bottom, swFlag );
752 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
754 /* Notify the parent window only */
756 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
757 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
758 if( !IsWindow32(hwnd) ) return 0;
761 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
763 /* Call WH_SHELL hook */
765 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
766 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
768 TRACE(win, "created window %04x\n", hwnd);
771 WIN_UnlinkWindow( hwnd );
774 /* Abort window creation */
776 WARN(win, "aborted by WM_xxCREATE!\n");
777 WIN_DestroyWindow( wndPtr );
782 /***********************************************************************
783 * CreateWindow16 (USER.41)
785 HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
786 DWORD style, INT16 x, INT16 y, INT16 width,
787 INT16 height, HWND16 parent, HMENU16 menu,
788 HINSTANCE16 instance, LPVOID data )
790 return CreateWindowEx16( 0, className, windowName, style,
791 x, y, width, height, parent, menu, instance, data );
795 /***********************************************************************
796 * CreateWindowEx16 (USER.452)
798 HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
799 LPCSTR windowName, DWORD style, INT16 x,
800 INT16 y, INT16 width, INT16 height,
801 HWND16 parent, HMENU16 menu,
802 HINSTANCE16 instance, LPVOID data )
807 /* Find the class atom */
809 if (!(classAtom = GlobalFindAtom32A( className )))
811 fprintf( stderr, "CreateWindowEx16: bad class name " );
812 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
813 else fprintf( stderr, "'%s'\n", className );
817 /* Fix the coordinates */
819 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
820 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
821 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
822 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
824 /* Create the window */
826 cs.lpCreateParams = data;
827 cs.hInstance = (HINSTANCE32)instance;
828 cs.hMenu = (HMENU32)menu;
829 cs.hwndParent = (HWND32)parent;
831 cs.lpszName = windowName;
832 cs.lpszClass = className;
833 cs.dwExStyle = exStyle;
834 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
838 /***********************************************************************
839 * CreateWindowEx32A (USER32.83)
841 HWND32 WINAPI CreateWindowEx32A( DWORD exStyle, LPCSTR className,
842 LPCSTR windowName, DWORD style, INT32 x,
843 INT32 y, INT32 width, INT32 height,
844 HWND32 parent, HMENU32 menu,
845 HINSTANCE32 instance, LPVOID data )
850 if(exStyle & WS_EX_MDICHILD)
851 return MDI_CreateMDIWindow32A(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
852 /* Find the class atom */
854 if (!(classAtom = GlobalFindAtom32A( className )))
856 fprintf( stderr, "CreateWindowEx32A: bad class name " );
857 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
858 else fprintf( stderr, "'%s'\n", className );
862 /* Create the window */
864 cs.lpCreateParams = data;
865 cs.hInstance = instance;
867 cs.hwndParent = parent;
873 cs.lpszName = windowName;
874 cs.lpszClass = className;
875 cs.dwExStyle = exStyle;
876 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
880 /***********************************************************************
881 * CreateWindowEx32W (USER32.84)
883 HWND32 WINAPI CreateWindowEx32W( DWORD exStyle, LPCWSTR className,
884 LPCWSTR windowName, DWORD style, INT32 x,
885 INT32 y, INT32 width, INT32 height,
886 HWND32 parent, HMENU32 menu,
887 HINSTANCE32 instance, LPVOID data )
892 if(exStyle & WS_EX_MDICHILD)
893 return MDI_CreateMDIWindow32W(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
895 /* Find the class atom */
897 if (!(classAtom = GlobalFindAtom32W( className )))
899 if (HIWORD(className))
901 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
902 WARN( win, "Bad class name '%s'\n",cn);
903 HeapFree( GetProcessHeap(), 0, cn );
906 WARN( win, "Bad class name %p\n", className );
910 /* Create the window */
912 cs.lpCreateParams = data;
913 cs.hInstance = instance;
915 cs.hwndParent = parent;
921 cs.lpszName = windowName;
922 cs.lpszClass = className;
923 cs.dwExStyle = exStyle;
924 /* Note: we rely on the fact that CREATESTRUCT32A and */
925 /* CREATESTRUCT32W have the same layout. */
926 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
930 /***********************************************************************
933 static void WIN_CheckFocus( WND* pWnd )
935 if( GetFocus16() == pWnd->hwndSelf )
936 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
939 /***********************************************************************
942 static void WIN_SendDestroyMsg( WND* pWnd )
944 WIN_CheckFocus(pWnd);
946 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
947 CLIPBOARD_GetDriver()->pResetOwner( pWnd, TRUE );
949 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
951 if( IsWindow32(pWnd->hwndSelf) )
953 WND* pChild = pWnd->child;
956 WIN_SendDestroyMsg( pChild );
957 pChild = pChild->next;
959 WIN_CheckFocus(pWnd);
962 WARN(win, "\tdestroyed itself while in WM_DESTROY!\n");
966 /***********************************************************************
967 * DestroyWindow16 (USER.53)
969 BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
971 return DestroyWindow32(hwnd);
975 /***********************************************************************
976 * DestroyWindow32 (USER32.135)
978 BOOL32 WINAPI DestroyWindow32( HWND32 hwnd )
982 TRACE(win, "(%04x)\n", hwnd);
986 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
987 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
991 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
994 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
996 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
997 /* FIXME: clean up palette - see "Internals" p.352 */
1000 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
1001 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
1003 /* Notify the parent window only */
1004 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
1005 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
1006 if( !IsWindow32(hwnd) ) return TRUE;
1009 CLIPBOARD_GetDriver()->pResetOwner( wndPtr, FALSE ); /* before the 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( (HQUEUE16)0xFFFF, wndPtr );
1030 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1033 if (siblingPtr->owner == wndPtr)
1035 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1038 siblingPtr->owner = NULL;
1040 siblingPtr = siblingPtr->next;
1042 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1046 if( !Options.managed || EVENT_CheckFocus() )
1047 WINPOS_ActivateOtherWindow(wndPtr);
1049 if( wndPtr->owner &&
1050 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1051 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1054 /* Send destroy messages */
1056 WIN_SendDestroyMsg( wndPtr );
1057 if (!IsWindow32(hwnd)) return TRUE;
1059 /* Unlink now so we won't bother with the children later on */
1061 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1063 /* Destroy the window storage */
1065 WIN_DestroyWindow( wndPtr );
1070 /***********************************************************************
1071 * CloseWindow16 (USER.43)
1073 BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
1075 return CloseWindow32( hwnd );
1079 /***********************************************************************
1080 * CloseWindow32 (USER32.56)
1082 BOOL32 WINAPI CloseWindow32( HWND32 hwnd )
1084 WND * wndPtr = WIN_FindWndPtr( hwnd );
1085 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1086 ShowWindow32( hwnd, SW_MINIMIZE );
1091 /***********************************************************************
1092 * OpenIcon16 (USER.44)
1094 BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
1096 return OpenIcon32( hwnd );
1100 /***********************************************************************
1101 * OpenIcon32 (USER32.410)
1103 BOOL32 WINAPI OpenIcon32( HWND32 hwnd )
1105 if (!IsIconic32( hwnd )) return FALSE;
1106 ShowWindow32( hwnd, SW_SHOWNORMAL );
1111 /***********************************************************************
1114 * Implementation of FindWindow() and FindWindowEx().
1116 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1120 CLASS *pClass = NULL;
1124 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1127 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1129 else if (pWnd->parent != pWndDesktop) return 0;
1134 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1137 if (!pWnd) return 0;
1139 /* For a child window, all siblings will have the same hInstance, */
1140 /* so we can look for the class once and for all. */
1142 if (className && (pWnd->dwStyle & WS_CHILD))
1144 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1149 for ( ; pWnd; pWnd = pWnd->next)
1151 if (className && !(pWnd->dwStyle & WS_CHILD))
1153 if (!(pClass = CLASS_FindClassByAtom( className, GetExePtr(pWnd->hInstance))))
1154 continue; /* Skip this window */
1157 if (pClass && (pWnd->class != pClass))
1158 continue; /* Not the right class */
1160 /* Now check the title */
1162 if (!title) return pWnd->hwndSelf;
1163 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1170 /***********************************************************************
1171 * FindWindow16 (USER.50)
1173 HWND16 WINAPI FindWindow16( SEGPTR className, LPCSTR title )
1175 return FindWindowEx16( 0, 0, className, title );
1179 /***********************************************************************
1180 * FindWindowEx16 (USER.427)
1182 HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child,
1183 SEGPTR className, LPCSTR title )
1187 TRACE(win, "%04x %04x '%s' '%s'\n", parent,
1188 child, HIWORD(className)?(char *)PTR_SEG_TO_LIN(className):"",
1189 title ? title : "");
1193 /* If the atom doesn't exist, then no class */
1194 /* with this name exists either. */
1195 if (!(atom = GlobalFindAtom16( className ))) return 0;
1197 return WIN_FindWindow( parent, child, atom, title );
1201 /***********************************************************************
1202 * FindWindow32A (USER32.198)
1204 HWND32 WINAPI FindWindow32A( LPCSTR className, LPCSTR title )
1206 HWND32 ret = FindWindowEx32A( 0, 0, className, title );
1207 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1212 /***********************************************************************
1213 * FindWindowEx32A (USER32.199)
1215 HWND32 WINAPI FindWindowEx32A( HWND32 parent, HWND32 child,
1216 LPCSTR className, LPCSTR title )
1222 /* If the atom doesn't exist, then no class */
1223 /* with this name exists either. */
1224 if (!(atom = GlobalFindAtom32A( className )))
1226 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1230 return WIN_FindWindow( parent, child, atom, title );
1234 /***********************************************************************
1235 * FindWindowEx32W (USER32.200)
1237 HWND32 WINAPI FindWindowEx32W( HWND32 parent, HWND32 child,
1238 LPCWSTR className, LPCWSTR title )
1246 /* If the atom doesn't exist, then no class */
1247 /* with this name exists either. */
1248 if (!(atom = GlobalFindAtom32W( className )))
1250 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1254 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1255 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1256 HeapFree( GetProcessHeap(), 0, buffer );
1261 /***********************************************************************
1262 * FindWindow32W (USER32.201)
1264 HWND32 WINAPI FindWindow32W( LPCWSTR className, LPCWSTR title )
1266 return FindWindowEx32W( 0, 0, className, title );
1270 /**********************************************************************
1273 WND *WIN_GetDesktop(void)
1279 /**********************************************************************
1280 * GetDesktopWindow16 (USER.286)
1282 HWND16 WINAPI GetDesktopWindow16(void)
1284 return (HWND16)pWndDesktop->hwndSelf;
1288 /**********************************************************************
1289 * GetDesktopWindow32 (USER32.232)
1291 HWND32 WINAPI GetDesktopWindow32(void)
1293 return pWndDesktop->hwndSelf;
1297 /**********************************************************************
1298 * GetDesktopHwnd (USER.278)
1300 * Exactly the same thing as GetDesktopWindow(), but not documented.
1301 * Don't ask me why...
1303 HWND16 WINAPI GetDesktopHwnd(void)
1305 return (HWND16)pWndDesktop->hwndSelf;
1309 /*******************************************************************
1310 * EnableWindow16 (USER.34)
1312 BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
1314 return EnableWindow32( hwnd, enable );
1318 /*******************************************************************
1319 * EnableWindow32 (USER32.172)
1321 BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
1325 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1326 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1329 wndPtr->dwStyle &= ~WS_DISABLED;
1330 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1333 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1335 /* Disable window */
1336 wndPtr->dwStyle |= WS_DISABLED;
1337 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1338 SetFocus32( 0 ); /* A disabled window can't have the focus */
1339 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1340 ReleaseCapture(); /* A disabled window can't capture the mouse */
1341 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1344 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1348 /***********************************************************************
1349 * IsWindowEnabled16 (USER.35)
1351 BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
1353 return IsWindowEnabled32(hWnd);
1357 /***********************************************************************
1358 * IsWindowEnabled32 (USER32.349)
1360 BOOL32 WINAPI IsWindowEnabled32(HWND32 hWnd)
1364 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1365 return !(wndPtr->dwStyle & WS_DISABLED);
1369 /***********************************************************************
1370 * IsWindowUnicode (USER32.350)
1372 BOOL32 WINAPI IsWindowUnicode( HWND32 hwnd )
1376 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1377 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1381 /**********************************************************************
1382 * GetWindowWord16 (USER.133)
1384 WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
1386 return GetWindowWord32( hwnd, offset );
1390 /**********************************************************************
1391 * GetWindowWord32 (USER32.314)
1393 WORD WINAPI GetWindowWord32( HWND32 hwnd, INT32 offset )
1395 WND * wndPtr = WIN_FindWndPtr( hwnd );
1396 if (!wndPtr) return 0;
1399 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1401 WARN( win, "Invalid offset %d\n", offset );
1404 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1409 if (HIWORD(wndPtr->wIDmenu))
1410 WARN( win,"GWW_ID: discards high bits of 0x%08x!\n",
1412 return (WORD)wndPtr->wIDmenu;
1413 case GWW_HWNDPARENT:
1414 return wndPtr->parent ?
1415 wndPtr->parent->hwndSelf : (
1417 wndPtr->owner->hwndSelf :
1420 if (HIWORD(wndPtr->hInstance))
1421 WARN(win,"GWW_HINSTANCE: discards high bits of 0x%08x!\n",
1423 return (WORD)wndPtr->hInstance;
1425 WARN( win, "Invalid offset %d\n", offset );
1431 /**********************************************************************
1432 * WIN_GetWindowInstance
1434 HINSTANCE32 WIN_GetWindowInstance( HWND32 hwnd )
1436 WND * wndPtr = WIN_FindWndPtr( hwnd );
1437 if (!wndPtr) return (HINSTANCE32)0;
1438 return wndPtr->hInstance;
1442 /**********************************************************************
1443 * SetWindowWord16 (USER.134)
1445 WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1447 return SetWindowWord32( hwnd, offset, newval );
1451 /**********************************************************************
1452 * SetWindowWord32 (USER32.524)
1454 WORD WINAPI SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1457 WND * wndPtr = WIN_FindWndPtr( hwnd );
1458 if (!wndPtr) return 0;
1461 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1463 WARN( win, "Invalid offset %d\n", offset );
1466 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1470 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1471 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1472 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1474 WARN( win, "Invalid offset %d\n", offset );
1483 /**********************************************************************
1486 * Helper function for GetWindowLong().
1488 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1491 WND * wndPtr = WIN_FindWndPtr( hwnd );
1492 if (!wndPtr) return 0;
1495 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1497 WARN( win, "Invalid offset %d\n", offset );
1500 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1501 /* Special case for dialog window procedure */
1502 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1503 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1508 case GWL_USERDATA: return wndPtr->userdata;
1509 case GWL_STYLE: return wndPtr->dwStyle;
1510 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1511 case GWL_ID: return (LONG)wndPtr->wIDmenu;
1512 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1514 case GWL_HWNDPARENT: return wndPtr->parent ?
1515 (HWND32)wndPtr->parent->hwndSelf : 0;
1516 case GWL_HINSTANCE: return wndPtr->hInstance;
1518 WARN( win, "Unknown offset %d\n", offset );
1524 /**********************************************************************
1527 * Helper function for SetWindowLong().
1529 * 0 is the failure code. However, in the case of failure SetLastError
1530 * must be set to distinguish between a 0 return value and a failure.
1532 * FIXME: The error values for SetLastError may not be right. Can
1533 * someone check with the real thing?
1535 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1536 WINDOWPROCTYPE type )
1539 WND * wndPtr = WIN_FindWndPtr( hwnd );
1542 TRACE(win,"%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
1546 /* Is this the right error? */
1547 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1553 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1555 WARN( win, "Invalid offset %d\n", offset );
1557 /* Is this the right error? */
1558 SetLastError( ERROR_OUTOFMEMORY );
1562 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1563 /* Special case for dialog window procedure */
1564 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1566 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1567 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1568 type, WIN_PROC_WINDOW );
1575 ptr = (DWORD*)&wndPtr->wIDmenu;
1578 return SetWindowWord32( hwnd, offset, newval );
1580 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1581 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1582 type, WIN_PROC_WINDOW );
1585 style.styleOld = wndPtr->dwStyle;
1586 newval &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way */
1587 style.styleNew = newval | (style.styleOld & (WS_VISIBLE | WS_CHILD));
1589 if (wndPtr->flags & WIN_ISWIN32)
1590 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
1591 wndPtr->dwStyle = style.styleNew;
1592 if (wndPtr->flags & WIN_ISWIN32)
1593 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
1594 return style.styleOld;
1597 ptr = &wndPtr->userdata;
1600 style.styleOld = wndPtr->dwExStyle;
1601 style.styleNew = newval;
1602 if (wndPtr->flags & WIN_ISWIN32)
1603 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
1604 wndPtr->dwExStyle = newval;
1605 if (wndPtr->flags & WIN_ISWIN32)
1606 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
1607 return style.styleOld;
1610 WARN( win, "Invalid offset %d\n", offset );
1612 /* Don't think this is right error but it should do */
1613 SetLastError( ERROR_OUTOFMEMORY );
1623 /**********************************************************************
1624 * GetWindowLong16 (USER.135)
1626 LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
1628 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1632 /**********************************************************************
1633 * GetWindowLong32A (USER32.305)
1635 LONG WINAPI GetWindowLong32A( HWND32 hwnd, INT32 offset )
1637 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1641 /**********************************************************************
1642 * GetWindowLong32W (USER32.306)
1644 LONG WINAPI GetWindowLong32W( HWND32 hwnd, INT32 offset )
1646 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1650 /**********************************************************************
1651 * SetWindowLong16 (USER.136)
1653 LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1655 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1659 /**********************************************************************
1660 * SetWindowLong32A (USER32.517)
1662 LONG WINAPI SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1664 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1668 /**********************************************************************
1669 * SetWindowLong32W (USER32.518) Set window attribute
1671 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
1672 * value in a window's extra memory.
1674 * The _hwnd_ parameter specifies the window. is the handle to a
1675 * window that has extra memory. The _newval_ parameter contains the
1676 * new attribute or extra memory value. If positive, the _offset_
1677 * parameter is the byte-addressed location in the window's extra
1678 * memory to set. If negative, _offset_ specifies the window
1679 * attribute to set, and should be one of the following values:
1681 * GWL_EXSTYLE The window's extended window style
1683 * GWL_STYLE The window's window style.
1685 * GWL_WNDPROC Pointer to the window's window procedure.
1687 * GWL_HINSTANCE The window's pplication instance handle.
1689 * GWL_ID The window's identifier.
1691 * GWL_USERDATA The window's user-specified data.
1693 * If the window is a dialog box, the _offset_ parameter can be one of
1694 * the following values:
1696 * DWL_DLGPROC The address of the window's dialog box procedure.
1698 * DWL_MSGRESULT The return value of a message
1699 * that the dialog box procedure processed.
1701 * DWL_USER Application specific information.
1705 * If successful, returns the previous value located at _offset_. Otherwise,
1710 * Extra memory for a window class is specified by a nonzero cbWndExtra
1711 * parameter of the WNDCLASS structure passed to RegisterClass() at the
1712 * time of class creation.
1714 * Using GWL_WNDPROC to set a new window procedure effectively creates
1715 * a window subclass. Use CallWindowProc() in the new windows procedure
1716 * to pass messages to the superclass's window procedure.
1718 * The user data is reserved for use by the application which created
1721 * Do not use GWL_STYLE to change the window's WS_DISABLE style;
1722 * instead, call the EnableWindow() function to change the window's
1725 * Do not use GWL_HWNDPARENT to reset the window's parent, use
1726 * SetParent() instead.
1729 * When offset is GWL_STYLE and the calling app's ver is 4.0,
1730 * it sends WM_STYLECHANGING before changing the settings
1731 * and WM_STYLECHANGED afterwards.
1732 * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
1736 * GWL_STYLE does not dispatch WM_STYLE... messages.
1743 LONG WINAPI SetWindowLong32W(
1744 HWND32 hwnd, /* window to alter */
1745 INT32 offset, /* offset, in bytes, of location to alter */
1746 LONG newval /* new value of location */
1748 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1752 /*******************************************************************
1753 * GetWindowText16 (USER.36)
1755 INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1757 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1761 /*******************************************************************
1762 * GetWindowText32A (USER32.309)
1764 INT32 WINAPI GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1766 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1770 /*******************************************************************
1771 * InternalGetWindowText (USER32.326)
1773 INT32 WINAPI InternalGetWindowText(HWND32 hwnd,LPWSTR lpString,INT32 nMaxCount )
1775 FIXME(win,"(0x%08x,%p,0x%x),stub!\n",hwnd,lpString,nMaxCount);
1776 return GetWindowText32W(hwnd,lpString,nMaxCount);
1780 /*******************************************************************
1781 * GetWindowText32W (USER32.312)
1783 INT32 WINAPI GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1785 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1790 /*******************************************************************
1791 * SetWindowText16 (USER.37)
1793 BOOL16 WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1795 return (BOOL16)SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1799 /*******************************************************************
1800 * SetWindowText32A (USER32.521)
1802 BOOL32 WINAPI SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1804 return (BOOL32)SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1808 /*******************************************************************
1809 * SetWindowText32W (USER32.523)
1811 BOOL32 WINAPI SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1813 return (BOOL32)SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1817 /*******************************************************************
1818 * GetWindowTextLength16 (USER.38)
1820 INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
1822 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1826 /*******************************************************************
1827 * GetWindowTextLength32A (USER32.310)
1829 INT32 WINAPI GetWindowTextLength32A( HWND32 hwnd )
1831 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1834 /*******************************************************************
1835 * GetWindowTextLength32W (USER32.311)
1837 INT32 WINAPI GetWindowTextLength32W( HWND32 hwnd )
1839 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1843 /*******************************************************************
1844 * IsWindow16 (USER.47)
1846 BOOL16 WINAPI IsWindow16( HWND16 hwnd )
1848 return IsWindow32( hwnd );
1851 void WINAPI WIN16_IsWindow16( CONTEXT *context )
1853 WORD *stack = PTR_SEG_OFF_TO_LIN(SS_reg(context), SP_reg(context));
1854 HWND16 hwnd = (HWND16)stack[2];
1856 AX_reg(context) = IsWindow32( hwnd );
1857 ES_reg(context) = USER_HeapSel;
1861 /*******************************************************************
1862 * IsWindow32 (USER32.348)
1864 BOOL32 WINAPI IsWindow32( HWND32 hwnd )
1866 WND * wndPtr = WIN_FindWndPtr( hwnd );
1867 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1871 /*****************************************************************
1872 * GetParent16 (USER.46)
1874 HWND16 WINAPI GetParent16( HWND16 hwnd )
1876 return (HWND16)GetParent32( hwnd );
1880 /*****************************************************************
1881 * GetParent32 (USER32.278)
1883 HWND32 WINAPI GetParent32( HWND32 hwnd )
1885 WND *wndPtr = WIN_FindWndPtr(hwnd);
1886 if ((!wndPtr) || (!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD)))) return 0;
1887 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1888 return wndPtr ? wndPtr->hwndSelf : 0;
1891 /*****************************************************************
1894 * Get the top-level parent for a child window.
1896 WND* WIN_GetTopParentPtr( WND* pWnd )
1898 while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
1902 /*****************************************************************
1905 * Get the top-level parent for a child window.
1907 HWND32 WIN_GetTopParent( HWND32 hwnd )
1909 WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
1910 return wndPtr ? wndPtr->hwndSelf : 0;
1914 /*****************************************************************
1915 * SetParent16 (USER.233)
1917 HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1919 return SetParent32( hwndChild, hwndNewParent );
1923 /*****************************************************************
1924 * SetParent32 (USER32.495)
1926 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1928 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1929 WND *pWndNewParent =
1930 (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent ) : pWndDesktop;
1931 WND *pWndOldParent =
1932 (wndPtr)?(*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent):NULL;
1934 /* SetParent32 additionally needs to make hwndChild the topmost window
1935 in the x-order and send the expected WM_WINDOWPOSCHANGING and
1936 WM_WINDOWPOSCHANGED notification messages.
1938 SetWindowPos32( hwndChild, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
1940 return pWndOldParent?pWndOldParent->hwndSelf:0;
1943 /*******************************************************************
1944 * IsChild16 (USER.48)
1946 BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
1948 return IsChild32(parent,child);
1952 /*******************************************************************
1953 * IsChild32 (USER32.339)
1955 BOOL32 WINAPI IsChild32( HWND32 parent, HWND32 child )
1957 WND * wndPtr = WIN_FindWndPtr( child );
1958 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1960 wndPtr = wndPtr->parent;
1961 if (wndPtr->hwndSelf == parent) return TRUE;
1967 /***********************************************************************
1968 * IsWindowVisible16 (USER.49)
1970 BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
1972 return IsWindowVisible32(hwnd);
1976 /***********************************************************************
1977 * IsWindowVisible32 (USER32.351)
1979 BOOL32 WINAPI IsWindowVisible32( HWND32 hwnd )
1981 WND *wndPtr = WIN_FindWndPtr( hwnd );
1982 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1984 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1985 wndPtr = wndPtr->parent;
1987 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1991 /***********************************************************************
1992 * WIN_IsWindowDrawable
1994 * hwnd is drawable when it is visible, all parents are not
1995 * minimized, and it is itself not minimized unless we are
1996 * trying to draw its default class icon.
1998 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
2000 if( (wnd->dwStyle & WS_MINIMIZE &&
2001 icon && wnd->class->hIcon) ||
2002 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
2003 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
2004 if( wnd->dwStyle & WS_MINIMIZE ||
2005 !(wnd->dwStyle & WS_VISIBLE) ) break;
2006 return (wnd == NULL);
2010 /*******************************************************************
2011 * GetTopWindow16 (USER.229)
2013 HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
2015 return GetTopWindow32(hwnd);
2019 /*******************************************************************
2020 * GetTopWindow32 (USER.229)
2022 HWND32 WINAPI GetTopWindow32( HWND32 hwnd )
2024 WND * wndPtr = WIN_FindWndPtr( hwnd );
2025 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
2030 /*******************************************************************
2031 * GetWindow16 (USER.262)
2033 HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
2035 return GetWindow32( hwnd,rel );
2039 /*******************************************************************
2040 * GetWindow32 (USER32.302)
2042 HWND32 WINAPI GetWindow32( HWND32 hwnd, WORD rel )
2044 WND * wndPtr = WIN_FindWndPtr( hwnd );
2045 if (!wndPtr) return 0;
2049 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
2053 if (!wndPtr->parent) return 0; /* Desktop window */
2054 while (wndPtr->next) wndPtr = wndPtr->next;
2055 return wndPtr->hwndSelf;
2058 if (!wndPtr->next) return 0;
2059 return wndPtr->next->hwndSelf;
2062 if (!wndPtr->parent) return 0; /* Desktop window */
2063 wndPtr = wndPtr->parent->child; /* First sibling */
2064 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
2065 while (wndPtr->next)
2067 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
2068 wndPtr = wndPtr->next;
2073 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
2076 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
2082 /*******************************************************************
2083 * GetNextWindow16 (USER.230)
2085 HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
2087 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
2088 return GetWindow16( hwnd, flag );
2091 /*******************************************************************
2092 * ShowOwnedPopups16 (USER.265)
2094 void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
2096 ShowOwnedPopups32( owner, fShow );
2100 /*******************************************************************
2101 * ShowOwnedPopups32 (USER32.531)
2103 BOOL32 WINAPI ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
2105 WND *pWnd = pWndDesktop->child;
2108 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
2109 (pWnd->dwStyle & WS_POPUP))
2110 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
2117 /*******************************************************************
2118 * GetLastActivePopup16 (USER.287)
2120 HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
2122 return GetLastActivePopup32( hwnd );
2125 /*******************************************************************
2126 * GetLastActivePopup32 (USER32.256)
2128 HWND32 WINAPI GetLastActivePopup32( HWND32 hwnd )
2131 wndPtr = WIN_FindWndPtr(hwnd);
2132 if (wndPtr == NULL) return hwnd;
2133 return wndPtr->hwndLastActive;
2137 /*******************************************************************
2140 * Build an array of pointers to the children of a given window.
2141 * The array must be freed with HeapFree(SystemHeap). Return NULL
2142 * when no windows are found.
2144 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
2146 WND **list, **ppWnd;
2148 UINT32 count, skipOwned, skipHidden;
2151 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2152 skipOwned = bwaFlags & BWA_SKIPOWNED;
2153 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2154 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
2156 /* First count the windows */
2158 if (!wndPtr) wndPtr = pWndDesktop;
2159 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
2161 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2162 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
2167 /* Now build the list of all windows */
2169 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
2171 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
2173 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2174 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2185 if( pTotal ) *pTotal = count;
2190 /*******************************************************************
2191 * EnumWindows16 (USER.54)
2193 BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2195 WND **list, **ppWnd;
2197 /* We have to build a list of all windows first, to avoid */
2198 /* unpleasant side-effects, for instance if the callback */
2199 /* function changes the Z-order of the windows. */
2201 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2203 /* Now call the callback function for every window */
2205 for (ppWnd = list; *ppWnd; ppWnd++)
2207 /* Make sure that the window still exists */
2208 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2209 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2211 HeapFree( SystemHeap, 0, list );
2216 /*******************************************************************
2217 * EnumWindows32 (USER32.193)
2219 BOOL32 WINAPI EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2221 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2225 /**********************************************************************
2226 * EnumTaskWindows16 (USER.225)
2228 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2231 WND **list, **ppWnd;
2233 /* This function is the same as EnumWindows(), */
2234 /* except for an added check on the window's task. */
2236 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2238 /* Now call the callback function for every window */
2240 for (ppWnd = list; *ppWnd; ppWnd++)
2242 /* Make sure that the window still exists */
2243 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2244 if (QUEUE_GetQueueTask((*ppWnd)->hmemTaskQ) != hTask) continue;
2245 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2247 HeapFree( SystemHeap, 0, list );
2252 /**********************************************************************
2253 * EnumThreadWindows (USER32.190)
2255 BOOL32 WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2257 THDB *tdb = THREAD_ID_TO_THDB(id);
2259 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2263 /**********************************************************************
2264 * WIN_EnumChildWindows
2266 * Helper function for EnumChildWindows().
2268 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2274 for ( ; *ppWnd; ppWnd++)
2276 /* Make sure that the window still exists */
2277 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2278 /* Build children list first */
2279 childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
2280 ret = func( (*ppWnd)->hwndSelf, lParam );
2283 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
2284 HeapFree( SystemHeap, 0, childList );
2286 if (!ret) return FALSE;
2292 /**********************************************************************
2293 * EnumChildWindows16 (USER.55)
2295 BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2298 WND **list, *pParent;
2300 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2301 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2302 WIN_EnumChildWindows( list, func, lParam );
2303 HeapFree( SystemHeap, 0, list );
2308 /**********************************************************************
2309 * EnumChildWindows32 (USER32.178)
2311 BOOL32 WINAPI EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
2314 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2319 /*******************************************************************
2320 * AnyPopup16 (USER.52)
2322 BOOL16 WINAPI AnyPopup16(void)
2324 return AnyPopup32();
2328 /*******************************************************************
2329 * AnyPopup32 (USER32.4)
2331 BOOL32 WINAPI AnyPopup32(void)
2334 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2335 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2340 /*******************************************************************
2341 * FlashWindow16 (USER.105)
2343 BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2345 return FlashWindow32( hWnd, bInvert );
2349 /*******************************************************************
2350 * FlashWindow32 (USER32.202)
2352 BOOL32 WINAPI FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2354 WND *wndPtr = WIN_FindWndPtr(hWnd);
2356 TRACE(win,"%04x\n", hWnd);
2358 if (!wndPtr) return FALSE;
2360 if (wndPtr->dwStyle & WS_MINIMIZE)
2362 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2364 HDC32 hDC = GetDC32(hWnd);
2366 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2367 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2369 ReleaseDC32( hWnd, hDC );
2370 wndPtr->flags |= WIN_NCACTIVATED;
2374 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2375 RDW_UPDATENOW | RDW_FRAME, 0 );
2376 wndPtr->flags &= ~WIN_NCACTIVATED;
2383 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2384 else wparam = (hWnd == GetActiveWindow32());
2386 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2392 /*******************************************************************
2393 * SetSysModalWindow16 (USER.188)
2395 HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
2397 HWND32 hWndOldModal = hwndSysModal;
2398 hwndSysModal = hWnd;
2399 FIXME(win, "EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2400 return hWndOldModal;
2404 /*******************************************************************
2405 * GetSysModalWindow16 (USER.52)
2407 HWND16 WINAPI GetSysModalWindow16(void)
2409 return hwndSysModal;
2413 /*******************************************************************
2414 * GetWindowContextHelpId (USER32.303)
2416 DWORD WINAPI GetWindowContextHelpId( HWND32 hwnd )
2418 WND *wnd = WIN_FindWndPtr( hwnd );
2420 return wnd->helpContext;
2424 /*******************************************************************
2425 * SetWindowContextHelpId (USER32.515)
2427 BOOL32 WINAPI SetWindowContextHelpId( HWND32 hwnd, DWORD id )
2429 WND *wnd = WIN_FindWndPtr( hwnd );
2430 if (!wnd) return FALSE;
2431 wnd->helpContext = id;
2436 /*******************************************************************
2439 * recursively find a child that contains spDragInfo->pt point
2440 * and send WM_QUERYDROPOBJECT
2442 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2444 BOOL16 wParam,bResult = 0;
2446 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2447 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2450 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2452 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2454 GetWindowRect32(hQueryWnd,&tempRect);
2456 if( !PtInRect32(&tempRect,pt) ||
2457 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2460 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2462 tempRect = ptrQueryWnd->rectClient;
2463 if(ptrQueryWnd->dwStyle & WS_CHILD)
2464 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2465 (LPPOINT32)&tempRect, 2 );
2467 if (PtInRect32( &tempRect, pt))
2471 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2472 if( ptrWnd->dwStyle & WS_VISIBLE )
2474 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2475 if (PtInRect32( &tempRect, pt )) break;
2480 TRACE(msg,"hwnd = %04x, %d %d - %d %d\n",
2481 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2482 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2483 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2484 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2487 if(bResult) return bResult;
2493 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2495 ptrDragInfo->hScope = hQueryWnd;
2497 bResult = ( bNoSend )
2498 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2499 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2500 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2502 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2508 /*******************************************************************
2509 * DragDetect (USER.465)
2511 BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
2514 CONV_POINT16TO32( &pt, &pt32 );
2515 return DragDetect32( hWnd, pt32 );
2518 /*******************************************************************
2519 * DragDetect32 (USER32.151)
2521 BOOL32 WINAPI DragDetect32( HWND32 hWnd, POINT32 pt )
2526 rect.left = pt.x - wDragWidth;
2527 rect.right = pt.x + wDragWidth;
2529 rect.top = pt.y - wDragHeight;
2530 rect.bottom = pt.y + wDragHeight;
2536 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2538 if( msg.message == WM_LBUTTONUP )
2543 if( msg.message == WM_MOUSEMOVE )
2545 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2557 /******************************************************************************
2558 * DragObject16 (USER.464)
2560 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2561 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2564 LPDRAGINFO lpDragInfo;
2566 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2567 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2568 WND *wndPtr = WIN_FindWndPtr(hWnd);
2569 HCURSOR16 hCurrentCursor = 0;
2570 HWND16 hCurrentWnd = 0;
2572 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2573 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2575 if( !lpDragInfo || !spDragInfo ) return 0L;
2577 hBummer = LoadCursor16(0, IDC_BUMMER16);
2579 if( !hBummer || !wndPtr )
2581 GlobalFree16(hDragInfo);
2587 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2589 GlobalFree16(hDragInfo);
2593 if( hDragCursor == hCursor ) hDragCursor = 0;
2594 else hCursor = hDragCursor;
2596 hOldCursor = SetCursor32(hDragCursor);
2599 lpDragInfo->hWnd = hWnd;
2600 lpDragInfo->hScope = 0;
2601 lpDragInfo->wFlags = wObj;
2602 lpDragInfo->hList = szList; /* near pointer! */
2603 lpDragInfo->hOfStruct = hOfStruct;
2607 ShowCursor32( TRUE );
2611 do{ WaitMessage(); }
2612 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2614 *(lpDragInfo+1) = *lpDragInfo;
2616 lpDragInfo->pt = msg.pt;
2618 /* update DRAGINFO struct */
2619 TRACE(msg,"lpDI->hScope = %04x\n",lpDragInfo->hScope);
2621 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2622 hCurrentCursor = hCursor;
2625 hCurrentCursor = hBummer;
2626 lpDragInfo->hScope = 0;
2628 if( hCurrentCursor )
2629 SetCursor32(hCurrentCursor);
2631 /* send WM_DRAGLOOP */
2632 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2633 (LPARAM) spDragInfo );
2634 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2635 if( hCurrentWnd != lpDragInfo->hScope )
2638 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2639 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2640 HIWORD(spDragInfo)) );
2641 hCurrentWnd = lpDragInfo->hScope;
2643 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2647 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2649 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2652 ShowCursor32( FALSE );
2656 SetCursor32( hOldCursor );
2657 if (hDragCursor) DestroyCursor32( hDragCursor );
2660 if( hCurrentCursor != hBummer )
2661 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2662 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2665 GlobalFree16(hDragInfo);
2667 return (DWORD)(msg.lParam);