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( wndPtr );
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 TRACE(win,"EnableWindow32: ( %x, %d )\n", hwnd, enable);
1327 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1328 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1331 wndPtr->dwStyle &= ~WS_DISABLED;
1332 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1335 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1337 /* Disable window */
1338 wndPtr->dwStyle |= WS_DISABLED;
1339 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1341 SetFocus32( 0 ); /* A disabled window can't have the focus */
1343 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1345 ReleaseCapture(); /* A disabled window can't capture the mouse */
1347 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1350 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1354 /***********************************************************************
1355 * IsWindowEnabled16 (USER.35)
1357 BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
1359 return IsWindowEnabled32(hWnd);
1363 /***********************************************************************
1364 * IsWindowEnabled32 (USER32.349)
1366 BOOL32 WINAPI IsWindowEnabled32(HWND32 hWnd)
1370 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1371 return !(wndPtr->dwStyle & WS_DISABLED);
1375 /***********************************************************************
1376 * IsWindowUnicode (USER32.350)
1378 BOOL32 WINAPI IsWindowUnicode( HWND32 hwnd )
1382 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1383 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1387 /**********************************************************************
1388 * GetWindowWord16 (USER.133)
1390 WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
1392 return GetWindowWord32( hwnd, offset );
1396 /**********************************************************************
1397 * GetWindowWord32 (USER32.314)
1399 WORD WINAPI GetWindowWord32( HWND32 hwnd, INT32 offset )
1401 WND * wndPtr = WIN_FindWndPtr( hwnd );
1402 if (!wndPtr) return 0;
1405 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1407 WARN( win, "Invalid offset %d\n", offset );
1410 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1415 if (HIWORD(wndPtr->wIDmenu))
1416 WARN( win,"GWW_ID: discards high bits of 0x%08x!\n",
1418 return (WORD)wndPtr->wIDmenu;
1419 case GWW_HWNDPARENT:
1420 return wndPtr->parent ?
1421 wndPtr->parent->hwndSelf : (
1423 wndPtr->owner->hwndSelf :
1426 if (HIWORD(wndPtr->hInstance))
1427 WARN(win,"GWW_HINSTANCE: discards high bits of 0x%08x!\n",
1429 return (WORD)wndPtr->hInstance;
1431 WARN( win, "Invalid offset %d\n", offset );
1437 /**********************************************************************
1438 * WIN_GetWindowInstance
1440 HINSTANCE32 WIN_GetWindowInstance( HWND32 hwnd )
1442 WND * wndPtr = WIN_FindWndPtr( hwnd );
1443 if (!wndPtr) return (HINSTANCE32)0;
1444 return wndPtr->hInstance;
1448 /**********************************************************************
1449 * SetWindowWord16 (USER.134)
1451 WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1453 return SetWindowWord32( hwnd, offset, newval );
1457 /**********************************************************************
1458 * SetWindowWord32 (USER32.524)
1460 WORD WINAPI SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1463 WND * wndPtr = WIN_FindWndPtr( hwnd );
1464 if (!wndPtr) return 0;
1467 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1469 WARN( win, "Invalid offset %d\n", offset );
1472 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1476 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1477 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1478 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1480 WARN( win, "Invalid offset %d\n", offset );
1489 /**********************************************************************
1492 * Helper function for GetWindowLong().
1494 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1497 WND * wndPtr = WIN_FindWndPtr( hwnd );
1498 if (!wndPtr) return 0;
1501 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1503 WARN( win, "Invalid offset %d\n", offset );
1506 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1507 /* Special case for dialog window procedure */
1508 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1509 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1514 case GWL_USERDATA: return wndPtr->userdata;
1515 case GWL_STYLE: return wndPtr->dwStyle;
1516 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1517 case GWL_ID: return (LONG)wndPtr->wIDmenu;
1518 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1520 case GWL_HWNDPARENT: return wndPtr->parent ?
1521 (HWND32)wndPtr->parent->hwndSelf : 0;
1522 case GWL_HINSTANCE: return wndPtr->hInstance;
1524 WARN( win, "Unknown offset %d\n", offset );
1530 /**********************************************************************
1533 * Helper function for SetWindowLong().
1535 * 0 is the failure code. However, in the case of failure SetLastError
1536 * must be set to distinguish between a 0 return value and a failure.
1538 * FIXME: The error values for SetLastError may not be right. Can
1539 * someone check with the real thing?
1541 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1542 WINDOWPROCTYPE type )
1545 WND * wndPtr = WIN_FindWndPtr( hwnd );
1548 TRACE(win,"%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
1552 /* Is this the right error? */
1553 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1559 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1561 WARN( win, "Invalid offset %d\n", offset );
1563 /* Is this the right error? */
1564 SetLastError( ERROR_OUTOFMEMORY );
1568 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1569 /* Special case for dialog window procedure */
1570 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1572 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1573 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1574 type, WIN_PROC_WINDOW );
1581 ptr = (DWORD*)&wndPtr->wIDmenu;
1584 return SetWindowWord32( hwnd, offset, newval );
1586 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1587 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1588 type, WIN_PROC_WINDOW );
1591 style.styleOld = wndPtr->dwStyle;
1592 newval &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way */
1593 style.styleNew = newval | (style.styleOld & (WS_VISIBLE | WS_CHILD));
1595 if (wndPtr->flags & WIN_ISWIN32)
1596 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
1597 wndPtr->dwStyle = style.styleNew;
1598 if (wndPtr->flags & WIN_ISWIN32)
1599 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
1600 return style.styleOld;
1603 ptr = &wndPtr->userdata;
1606 style.styleOld = wndPtr->dwExStyle;
1607 style.styleNew = newval;
1608 if (wndPtr->flags & WIN_ISWIN32)
1609 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
1610 wndPtr->dwExStyle = newval;
1611 if (wndPtr->flags & WIN_ISWIN32)
1612 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
1613 return style.styleOld;
1616 WARN( win, "Invalid offset %d\n", offset );
1618 /* Don't think this is right error but it should do */
1619 SetLastError( ERROR_OUTOFMEMORY );
1629 /**********************************************************************
1630 * GetWindowLong16 (USER.135)
1632 LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
1634 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1638 /**********************************************************************
1639 * GetWindowLong32A (USER32.305)
1641 LONG WINAPI GetWindowLong32A( HWND32 hwnd, INT32 offset )
1643 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1647 /**********************************************************************
1648 * GetWindowLong32W (USER32.306)
1650 LONG WINAPI GetWindowLong32W( HWND32 hwnd, INT32 offset )
1652 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1656 /**********************************************************************
1657 * SetWindowLong16 (USER.136)
1659 LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1661 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1665 /**********************************************************************
1666 * SetWindowLong32A (USER32.517)
1668 LONG WINAPI SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1670 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1674 /**********************************************************************
1675 * SetWindowLong32W (USER32.518) Set window attribute
1677 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
1678 * value in a window's extra memory.
1680 * The _hwnd_ parameter specifies the window. is the handle to a
1681 * window that has extra memory. The _newval_ parameter contains the
1682 * new attribute or extra memory value. If positive, the _offset_
1683 * parameter is the byte-addressed location in the window's extra
1684 * memory to set. If negative, _offset_ specifies the window
1685 * attribute to set, and should be one of the following values:
1687 * GWL_EXSTYLE The window's extended window style
1689 * GWL_STYLE The window's window style.
1691 * GWL_WNDPROC Pointer to the window's window procedure.
1693 * GWL_HINSTANCE The window's pplication instance handle.
1695 * GWL_ID The window's identifier.
1697 * GWL_USERDATA The window's user-specified data.
1699 * If the window is a dialog box, the _offset_ parameter can be one of
1700 * the following values:
1702 * DWL_DLGPROC The address of the window's dialog box procedure.
1704 * DWL_MSGRESULT The return value of a message
1705 * that the dialog box procedure processed.
1707 * DWL_USER Application specific information.
1711 * If successful, returns the previous value located at _offset_. Otherwise,
1716 * Extra memory for a window class is specified by a nonzero cbWndExtra
1717 * parameter of the WNDCLASS structure passed to RegisterClass() at the
1718 * time of class creation.
1720 * Using GWL_WNDPROC to set a new window procedure effectively creates
1721 * a window subclass. Use CallWindowProc() in the new windows procedure
1722 * to pass messages to the superclass's window procedure.
1724 * The user data is reserved for use by the application which created
1727 * Do not use GWL_STYLE to change the window's WS_DISABLE style;
1728 * instead, call the EnableWindow() function to change the window's
1731 * Do not use GWL_HWNDPARENT to reset the window's parent, use
1732 * SetParent() instead.
1735 * When offset is GWL_STYLE and the calling app's ver is 4.0,
1736 * it sends WM_STYLECHANGING before changing the settings
1737 * and WM_STYLECHANGED afterwards.
1738 * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
1742 * GWL_STYLE does not dispatch WM_STYLE... messages.
1749 LONG WINAPI SetWindowLong32W(
1750 HWND32 hwnd, /* window to alter */
1751 INT32 offset, /* offset, in bytes, of location to alter */
1752 LONG newval /* new value of location */
1754 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1758 /*******************************************************************
1759 * GetWindowText16 (USER.36)
1761 INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1763 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1767 /*******************************************************************
1768 * GetWindowText32A (USER32.309)
1770 INT32 WINAPI GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1772 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1776 /*******************************************************************
1777 * InternalGetWindowText (USER32.326)
1779 INT32 WINAPI InternalGetWindowText(HWND32 hwnd,LPWSTR lpString,INT32 nMaxCount )
1781 FIXME(win,"(0x%08x,%p,0x%x),stub!\n",hwnd,lpString,nMaxCount);
1782 return GetWindowText32W(hwnd,lpString,nMaxCount);
1786 /*******************************************************************
1787 * GetWindowText32W (USER32.312)
1789 INT32 WINAPI GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1791 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1796 /*******************************************************************
1797 * SetWindowText16 (USER.37)
1799 BOOL16 WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1801 return (BOOL16)SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1805 /*******************************************************************
1806 * SetWindowText32A (USER32.521)
1808 BOOL32 WINAPI SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1810 return (BOOL32)SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1814 /*******************************************************************
1815 * SetWindowText32W (USER32.523)
1817 BOOL32 WINAPI SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1819 return (BOOL32)SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1823 /*******************************************************************
1824 * GetWindowTextLength16 (USER.38)
1826 INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
1828 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1832 /*******************************************************************
1833 * GetWindowTextLength32A (USER32.310)
1835 INT32 WINAPI GetWindowTextLength32A( HWND32 hwnd )
1837 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1840 /*******************************************************************
1841 * GetWindowTextLength32W (USER32.311)
1843 INT32 WINAPI GetWindowTextLength32W( HWND32 hwnd )
1845 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1849 /*******************************************************************
1850 * IsWindow16 (USER.47)
1852 BOOL16 WINAPI IsWindow16( HWND16 hwnd )
1854 return IsWindow32( hwnd );
1857 void WINAPI WIN16_IsWindow16( CONTEXT *context )
1859 WORD *stack = PTR_SEG_OFF_TO_LIN(SS_reg(context), SP_reg(context));
1860 HWND16 hwnd = (HWND16)stack[2];
1862 AX_reg(context) = IsWindow32( hwnd );
1863 ES_reg(context) = USER_HeapSel;
1867 /*******************************************************************
1868 * IsWindow32 (USER32.348)
1870 BOOL32 WINAPI IsWindow32( HWND32 hwnd )
1872 WND * wndPtr = WIN_FindWndPtr( hwnd );
1873 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1877 /*****************************************************************
1878 * GetParent16 (USER.46)
1880 HWND16 WINAPI GetParent16( HWND16 hwnd )
1882 return (HWND16)GetParent32( hwnd );
1886 /*****************************************************************
1887 * GetParent32 (USER32.278)
1889 HWND32 WINAPI GetParent32( HWND32 hwnd )
1891 WND *wndPtr = WIN_FindWndPtr(hwnd);
1892 if ((!wndPtr) || (!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD)))) return 0;
1893 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1894 return wndPtr ? wndPtr->hwndSelf : 0;
1897 /*****************************************************************
1900 * Get the top-level parent for a child window.
1902 WND* WIN_GetTopParentPtr( WND* pWnd )
1904 while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
1908 /*****************************************************************
1911 * Get the top-level parent for a child window.
1913 HWND32 WIN_GetTopParent( HWND32 hwnd )
1915 WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
1916 return wndPtr ? wndPtr->hwndSelf : 0;
1920 /*****************************************************************
1921 * SetParent16 (USER.233)
1923 HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1925 return SetParent32( hwndChild, hwndNewParent );
1929 /*****************************************************************
1930 * SetParent32 (USER32.495)
1932 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1934 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1935 WND *pWndNewParent =
1936 (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent ) : pWndDesktop;
1937 WND *pWndOldParent =
1938 (wndPtr)?(*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent):NULL;
1940 /* SetParent32 additionally needs to make hwndChild the topmost window
1941 in the x-order and send the expected WM_WINDOWPOSCHANGING and
1942 WM_WINDOWPOSCHANGED notification messages.
1944 SetWindowPos32( hwndChild, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
1946 return pWndOldParent?pWndOldParent->hwndSelf:0;
1949 /*******************************************************************
1950 * IsChild16 (USER.48)
1952 BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
1954 return IsChild32(parent,child);
1958 /*******************************************************************
1959 * IsChild32 (USER32.339)
1961 BOOL32 WINAPI IsChild32( HWND32 parent, HWND32 child )
1963 WND * wndPtr = WIN_FindWndPtr( child );
1964 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1966 wndPtr = wndPtr->parent;
1967 if (wndPtr->hwndSelf == parent) return TRUE;
1973 /***********************************************************************
1974 * IsWindowVisible16 (USER.49)
1976 BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
1978 return IsWindowVisible32(hwnd);
1982 /***********************************************************************
1983 * IsWindowVisible32 (USER32.351)
1985 BOOL32 WINAPI IsWindowVisible32( HWND32 hwnd )
1987 WND *wndPtr = WIN_FindWndPtr( hwnd );
1988 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1990 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1991 wndPtr = wndPtr->parent;
1993 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1997 /***********************************************************************
1998 * WIN_IsWindowDrawable
2000 * hwnd is drawable when it is visible, all parents are not
2001 * minimized, and it is itself not minimized unless we are
2002 * trying to draw its default class icon.
2004 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
2006 if( (wnd->dwStyle & WS_MINIMIZE &&
2007 icon && wnd->class->hIcon) ||
2008 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
2009 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
2010 if( wnd->dwStyle & WS_MINIMIZE ||
2011 !(wnd->dwStyle & WS_VISIBLE) ) break;
2012 return (wnd == NULL);
2016 /*******************************************************************
2017 * GetTopWindow16 (USER.229)
2019 HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
2021 return GetTopWindow32(hwnd);
2025 /*******************************************************************
2026 * GetTopWindow32 (USER.229)
2028 HWND32 WINAPI GetTopWindow32( HWND32 hwnd )
2030 WND * wndPtr = WIN_FindWndPtr( hwnd );
2031 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
2036 /*******************************************************************
2037 * GetWindow16 (USER.262)
2039 HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
2041 return GetWindow32( hwnd,rel );
2045 /*******************************************************************
2046 * GetWindow32 (USER32.302)
2048 HWND32 WINAPI GetWindow32( HWND32 hwnd, WORD rel )
2050 WND * wndPtr = WIN_FindWndPtr( hwnd );
2051 if (!wndPtr) return 0;
2055 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
2059 if (!wndPtr->parent) return 0; /* Desktop window */
2060 while (wndPtr->next) wndPtr = wndPtr->next;
2061 return wndPtr->hwndSelf;
2064 if (!wndPtr->next) return 0;
2065 return wndPtr->next->hwndSelf;
2068 if (!wndPtr->parent) return 0; /* Desktop window */
2069 wndPtr = wndPtr->parent->child; /* First sibling */
2070 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
2071 while (wndPtr->next)
2073 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
2074 wndPtr = wndPtr->next;
2079 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
2082 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
2088 /*******************************************************************
2089 * GetNextWindow16 (USER.230)
2091 HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
2093 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
2094 return GetWindow16( hwnd, flag );
2097 /*******************************************************************
2098 * ShowOwnedPopups16 (USER.265)
2100 void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
2102 ShowOwnedPopups32( owner, fShow );
2106 /*******************************************************************
2107 * ShowOwnedPopups32 (USER32.531)
2109 BOOL32 WINAPI ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
2111 WND *pWnd = pWndDesktop->child;
2114 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
2115 (pWnd->dwStyle & WS_POPUP))
2116 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
2123 /*******************************************************************
2124 * GetLastActivePopup16 (USER.287)
2126 HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
2128 return GetLastActivePopup32( hwnd );
2131 /*******************************************************************
2132 * GetLastActivePopup32 (USER32.256)
2134 HWND32 WINAPI GetLastActivePopup32( HWND32 hwnd )
2137 wndPtr = WIN_FindWndPtr(hwnd);
2138 if (wndPtr == NULL) return hwnd;
2139 return wndPtr->hwndLastActive;
2143 /*******************************************************************
2146 * Build an array of pointers to the children of a given window.
2147 * The array must be freed with HeapFree(SystemHeap). Return NULL
2148 * when no windows are found.
2150 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
2152 WND **list, **ppWnd;
2154 UINT32 count, skipOwned, skipHidden;
2157 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2158 skipOwned = bwaFlags & BWA_SKIPOWNED;
2159 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2160 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
2162 /* First count the windows */
2164 if (!wndPtr) wndPtr = pWndDesktop;
2165 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
2167 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2168 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
2173 /* Now build the list of all windows */
2175 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
2177 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
2179 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2180 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2191 if( pTotal ) *pTotal = count;
2196 /*******************************************************************
2197 * EnumWindows16 (USER.54)
2199 BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2201 WND **list, **ppWnd;
2203 /* We have to build a list of all windows first, to avoid */
2204 /* unpleasant side-effects, for instance if the callback */
2205 /* function changes the Z-order of the windows. */
2207 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2209 /* Now call the callback function for every window */
2211 for (ppWnd = list; *ppWnd; ppWnd++)
2213 /* Make sure that the window still exists */
2214 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2215 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2217 HeapFree( SystemHeap, 0, list );
2222 /*******************************************************************
2223 * EnumWindows32 (USER32.193)
2225 BOOL32 WINAPI EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2227 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2231 /**********************************************************************
2232 * EnumTaskWindows16 (USER.225)
2234 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2237 WND **list, **ppWnd;
2239 /* This function is the same as EnumWindows(), */
2240 /* except for an added check on the window's task. */
2242 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2244 /* Now call the callback function for every window */
2246 for (ppWnd = list; *ppWnd; ppWnd++)
2248 /* Make sure that the window still exists */
2249 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2250 if (QUEUE_GetQueueTask((*ppWnd)->hmemTaskQ) != hTask) continue;
2251 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2253 HeapFree( SystemHeap, 0, list );
2258 /**********************************************************************
2259 * EnumThreadWindows (USER32.190)
2261 BOOL32 WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2263 THDB *tdb = THREAD_ID_TO_THDB(id);
2265 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2269 /**********************************************************************
2270 * WIN_EnumChildWindows
2272 * Helper function for EnumChildWindows().
2274 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2280 for ( ; *ppWnd; ppWnd++)
2282 /* Make sure that the window still exists */
2283 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2284 /* Build children list first */
2285 childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
2286 ret = func( (*ppWnd)->hwndSelf, lParam );
2289 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
2290 HeapFree( SystemHeap, 0, childList );
2292 if (!ret) return FALSE;
2298 /**********************************************************************
2299 * EnumChildWindows16 (USER.55)
2301 BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2304 WND **list, *pParent;
2306 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2307 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2308 WIN_EnumChildWindows( list, func, lParam );
2309 HeapFree( SystemHeap, 0, list );
2314 /**********************************************************************
2315 * EnumChildWindows32 (USER32.178)
2317 BOOL32 WINAPI EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
2320 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2325 /*******************************************************************
2326 * AnyPopup16 (USER.52)
2328 BOOL16 WINAPI AnyPopup16(void)
2330 return AnyPopup32();
2334 /*******************************************************************
2335 * AnyPopup32 (USER32.4)
2337 BOOL32 WINAPI AnyPopup32(void)
2340 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2341 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2346 /*******************************************************************
2347 * FlashWindow16 (USER.105)
2349 BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2351 return FlashWindow32( hWnd, bInvert );
2355 /*******************************************************************
2356 * FlashWindow32 (USER32.202)
2358 BOOL32 WINAPI FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2360 WND *wndPtr = WIN_FindWndPtr(hWnd);
2362 TRACE(win,"%04x\n", hWnd);
2364 if (!wndPtr) return FALSE;
2366 if (wndPtr->dwStyle & WS_MINIMIZE)
2368 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2370 HDC32 hDC = GetDC32(hWnd);
2372 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2373 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2375 ReleaseDC32( hWnd, hDC );
2376 wndPtr->flags |= WIN_NCACTIVATED;
2380 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2381 RDW_UPDATENOW | RDW_FRAME, 0 );
2382 wndPtr->flags &= ~WIN_NCACTIVATED;
2389 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2390 else wparam = (hWnd == GetActiveWindow32());
2392 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2398 /*******************************************************************
2399 * SetSysModalWindow16 (USER.188)
2401 HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
2403 HWND32 hWndOldModal = hwndSysModal;
2404 hwndSysModal = hWnd;
2405 FIXME(win, "EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2406 return hWndOldModal;
2410 /*******************************************************************
2411 * GetSysModalWindow16 (USER.52)
2413 HWND16 WINAPI GetSysModalWindow16(void)
2415 return hwndSysModal;
2419 /*******************************************************************
2420 * GetWindowContextHelpId (USER32.303)
2422 DWORD WINAPI GetWindowContextHelpId( HWND32 hwnd )
2424 WND *wnd = WIN_FindWndPtr( hwnd );
2426 return wnd->helpContext;
2430 /*******************************************************************
2431 * SetWindowContextHelpId (USER32.515)
2433 BOOL32 WINAPI SetWindowContextHelpId( HWND32 hwnd, DWORD id )
2435 WND *wnd = WIN_FindWndPtr( hwnd );
2436 if (!wnd) return FALSE;
2437 wnd->helpContext = id;
2442 /*******************************************************************
2445 * recursively find a child that contains spDragInfo->pt point
2446 * and send WM_QUERYDROPOBJECT
2448 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2450 BOOL16 wParam,bResult = 0;
2452 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2453 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2456 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2458 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2460 GetWindowRect32(hQueryWnd,&tempRect);
2462 if( !PtInRect32(&tempRect,pt) ||
2463 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2466 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2468 tempRect = ptrQueryWnd->rectClient;
2469 if(ptrQueryWnd->dwStyle & WS_CHILD)
2470 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2471 (LPPOINT32)&tempRect, 2 );
2473 if (PtInRect32( &tempRect, pt))
2477 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2478 if( ptrWnd->dwStyle & WS_VISIBLE )
2480 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2481 if (PtInRect32( &tempRect, pt )) break;
2486 TRACE(msg,"hwnd = %04x, %d %d - %d %d\n",
2487 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2488 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2489 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2490 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2493 if(bResult) return bResult;
2499 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2501 ptrDragInfo->hScope = hQueryWnd;
2503 bResult = ( bNoSend )
2504 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2505 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2506 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2508 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2514 /*******************************************************************
2515 * DragDetect (USER.465)
2517 BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
2520 CONV_POINT16TO32( &pt, &pt32 );
2521 return DragDetect32( hWnd, pt32 );
2524 /*******************************************************************
2525 * DragDetect32 (USER32.151)
2527 BOOL32 WINAPI DragDetect32( HWND32 hWnd, POINT32 pt )
2532 rect.left = pt.x - wDragWidth;
2533 rect.right = pt.x + wDragWidth;
2535 rect.top = pt.y - wDragHeight;
2536 rect.bottom = pt.y + wDragHeight;
2542 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2544 if( msg.message == WM_LBUTTONUP )
2549 if( msg.message == WM_MOUSEMOVE )
2551 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2563 /******************************************************************************
2564 * DragObject16 (USER.464)
2566 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2567 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2570 LPDRAGINFO lpDragInfo;
2572 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2573 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2574 WND *wndPtr = WIN_FindWndPtr(hWnd);
2575 HCURSOR16 hCurrentCursor = 0;
2576 HWND16 hCurrentWnd = 0;
2578 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2579 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2581 if( !lpDragInfo || !spDragInfo ) return 0L;
2583 hBummer = LoadCursor16(0, IDC_BUMMER16);
2585 if( !hBummer || !wndPtr )
2587 GlobalFree16(hDragInfo);
2593 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2595 GlobalFree16(hDragInfo);
2599 if( hDragCursor == hCursor ) hDragCursor = 0;
2600 else hCursor = hDragCursor;
2602 hOldCursor = SetCursor32(hDragCursor);
2605 lpDragInfo->hWnd = hWnd;
2606 lpDragInfo->hScope = 0;
2607 lpDragInfo->wFlags = wObj;
2608 lpDragInfo->hList = szList; /* near pointer! */
2609 lpDragInfo->hOfStruct = hOfStruct;
2613 ShowCursor32( TRUE );
2617 do{ WaitMessage(); }
2618 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2620 *(lpDragInfo+1) = *lpDragInfo;
2622 lpDragInfo->pt = msg.pt;
2624 /* update DRAGINFO struct */
2625 TRACE(msg,"lpDI->hScope = %04x\n",lpDragInfo->hScope);
2627 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2628 hCurrentCursor = hCursor;
2631 hCurrentCursor = hBummer;
2632 lpDragInfo->hScope = 0;
2634 if( hCurrentCursor )
2635 SetCursor32(hCurrentCursor);
2637 /* send WM_DRAGLOOP */
2638 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2639 (LPARAM) spDragInfo );
2640 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2641 if( hCurrentWnd != lpDragInfo->hScope )
2644 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2645 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2646 HIWORD(spDragInfo)) );
2647 hCurrentWnd = lpDragInfo->hScope;
2649 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2653 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2655 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2658 ShowCursor32( FALSE );
2662 SetCursor32( hOldCursor );
2663 if (hDragCursor) DestroyCursor32( hDragCursor );
2666 if( hCurrentCursor != hBummer )
2667 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2668 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2671 GlobalFree16(hDragInfo);
2673 return (DWORD)(msg.lParam);