2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
11 #include "wine/winbase16.h"
18 #include "sysmetrics.h"
19 #include "cursoricon.h"
24 #include "nonclient.h"
27 #include "shm_main_blk.h"
29 #include "clipboard.h"
40 #ifndef X_DISPLAY_MISSING
41 extern DESKTOP_DRIVER X11DRV_DESKTOP_Driver;
42 extern WND_DRIVER X11DRV_WND_Driver;
43 #else /* X_DISPLAY_MISSING */
44 extern DESKTOP_DRIVER TTYDRV_DESKTOP_Driver;
45 extern WND_DRIVER TTYDRV_WND_Driver;
46 #endif /* X_DISPLAY_MISSING */
49 static WND *pWndDesktop = NULL;
51 static HWND32 hwndSysModal = 0;
53 static WORD wDragWidth = 4;
54 static WORD wDragHeight= 3;
56 /***********************************************************************
59 * Return a pointer to the WND structure corresponding to a HWND.
61 WND * WIN_FindWndPtr( HWND32 hwnd )
65 if (!hwnd || HIWORD(hwnd)) goto error;
66 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
67 if (ptr->dwMagic != WND_MAGIC) goto error;
68 if (ptr->hwndSelf != hwnd)
70 ERR( win, "Can't happen: hwnd %04x self pointer is %04x\n",
71 hwnd, ptr->hwndSelf );
76 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
81 /***********************************************************************
84 * Dump the content of a window structure to stderr.
86 void WIN_DumpWindow( HWND32 hwnd )
92 if (!(ptr = WIN_FindWndPtr( hwnd )))
94 WARN( win, "%04x is not a window handle\n", hwnd );
98 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
99 strcpy( className, "#NULL#" );
101 TRACE( win, "Window %04x (%p):\n", hwnd, ptr );
102 DUMP( "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
103 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
104 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
105 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
106 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
107 ptr->next, ptr->child, ptr->parent, ptr->owner,
108 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
109 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
110 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
111 ptr->text ? ptr->text : "",
112 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
113 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
114 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
115 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
117 if (ptr->class->cbWndExtra)
119 DUMP( "extra bytes:" );
120 for (i = 0; i < ptr->class->cbWndExtra; i++)
121 DUMP( " %02x", *((BYTE*)ptr->wExtra+i) );
128 /***********************************************************************
131 * Walk the windows tree and print each window on stderr.
133 void WIN_WalkWindows( HWND32 hwnd, int indent )
138 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
141 WARN( win, "Invalid window handle %04x\n", hwnd );
145 if (!indent) /* first time around */
146 DUMP( "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
147 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc"
152 DUMP( "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
154 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
156 DUMP( "%08lx %-6.4x %-17.17s %08x %08x %.14s\n",
157 (DWORD)ptr, ptr->hmemTaskQ, className,
158 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc,
159 ptr->text?ptr->text:"<null>");
161 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
166 /***********************************************************************
169 * Remove a window from the siblings linked list.
171 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
173 WND *wndPtr, **ppWnd;
175 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
176 ppWnd = &wndPtr->parent->child;
177 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
178 *ppWnd = wndPtr->next;
183 /***********************************************************************
186 * Insert a window into the siblings linked list.
187 * The window is inserted after the specified window, which can also
188 * be specified as HWND_TOP or HWND_BOTTOM.
190 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
192 WND *wndPtr, **ppWnd;
194 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
196 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
198 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
199 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
200 while (*ppWnd) ppWnd = &(*ppWnd)->next;
202 else /* Normal case */
204 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
205 if (!afterPtr) return FALSE;
206 ppWnd = &afterPtr->next;
208 wndPtr->next = *ppWnd;
214 /***********************************************************************
215 * WIN_FindWinToRepaint
217 * Find a window that needs repaint.
219 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
222 WND *pWnd = pWndDesktop;
224 /* Note: the desktop window never gets WM_PAINT messages
225 * The real reason why is because Windows DesktopWndProc
226 * does ValidateRgn inside WM_ERASEBKGND handler.
229 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
231 for ( ; pWnd ; pWnd = pWnd->next )
233 if (!(pWnd->dwStyle & WS_VISIBLE))
235 TRACE(win, "skipping window %04x\n",
239 if ((pWnd->hmemTaskQ == hQueue) &&
240 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
243 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
249 hwndRet = pWnd->hwndSelf;
251 /* look among siblings if we got a transparent window */
252 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
253 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
257 if (pWnd) hwndRet = pWnd->hwndSelf;
258 TRACE(win,"found %04x\n",hwndRet);
263 /***********************************************************************
266 * Destroy storage associated to a window. "Internals" p.358
268 static WND* WIN_DestroyWindow( WND* wndPtr )
270 HWND32 hwnd = wndPtr->hwndSelf;
273 TRACE(win, "%04x\n", wndPtr->hwndSelf );
277 DDE_DestroyWindow(wndPtr->hwndSelf);
278 #endif /* CONFIG_IPC */
280 /* free child windows */
282 while ((pWnd = wndPtr->child))
283 wndPtr->child = WIN_DestroyWindow( pWnd );
285 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
287 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
289 WINPOS_CheckInternalPos( wndPtr );
290 if( hwnd == GetCapture32()) ReleaseCapture();
292 /* free resources associated with the window */
294 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
295 PROPERTY_RemoveWindowProps( wndPtr );
297 wndPtr->dwMagic = 0; /* Mark it as invalid */
299 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
301 if (wndPtr->hrgnUpdate > 1) DeleteObject32( wndPtr->hrgnUpdate );
302 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
305 /* toss stale messages from the queue */
307 if( wndPtr->hmemTaskQ )
309 BOOL32 bPostQuit = FALSE;
310 WPARAM32 wQuitParam = 0;
311 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) QUEUE_Lock(wndPtr->hmemTaskQ);
314 while( (qmsg = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != 0 )
316 if( qmsg->msg.message == WM_QUIT )
319 wQuitParam = qmsg->msg.wParam;
321 QUEUE_RemoveMsg(msgQ, qmsg);
326 /* repost WM_QUIT to make sure this app exits its message loop */
327 if( bPostQuit ) PostQuitMessage32(wQuitParam);
328 wndPtr->hmemTaskQ = 0;
331 if (!(wndPtr->dwStyle & WS_CHILD))
332 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
333 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
334 wndPtr->pDriver->pDestroyWindow( wndPtr );
335 DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */
336 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
337 wndPtr->hwndSelf = 0;
338 wndPtr->class->cWindows--;
339 wndPtr->class = NULL;
342 wndPtr->pDriver->pFinalize(wndPtr);
343 USER_HEAP_FREE( hwnd );
347 /***********************************************************************
348 * WIN_ResetQueueWindows
350 * Reset the queue of all the children of a given window.
351 * Return TRUE if something was done.
353 BOOL32 WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
357 if (hNew) /* Set a new queue */
359 for (wnd = wnd->child; (wnd); wnd = wnd->next)
361 if (wnd->hmemTaskQ == hQueue)
363 wnd->hmemTaskQ = hNew;
367 ret |= WIN_ResetQueueWindows( wnd, hQueue, hNew );
370 else /* Queue is being destroyed */
374 WND *tmp = wnd->child;
378 if (tmp->hmemTaskQ == hQueue)
380 DestroyWindow32( tmp->hwndSelf );
384 if (tmp->child && WIN_ResetQueueWindows(tmp->child,hQueue,0))
395 /***********************************************************************
396 * WIN_CreateDesktopWindow
398 * Create the desktop window.
400 BOOL32 WIN_CreateDesktopWindow(void)
406 TRACE(win,"Creating desktop window\n");
408 if (!ICONTITLE_Init() ||
409 !WINPOS_CreateInternalPosAtom() ||
410 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
413 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
414 if (!hwndDesktop) return FALSE;
415 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
417 pDesktop = (DESKTOP *) pWndDesktop->wExtra;
418 #ifndef X_DISPLAY_MISSING
419 pDesktop->pDriver = &X11DRV_DESKTOP_Driver;
420 pWndDesktop->pDriver = &X11DRV_WND_Driver;
421 #else /* X_DISPLAY_MISSING */
422 pDesktop->pDriver = &TTYDRV_DESKTOP_Driver;
423 pWndDesktop->pDriver = &TTYDRV_WND_Driver;
424 #endif /* X_DISPLAY_MISSING */
426 pDesktop->pDriver->pInitialize(pDesktop);
427 pWndDesktop->pDriver->pInitialize(pWndDesktop);
429 pWndDesktop->next = NULL;
430 pWndDesktop->child = NULL;
431 pWndDesktop->parent = NULL;
432 pWndDesktop->owner = NULL;
433 pWndDesktop->class = class;
434 pWndDesktop->dwMagic = WND_MAGIC;
435 pWndDesktop->hwndSelf = hwndDesktop;
436 pWndDesktop->hInstance = 0;
437 pWndDesktop->rectWindow.left = 0;
438 pWndDesktop->rectWindow.top = 0;
439 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
440 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
441 pWndDesktop->rectClient = pWndDesktop->rectWindow;
442 pWndDesktop->text = NULL;
443 pWndDesktop->hmemTaskQ = GetFastQueue();
444 pWndDesktop->hrgnUpdate = 0;
445 pWndDesktop->hwndLastActive = hwndDesktop;
446 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
448 pWndDesktop->dwExStyle = 0;
449 pWndDesktop->dce = NULL;
450 pWndDesktop->pVScroll = NULL;
451 pWndDesktop->pHScroll = NULL;
452 pWndDesktop->pProp = NULL;
453 pWndDesktop->wIDmenu = 0;
454 pWndDesktop->helpContext = 0;
455 pWndDesktop->flags = 0;
456 pWndDesktop->hSysMenu = 0;
457 pWndDesktop->userdata = 0;
458 pWndDesktop->winproc = (WNDPROC16)class->winproc;
460 /* FIXME: How do we know if it should be Unicode or not */
461 if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop, class, FALSE))
464 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
465 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
470 /***********************************************************************
473 * Implementation of CreateWindowEx().
475 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
476 BOOL32 win32, BOOL32 unicode )
480 HWND16 hwnd, hwndLinkAfter;
481 POINT32 maxSize, maxPos, minTrack, maxTrack;
482 LRESULT (CALLBACK *localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
484 TRACE(win, "%s %s %08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
485 unicode ? debugres_w((LPWSTR)cs->lpszName) : debugres_a(cs->lpszName),
486 unicode ? debugres_w((LPWSTR)cs->lpszClass) : debugres_a(cs->lpszClass),
487 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
488 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
490 /* Find the parent window */
494 /* Make sure parent is valid */
495 if (!IsWindow32( cs->hwndParent ))
497 WARN( win, "Bad parent %04x\n", cs->hwndParent );
500 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
501 WARN( win, "No parent for child window\n" );
502 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
505 /* Find the window class */
506 if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
509 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
510 WARN( win, "Bad class '%s'\n", buffer );
514 /* Fix the coordinates */
516 if (cs->x == CW_USEDEFAULT32)
518 PDB32 *pdb = PROCESS_Current();
519 if ( !(cs->style & (WS_CHILD | WS_POPUP))
520 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
522 cs->x = pdb->env_db->startup_info->dwX;
523 cs->y = pdb->env_db->startup_info->dwY;
531 if (cs->cx == CW_USEDEFAULT32)
533 PDB32 *pdb = PROCESS_Current();
534 if ( !(cs->style & (WS_CHILD | WS_POPUP))
535 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
537 cs->cx = pdb->env_db->startup_info->dwXSize;
538 cs->cy = pdb->env_db->startup_info->dwYSize;
542 cs->cx = 600; /* FIXME */
547 /* Create the window structure */
549 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
550 - sizeof(wndPtr->wExtra) )))
552 TRACE(win, "out of memory\n" );
556 /* Fill the window structure */
558 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
560 wndPtr->child = NULL;
562 if ((cs->style & WS_CHILD) && cs->hwndParent)
564 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
565 wndPtr->owner = NULL;
569 wndPtr->parent = pWndDesktop;
570 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
571 wndPtr->owner = NULL;
573 wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
576 wndPtr->pDriver = wndPtr->parent->pDriver;
577 wndPtr->pDriver->pInitialize(wndPtr);
579 wndPtr->class = classPtr;
580 wndPtr->winproc = classPtr->winproc;
581 wndPtr->dwMagic = WND_MAGIC;
582 wndPtr->hwndSelf = hwnd;
583 wndPtr->hInstance = cs->hInstance;
585 wndPtr->hmemTaskQ = GetFastQueue();
586 wndPtr->hrgnUpdate = 0;
587 wndPtr->hwndLastActive = hwnd;
588 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
589 wndPtr->dwExStyle = cs->dwExStyle;
591 wndPtr->helpContext = 0;
592 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
593 wndPtr->pVScroll = NULL;
594 wndPtr->pHScroll = NULL;
595 wndPtr->pProp = NULL;
596 wndPtr->userdata = 0;
597 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
598 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
600 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
602 /* Call the WH_CBT hook */
604 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
605 ? HWND_BOTTOM : HWND_TOP;
607 if (HOOK_IsHooked( WH_CBT ))
609 CBT_CREATEWND32A cbtc;
613 cbtc.hwndInsertAfter = hwndLinkAfter;
614 ret = unicode ? HOOK_CallHooks32W(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc)
615 : HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc);
618 TRACE(win, "CBT-hook returned 0\n");
619 wndPtr->pDriver->pFinalize(wndPtr);
620 USER_HEAP_FREE( hwnd );
625 /* Increment class window counter */
627 classPtr->cWindows++;
629 /* Correct the window style */
631 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
633 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
634 wndPtr->flags |= WIN_NEED_SIZE;
636 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
638 /* Get class or window DC if needed */
640 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
641 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
642 else wndPtr->dce = NULL;
644 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
646 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
648 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
649 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
650 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
651 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
652 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
655 if(cs->style & WS_CHILD)
657 if(cs->cx < 0) cs->cx = 0;
658 if(cs->cy < 0) cs->cy = 0;
662 if (cs->cx <= 0) cs->cx = 1;
663 if (cs->cy <= 0) cs->cy = 1;
666 wndPtr->rectWindow.left = cs->x;
667 wndPtr->rectWindow.top = cs->y;
668 wndPtr->rectWindow.right = cs->x + cs->cx;
669 wndPtr->rectWindow.bottom = cs->y + cs->cy;
670 wndPtr->rectClient = wndPtr->rectWindow;
672 if(!wndPtr->pDriver->pCreateWindow(wndPtr, classPtr, cs, unicode))
675 /* Set the window menu */
677 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
679 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
682 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
683 if (classPtr->menuNameA)
684 cs->hMenu = HIWORD(classPtr->menuNameA) ?
685 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
686 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
688 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
691 if (HIWORD(cs->hInstance))
692 cs->hMenu = LoadMenu32A(cs->hInstance,PTR_SEG_TO_LIN(menuName));
694 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
696 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
701 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
703 /* Send the WM_CREATE message
704 * Perhaps we shouldn't allow width/height changes as well.
705 * See p327 in "Internals".
708 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
710 localSend32 = unicode ? SendMessage32W : SendMessage32A;
711 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
713 /* Insert the window in the linked list */
715 WIN_LinkWindow( hwnd, hwndLinkAfter );
717 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
718 NULL, NULL, 0, &wndPtr->rectClient );
719 OffsetRect32(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
720 maxPos.y - wndPtr->rectWindow.top);
721 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
723 /* Send the size messages */
725 if (!(wndPtr->flags & WIN_NEED_SIZE))
728 if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
729 ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
730 WARN(win,"sending bogus WM_SIZE message 0x%08lx\n",
731 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
732 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
733 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
734 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
735 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
736 SendMessage32A( hwnd, WM_MOVE, 0,
737 MAKELONG( wndPtr->rectClient.left,
738 wndPtr->rectClient.top ) );
741 /* Show the window, maximizing or minimizing if needed */
743 if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
746 UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
747 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
748 WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
749 swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow32())
750 ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
751 : SWP_NOZORDER | SWP_FRAMECHANGED;
752 SetWindowPos32( hwnd, 0, newPos.left, newPos.top,
753 newPos.right, newPos.bottom, swFlag );
756 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
758 /* Notify the parent window only */
760 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
761 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
762 if( !IsWindow32(hwnd) ) return 0;
765 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
767 /* Call WH_SHELL hook */
769 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
770 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
772 TRACE(win, "created window %04x\n", hwnd);
775 WIN_UnlinkWindow( hwnd );
778 /* Abort window creation */
780 WARN(win, "aborted by WM_xxCREATE!\n");
781 WIN_DestroyWindow( wndPtr );
786 /***********************************************************************
787 * CreateWindow16 (USER.41)
789 HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
790 DWORD style, INT16 x, INT16 y, INT16 width,
791 INT16 height, HWND16 parent, HMENU16 menu,
792 HINSTANCE16 instance, LPVOID data )
794 return CreateWindowEx16( 0, className, windowName, style,
795 x, y, width, height, parent, menu, instance, data );
799 /***********************************************************************
800 * CreateWindowEx16 (USER.452)
802 HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
803 LPCSTR windowName, DWORD style, INT16 x,
804 INT16 y, INT16 width, INT16 height,
805 HWND16 parent, HMENU16 menu,
806 HINSTANCE16 instance, LPVOID data )
811 /* Find the class atom */
813 if (!(classAtom = GlobalFindAtom32A( className )))
815 fprintf( stderr, "CreateWindowEx16: bad class name " );
816 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
817 else fprintf( stderr, "'%s'\n", className );
821 /* Fix the coordinates */
823 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
824 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
825 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
826 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
828 /* Create the window */
830 cs.lpCreateParams = data;
831 cs.hInstance = (HINSTANCE32)instance;
832 cs.hMenu = (HMENU32)menu;
833 cs.hwndParent = (HWND32)parent;
835 cs.lpszName = windowName;
836 cs.lpszClass = className;
837 cs.dwExStyle = exStyle;
838 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
842 /***********************************************************************
843 * CreateWindowEx32A (USER32.83)
845 HWND32 WINAPI CreateWindowEx32A( DWORD exStyle, LPCSTR className,
846 LPCSTR windowName, DWORD style, INT32 x,
847 INT32 y, INT32 width, INT32 height,
848 HWND32 parent, HMENU32 menu,
849 HINSTANCE32 instance, LPVOID data )
854 if(exStyle & WS_EX_MDICHILD)
855 return MDI_CreateMDIWindow32A(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
856 /* Find the class atom */
858 if (!(classAtom = GlobalFindAtom32A( className )))
860 fprintf( stderr, "CreateWindowEx32A: bad class name " );
861 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
862 else fprintf( stderr, "'%s'\n", className );
866 /* Create the window */
868 cs.lpCreateParams = data;
869 cs.hInstance = instance;
871 cs.hwndParent = parent;
877 cs.lpszName = windowName;
878 cs.lpszClass = className;
879 cs.dwExStyle = exStyle;
880 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
884 /***********************************************************************
885 * CreateWindowEx32W (USER32.84)
887 HWND32 WINAPI CreateWindowEx32W( DWORD exStyle, LPCWSTR className,
888 LPCWSTR windowName, DWORD style, INT32 x,
889 INT32 y, INT32 width, INT32 height,
890 HWND32 parent, HMENU32 menu,
891 HINSTANCE32 instance, LPVOID data )
896 if(exStyle & WS_EX_MDICHILD)
897 return MDI_CreateMDIWindow32W(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
899 /* Find the class atom */
901 if (!(classAtom = GlobalFindAtom32W( className )))
903 if (HIWORD(className))
905 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
906 WARN( win, "Bad class name '%s'\n",cn);
907 HeapFree( GetProcessHeap(), 0, cn );
910 WARN( win, "Bad class name %p\n", className );
914 /* Create the window */
916 cs.lpCreateParams = data;
917 cs.hInstance = instance;
919 cs.hwndParent = parent;
925 cs.lpszName = windowName;
926 cs.lpszClass = className;
927 cs.dwExStyle = exStyle;
928 /* Note: we rely on the fact that CREATESTRUCT32A and */
929 /* CREATESTRUCT32W have the same layout. */
930 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
934 /***********************************************************************
937 static void WIN_CheckFocus( WND* pWnd )
939 if( GetFocus16() == pWnd->hwndSelf )
940 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
943 /***********************************************************************
946 static void WIN_SendDestroyMsg( WND* pWnd )
948 WIN_CheckFocus(pWnd);
950 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
951 CLIPBOARD_GetDriver()->pResetOwner( pWnd, TRUE );
953 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
955 if( IsWindow32(pWnd->hwndSelf) )
957 WND* pChild = pWnd->child;
960 WIN_SendDestroyMsg( pChild );
961 pChild = pChild->next;
963 WIN_CheckFocus(pWnd);
966 WARN(win, "\tdestroyed itself while in WM_DESTROY!\n");
970 /***********************************************************************
971 * DestroyWindow16 (USER.53)
973 BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
975 return DestroyWindow32(hwnd);
979 /***********************************************************************
980 * DestroyWindow32 (USER32.135)
982 BOOL32 WINAPI DestroyWindow32( HWND32 hwnd )
986 TRACE(win, "(%04x)\n", hwnd);
990 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
991 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
995 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
998 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1000 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
1001 /* FIXME: clean up palette - see "Internals" p.352 */
1004 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
1005 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
1007 /* Notify the parent window only */
1008 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
1009 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
1010 if( !IsWindow32(hwnd) ) return TRUE;
1013 CLIPBOARD_GetDriver()->pResetOwner( wndPtr, FALSE ); /* before the window is unmapped */
1015 /* Hide the window */
1017 if (wndPtr->dwStyle & WS_VISIBLE)
1019 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
1020 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
1021 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
1022 if (!IsWindow32(hwnd)) return TRUE;
1025 /* Recursively destroy owned windows */
1027 if( !(wndPtr->dwStyle & WS_CHILD) )
1029 /* make sure top menu popup doesn't get destroyed */
1030 MENU_PatchResidentPopup( (HQUEUE16)0xFFFF, wndPtr );
1034 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1037 if (siblingPtr->owner == wndPtr)
1039 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1042 siblingPtr->owner = NULL;
1044 siblingPtr = siblingPtr->next;
1046 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1050 if( !Options.managed || EVENT_CheckFocus() )
1051 WINPOS_ActivateOtherWindow(wndPtr);
1053 if( wndPtr->owner &&
1054 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1055 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1058 /* Send destroy messages */
1060 WIN_SendDestroyMsg( wndPtr );
1061 if (!IsWindow32(hwnd)) return TRUE;
1063 /* Unlink now so we won't bother with the children later on */
1065 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1067 /* Destroy the window storage */
1069 WIN_DestroyWindow( wndPtr );
1074 /***********************************************************************
1075 * CloseWindow16 (USER.43)
1077 BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
1079 return CloseWindow32( hwnd );
1083 /***********************************************************************
1084 * CloseWindow32 (USER32.56)
1086 BOOL32 WINAPI CloseWindow32( HWND32 hwnd )
1088 WND * wndPtr = WIN_FindWndPtr( hwnd );
1089 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1090 ShowWindow32( hwnd, SW_MINIMIZE );
1095 /***********************************************************************
1096 * OpenIcon16 (USER.44)
1098 BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
1100 return OpenIcon32( hwnd );
1104 /***********************************************************************
1105 * OpenIcon32 (USER32.410)
1107 BOOL32 WINAPI OpenIcon32( HWND32 hwnd )
1109 if (!IsIconic32( hwnd )) return FALSE;
1110 ShowWindow32( hwnd, SW_SHOWNORMAL );
1115 /***********************************************************************
1118 * Implementation of FindWindow() and FindWindowEx().
1120 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1124 CLASS *pClass = NULL;
1128 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1131 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1133 else if (pWnd->parent != pWndDesktop) return 0;
1138 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1141 if (!pWnd) return 0;
1143 /* For a child window, all siblings will have the same hInstance, */
1144 /* so we can look for the class once and for all. */
1146 if (className && (pWnd->dwStyle & WS_CHILD))
1148 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1153 for ( ; pWnd; pWnd = pWnd->next)
1155 if (className && !(pWnd->dwStyle & WS_CHILD))
1157 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance)))
1158 continue; /* Skip this window */
1161 if (pClass && (pWnd->class != pClass))
1162 continue; /* Not the right class */
1164 /* Now check the title */
1166 if (!title) return pWnd->hwndSelf;
1167 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1174 /***********************************************************************
1175 * FindWindow16 (USER.50)
1177 HWND16 WINAPI FindWindow16( SEGPTR className, LPCSTR title )
1179 return FindWindowEx16( 0, 0, className, title );
1183 /***********************************************************************
1184 * FindWindowEx16 (USER.427)
1186 HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child,
1187 SEGPTR className, LPCSTR title )
1191 TRACE(win, "%04x %04x '%s' '%s'\n", parent,
1192 child, HIWORD(className)?(char *)PTR_SEG_TO_LIN(className):"",
1193 title ? title : "");
1197 /* If the atom doesn't exist, then no class */
1198 /* with this name exists either. */
1199 if (!(atom = GlobalFindAtom16( className ))) return 0;
1201 return WIN_FindWindow( parent, child, atom, title );
1205 /***********************************************************************
1206 * FindWindow32A (USER32.198)
1208 HWND32 WINAPI FindWindow32A( LPCSTR className, LPCSTR title )
1210 HWND32 ret = FindWindowEx32A( 0, 0, className, title );
1211 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1216 /***********************************************************************
1217 * FindWindowEx32A (USER32.199)
1219 HWND32 WINAPI FindWindowEx32A( HWND32 parent, HWND32 child,
1220 LPCSTR className, LPCSTR title )
1226 /* If the atom doesn't exist, then no class */
1227 /* with this name exists either. */
1228 if (!(atom = GlobalFindAtom32A( className )))
1230 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1234 return WIN_FindWindow( parent, child, atom, title );
1238 /***********************************************************************
1239 * FindWindowEx32W (USER32.200)
1241 HWND32 WINAPI FindWindowEx32W( HWND32 parent, HWND32 child,
1242 LPCWSTR className, LPCWSTR title )
1250 /* If the atom doesn't exist, then no class */
1251 /* with this name exists either. */
1252 if (!(atom = GlobalFindAtom32W( className )))
1254 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1258 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1259 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1260 HeapFree( GetProcessHeap(), 0, buffer );
1265 /***********************************************************************
1266 * FindWindow32W (USER32.201)
1268 HWND32 WINAPI FindWindow32W( LPCWSTR className, LPCWSTR title )
1270 return FindWindowEx32W( 0, 0, className, title );
1274 /**********************************************************************
1277 WND *WIN_GetDesktop(void)
1283 /**********************************************************************
1284 * GetDesktopWindow16 (USER.286)
1286 HWND16 WINAPI GetDesktopWindow16(void)
1288 return (HWND16)pWndDesktop->hwndSelf;
1292 /**********************************************************************
1293 * GetDesktopWindow32 (USER32.232)
1295 HWND32 WINAPI GetDesktopWindow32(void)
1297 return pWndDesktop->hwndSelf;
1301 /**********************************************************************
1302 * GetDesktopHwnd (USER.278)
1304 * Exactly the same thing as GetDesktopWindow(), but not documented.
1305 * Don't ask me why...
1307 HWND16 WINAPI GetDesktopHwnd(void)
1309 return (HWND16)pWndDesktop->hwndSelf;
1313 /*******************************************************************
1314 * EnableWindow16 (USER.34)
1316 BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
1318 return EnableWindow32( hwnd, enable );
1322 /*******************************************************************
1323 * EnableWindow32 (USER32.172)
1325 BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
1329 TRACE(win,"EnableWindow32: ( %x, %d )\n", hwnd, enable);
1331 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1332 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1335 wndPtr->dwStyle &= ~WS_DISABLED;
1336 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1339 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1341 /* Disable window */
1342 wndPtr->dwStyle |= WS_DISABLED;
1343 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1345 SetFocus32( 0 ); /* A disabled window can't have the focus */
1347 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1349 ReleaseCapture(); /* A disabled window can't capture the mouse */
1351 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1354 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1358 /***********************************************************************
1359 * IsWindowEnabled16 (USER.35)
1361 BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
1363 return IsWindowEnabled32(hWnd);
1367 /***********************************************************************
1368 * IsWindowEnabled32 (USER32.349)
1370 BOOL32 WINAPI IsWindowEnabled32(HWND32 hWnd)
1374 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1375 return !(wndPtr->dwStyle & WS_DISABLED);
1379 /***********************************************************************
1380 * IsWindowUnicode (USER32.350)
1382 BOOL32 WINAPI IsWindowUnicode( HWND32 hwnd )
1386 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1387 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1391 /**********************************************************************
1392 * GetWindowWord16 (USER.133)
1394 WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
1396 return GetWindowWord32( hwnd, offset );
1400 /**********************************************************************
1401 * GetWindowWord32 (USER32.314)
1403 WORD WINAPI GetWindowWord32( HWND32 hwnd, INT32 offset )
1405 WND * wndPtr = WIN_FindWndPtr( hwnd );
1406 if (!wndPtr) return 0;
1409 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1411 WARN( win, "Invalid offset %d\n", offset );
1414 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1419 if (HIWORD(wndPtr->wIDmenu))
1420 WARN( win,"GWW_ID: discards high bits of 0x%08x!\n",
1422 return (WORD)wndPtr->wIDmenu;
1423 case GWW_HWNDPARENT:
1424 return wndPtr->parent ?
1425 wndPtr->parent->hwndSelf : (
1427 wndPtr->owner->hwndSelf :
1430 if (HIWORD(wndPtr->hInstance))
1431 WARN(win,"GWW_HINSTANCE: discards high bits of 0x%08x!\n",
1433 return (WORD)wndPtr->hInstance;
1435 WARN( win, "Invalid offset %d\n", offset );
1441 /**********************************************************************
1442 * WIN_GetWindowInstance
1444 HINSTANCE32 WIN_GetWindowInstance( HWND32 hwnd )
1446 WND * wndPtr = WIN_FindWndPtr( hwnd );
1447 if (!wndPtr) return (HINSTANCE32)0;
1448 return wndPtr->hInstance;
1452 /**********************************************************************
1453 * SetWindowWord16 (USER.134)
1455 WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1457 return SetWindowWord32( hwnd, offset, newval );
1461 /**********************************************************************
1462 * SetWindowWord32 (USER32.524)
1464 WORD WINAPI SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1467 WND * wndPtr = WIN_FindWndPtr( hwnd );
1468 if (!wndPtr) return 0;
1471 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1473 WARN( win, "Invalid offset %d\n", offset );
1476 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1480 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1481 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1482 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1484 WARN( win, "Invalid offset %d\n", offset );
1493 /**********************************************************************
1496 * Helper function for GetWindowLong().
1498 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1501 WND * wndPtr = WIN_FindWndPtr( hwnd );
1502 if (!wndPtr) return 0;
1505 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1507 WARN( win, "Invalid offset %d\n", offset );
1510 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1511 /* Special case for dialog window procedure */
1512 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1513 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1518 case GWL_USERDATA: return wndPtr->userdata;
1519 case GWL_STYLE: return wndPtr->dwStyle;
1520 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1521 case GWL_ID: return (LONG)wndPtr->wIDmenu;
1522 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1524 case GWL_HWNDPARENT: return wndPtr->parent ?
1525 (HWND32)wndPtr->parent->hwndSelf : 0;
1526 case GWL_HINSTANCE: return wndPtr->hInstance;
1528 WARN( win, "Unknown offset %d\n", offset );
1534 /**********************************************************************
1537 * Helper function for SetWindowLong().
1539 * 0 is the failure code. However, in the case of failure SetLastError
1540 * must be set to distinguish between a 0 return value and a failure.
1542 * FIXME: The error values for SetLastError may not be right. Can
1543 * someone check with the real thing?
1545 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1546 WINDOWPROCTYPE type )
1549 WND * wndPtr = WIN_FindWndPtr( hwnd );
1552 TRACE(win,"%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
1556 /* Is this the right error? */
1557 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1563 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1565 WARN( win, "Invalid offset %d\n", offset );
1567 /* Is this the right error? */
1568 SetLastError( ERROR_OUTOFMEMORY );
1572 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1573 /* Special case for dialog window procedure */
1574 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1576 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1577 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1578 type, WIN_PROC_WINDOW );
1585 ptr = (DWORD*)&wndPtr->wIDmenu;
1588 return SetWindowWord32( hwnd, offset, newval );
1590 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1591 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1592 type, WIN_PROC_WINDOW );
1595 style.styleOld = wndPtr->dwStyle;
1596 newval &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way */
1597 style.styleNew = newval | (style.styleOld & (WS_VISIBLE | WS_CHILD));
1599 if (wndPtr->flags & WIN_ISWIN32)
1600 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
1601 wndPtr->dwStyle = style.styleNew;
1602 if (wndPtr->flags & WIN_ISWIN32)
1603 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
1604 return style.styleOld;
1607 ptr = &wndPtr->userdata;
1610 style.styleOld = wndPtr->dwExStyle;
1611 style.styleNew = newval;
1612 if (wndPtr->flags & WIN_ISWIN32)
1613 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
1614 wndPtr->dwExStyle = newval;
1615 if (wndPtr->flags & WIN_ISWIN32)
1616 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
1617 return style.styleOld;
1620 WARN( win, "Invalid offset %d\n", offset );
1622 /* Don't think this is right error but it should do */
1623 SetLastError( ERROR_OUTOFMEMORY );
1633 /**********************************************************************
1634 * GetWindowLong16 (USER.135)
1636 LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
1638 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1642 /**********************************************************************
1643 * GetWindowLong32A (USER32.305)
1645 LONG WINAPI GetWindowLong32A( HWND32 hwnd, INT32 offset )
1647 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1651 /**********************************************************************
1652 * GetWindowLong32W (USER32.306)
1654 LONG WINAPI GetWindowLong32W( HWND32 hwnd, INT32 offset )
1656 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1660 /**********************************************************************
1661 * SetWindowLong16 (USER.136)
1663 LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1665 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1669 /**********************************************************************
1670 * SetWindowLong32A (USER32.517)
1672 LONG WINAPI SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1674 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1678 /**********************************************************************
1679 * SetWindowLong32W (USER32.518) Set window attribute
1681 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
1682 * value in a window's extra memory.
1684 * The _hwnd_ parameter specifies the window. is the handle to a
1685 * window that has extra memory. The _newval_ parameter contains the
1686 * new attribute or extra memory value. If positive, the _offset_
1687 * parameter is the byte-addressed location in the window's extra
1688 * memory to set. If negative, _offset_ specifies the window
1689 * attribute to set, and should be one of the following values:
1691 * GWL_EXSTYLE The window's extended window style
1693 * GWL_STYLE The window's window style.
1695 * GWL_WNDPROC Pointer to the window's window procedure.
1697 * GWL_HINSTANCE The window's pplication instance handle.
1699 * GWL_ID The window's identifier.
1701 * GWL_USERDATA The window's user-specified data.
1703 * If the window is a dialog box, the _offset_ parameter can be one of
1704 * the following values:
1706 * DWL_DLGPROC The address of the window's dialog box procedure.
1708 * DWL_MSGRESULT The return value of a message
1709 * that the dialog box procedure processed.
1711 * DWL_USER Application specific information.
1715 * If successful, returns the previous value located at _offset_. Otherwise,
1720 * Extra memory for a window class is specified by a nonzero cbWndExtra
1721 * parameter of the WNDCLASS structure passed to RegisterClass() at the
1722 * time of class creation.
1724 * Using GWL_WNDPROC to set a new window procedure effectively creates
1725 * a window subclass. Use CallWindowProc() in the new windows procedure
1726 * to pass messages to the superclass's window procedure.
1728 * The user data is reserved for use by the application which created
1731 * Do not use GWL_STYLE to change the window's WS_DISABLE style;
1732 * instead, call the EnableWindow() function to change the window's
1735 * Do not use GWL_HWNDPARENT to reset the window's parent, use
1736 * SetParent() instead.
1739 * When offset is GWL_STYLE and the calling app's ver is 4.0,
1740 * it sends WM_STYLECHANGING before changing the settings
1741 * and WM_STYLECHANGED afterwards.
1742 * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
1746 * GWL_STYLE does not dispatch WM_STYLE... messages.
1753 LONG WINAPI SetWindowLong32W(
1754 HWND32 hwnd, /* window to alter */
1755 INT32 offset, /* offset, in bytes, of location to alter */
1756 LONG newval /* new value of location */
1758 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1762 /*******************************************************************
1763 * GetWindowText16 (USER.36)
1765 INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1767 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1771 /*******************************************************************
1772 * GetWindowText32A (USER32.309)
1774 INT32 WINAPI GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1776 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1780 /*******************************************************************
1781 * InternalGetWindowText (USER32.326)
1783 INT32 WINAPI InternalGetWindowText(HWND32 hwnd,LPWSTR lpString,INT32 nMaxCount )
1785 FIXME(win,"(0x%08x,%p,0x%x),stub!\n",hwnd,lpString,nMaxCount);
1786 return GetWindowText32W(hwnd,lpString,nMaxCount);
1790 /*******************************************************************
1791 * GetWindowText32W (USER32.312)
1793 INT32 WINAPI GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1795 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1800 /*******************************************************************
1801 * SetWindowText16 (USER.37)
1803 BOOL16 WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1805 return (BOOL16)SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1809 /*******************************************************************
1810 * SetWindowText32A (USER32.521)
1812 BOOL32 WINAPI SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1814 return (BOOL32)SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1818 /*******************************************************************
1819 * SetWindowText32W (USER32.523)
1821 BOOL32 WINAPI SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1823 return (BOOL32)SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1827 /*******************************************************************
1828 * GetWindowTextLength16 (USER.38)
1830 INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
1832 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1836 /*******************************************************************
1837 * GetWindowTextLength32A (USER32.310)
1839 INT32 WINAPI GetWindowTextLength32A( HWND32 hwnd )
1841 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1844 /*******************************************************************
1845 * GetWindowTextLength32W (USER32.311)
1847 INT32 WINAPI GetWindowTextLength32W( HWND32 hwnd )
1849 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1853 /*******************************************************************
1854 * IsWindow16 (USER.47)
1856 BOOL16 WINAPI IsWindow16( HWND16 hwnd )
1858 return IsWindow32( hwnd );
1861 void WINAPI WIN16_IsWindow16( CONTEXT *context )
1863 WORD *stack = PTR_SEG_OFF_TO_LIN(SS_reg(context), SP_reg(context));
1864 HWND16 hwnd = (HWND16)stack[2];
1866 AX_reg(context) = IsWindow32( hwnd );
1867 ES_reg(context) = USER_HeapSel;
1871 /*******************************************************************
1872 * IsWindow32 (USER32.348)
1874 BOOL32 WINAPI IsWindow32( HWND32 hwnd )
1876 WND * wndPtr = WIN_FindWndPtr( hwnd );
1877 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1881 /*****************************************************************
1882 * GetParent16 (USER.46)
1884 HWND16 WINAPI GetParent16( HWND16 hwnd )
1886 return (HWND16)GetParent32( hwnd );
1890 /*****************************************************************
1891 * GetParent32 (USER32.278)
1893 HWND32 WINAPI GetParent32( HWND32 hwnd )
1895 WND *wndPtr = WIN_FindWndPtr(hwnd);
1896 if ((!wndPtr) || (!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD)))) return 0;
1897 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1898 return wndPtr ? wndPtr->hwndSelf : 0;
1901 /*****************************************************************
1904 * Get the top-level parent for a child window.
1906 WND* WIN_GetTopParentPtr( WND* pWnd )
1908 while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
1912 /*****************************************************************
1915 * Get the top-level parent for a child window.
1917 HWND32 WIN_GetTopParent( HWND32 hwnd )
1919 WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
1920 return wndPtr ? wndPtr->hwndSelf : 0;
1924 /*****************************************************************
1925 * SetParent16 (USER.233)
1927 HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1929 return SetParent32( hwndChild, hwndNewParent );
1933 /*****************************************************************
1934 * SetParent32 (USER32.495)
1936 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1938 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1939 DWORD dwStyle = (wndPtr)?(wndPtr->dwStyle):0;
1940 WND *pWndNewParent =
1941 (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent ) : pWndDesktop;
1944 /* Windows hides the window first, then shows it again
1945 * including the WM_SHOWWINDOW messages and all */
1946 if (dwStyle & WS_VISIBLE)
1947 ShowWindow32( hwndChild, SW_HIDE );
1949 pWndOldParent = (wndPtr)?(*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent):NULL;
1951 /* SetParent32 additionally needs to make hwndChild the topmost window
1952 in the x-order and send the expected WM_WINDOWPOSCHANGING and
1953 WM_WINDOWPOSCHANGED notification messages.
1955 SetWindowPos32( hwndChild, HWND_TOPMOST, 0, 0, 0, 0,
1956 SWP_NOMOVE|SWP_NOSIZE|((dwStyle & WS_VISIBLE)?SWP_SHOWWINDOW:0));
1957 /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler
1958 * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */
1960 return pWndOldParent?pWndOldParent->hwndSelf:0;
1963 /*******************************************************************
1964 * IsChild16 (USER.48)
1966 BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
1968 return IsChild32(parent,child);
1972 /*******************************************************************
1973 * IsChild32 (USER32.339)
1975 BOOL32 WINAPI IsChild32( HWND32 parent, HWND32 child )
1977 WND * wndPtr = WIN_FindWndPtr( child );
1978 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1980 wndPtr = wndPtr->parent;
1981 if (wndPtr->hwndSelf == parent) return TRUE;
1987 /***********************************************************************
1988 * IsWindowVisible16 (USER.49)
1990 BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
1992 return IsWindowVisible32(hwnd);
1996 /***********************************************************************
1997 * IsWindowVisible32 (USER32.351)
1999 BOOL32 WINAPI IsWindowVisible32( HWND32 hwnd )
2001 WND *wndPtr = WIN_FindWndPtr( hwnd );
2002 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
2004 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
2005 wndPtr = wndPtr->parent;
2007 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
2011 /***********************************************************************
2012 * WIN_IsWindowDrawable
2014 * hwnd is drawable when it is visible, all parents are not
2015 * minimized, and it is itself not minimized unless we are
2016 * trying to draw its default class icon.
2018 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
2020 if( (wnd->dwStyle & WS_MINIMIZE &&
2021 icon && wnd->class->hIcon) ||
2022 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
2023 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
2024 if( wnd->dwStyle & WS_MINIMIZE ||
2025 !(wnd->dwStyle & WS_VISIBLE) ) break;
2026 return (wnd == NULL);
2030 /*******************************************************************
2031 * GetTopWindow16 (USER.229)
2033 HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
2035 return GetTopWindow32(hwnd);
2039 /*******************************************************************
2040 * GetTopWindow32 (USER.229)
2042 HWND32 WINAPI GetTopWindow32( HWND32 hwnd )
2044 WND * wndPtr = WIN_FindWndPtr( hwnd );
2045 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
2050 /*******************************************************************
2051 * GetWindow16 (USER.262)
2053 HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
2055 return GetWindow32( hwnd,rel );
2059 /*******************************************************************
2060 * GetWindow32 (USER32.302)
2062 HWND32 WINAPI GetWindow32( HWND32 hwnd, WORD rel )
2064 WND * wndPtr = WIN_FindWndPtr( hwnd );
2065 if (!wndPtr) return 0;
2069 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
2073 if (!wndPtr->parent) return 0; /* Desktop window */
2074 while (wndPtr->next) wndPtr = wndPtr->next;
2075 return wndPtr->hwndSelf;
2078 if (!wndPtr->next) return 0;
2079 return wndPtr->next->hwndSelf;
2082 if (!wndPtr->parent) return 0; /* Desktop window */
2083 wndPtr = wndPtr->parent->child; /* First sibling */
2084 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
2085 while (wndPtr->next)
2087 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
2088 wndPtr = wndPtr->next;
2093 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
2096 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
2102 /*******************************************************************
2103 * GetNextWindow16 (USER.230)
2105 HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
2107 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
2108 return GetWindow16( hwnd, flag );
2111 /*******************************************************************
2112 * ShowOwnedPopups16 (USER.265)
2114 void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
2116 ShowOwnedPopups32( owner, fShow );
2120 /*******************************************************************
2121 * ShowOwnedPopups32 (USER32.531)
2123 BOOL32 WINAPI ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
2125 WND *pWnd = pWndDesktop->child;
2128 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
2129 (pWnd->dwStyle & WS_POPUP))
2130 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
2137 /*******************************************************************
2138 * GetLastActivePopup16 (USER.287)
2140 HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
2142 return GetLastActivePopup32( hwnd );
2145 /*******************************************************************
2146 * GetLastActivePopup32 (USER32.256)
2148 HWND32 WINAPI GetLastActivePopup32( HWND32 hwnd )
2151 wndPtr = WIN_FindWndPtr(hwnd);
2152 if (wndPtr == NULL) return hwnd;
2153 return wndPtr->hwndLastActive;
2157 /*******************************************************************
2160 * Build an array of pointers to the children of a given window.
2161 * The array must be freed with HeapFree(SystemHeap). Return NULL
2162 * when no windows are found.
2164 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
2166 WND **list, **ppWnd;
2168 UINT32 count, skipOwned, skipHidden;
2171 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2172 skipOwned = bwaFlags & BWA_SKIPOWNED;
2173 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2174 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
2176 /* First count the windows */
2178 if (!wndPtr) wndPtr = pWndDesktop;
2179 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
2181 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2182 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
2187 /* Now build the list of all windows */
2189 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
2191 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
2193 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2194 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2205 if( pTotal ) *pTotal = count;
2210 /*******************************************************************
2211 * EnumWindows16 (USER.54)
2213 BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2215 WND **list, **ppWnd;
2217 /* We have to build a list of all windows first, to avoid */
2218 /* unpleasant side-effects, for instance if the callback */
2219 /* function changes the Z-order of the windows. */
2221 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2223 /* Now call the callback function for every window */
2225 for (ppWnd = list; *ppWnd; ppWnd++)
2227 /* Make sure that the window still exists */
2228 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2229 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2231 HeapFree( SystemHeap, 0, list );
2236 /*******************************************************************
2237 * EnumWindows32 (USER32.193)
2239 BOOL32 WINAPI EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2241 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2245 /**********************************************************************
2246 * EnumTaskWindows16 (USER.225)
2248 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2251 WND **list, **ppWnd;
2253 /* This function is the same as EnumWindows(), */
2254 /* except for an added check on the window's task. */
2256 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2258 /* Now call the callback function for every window */
2260 for (ppWnd = list; *ppWnd; ppWnd++)
2262 /* Make sure that the window still exists */
2263 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2264 if (QUEUE_GetQueueTask((*ppWnd)->hmemTaskQ) != hTask) continue;
2265 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2267 HeapFree( SystemHeap, 0, list );
2272 /**********************************************************************
2273 * EnumThreadWindows (USER32.190)
2275 BOOL32 WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2277 THDB *tdb = THREAD_ID_TO_THDB(id);
2279 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2283 /**********************************************************************
2284 * WIN_EnumChildWindows
2286 * Helper function for EnumChildWindows().
2288 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2294 for ( ; *ppWnd; ppWnd++)
2296 /* Make sure that the window still exists */
2297 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2298 /* Build children list first */
2299 childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
2300 ret = func( (*ppWnd)->hwndSelf, lParam );
2303 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
2304 HeapFree( SystemHeap, 0, childList );
2306 if (!ret) return FALSE;
2312 /**********************************************************************
2313 * EnumChildWindows16 (USER.55)
2315 BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2318 WND **list, *pParent;
2320 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2321 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2322 WIN_EnumChildWindows( list, func, lParam );
2323 HeapFree( SystemHeap, 0, list );
2328 /**********************************************************************
2329 * EnumChildWindows32 (USER32.178)
2331 BOOL32 WINAPI EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
2334 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2339 /*******************************************************************
2340 * AnyPopup16 (USER.52)
2342 BOOL16 WINAPI AnyPopup16(void)
2344 return AnyPopup32();
2348 /*******************************************************************
2349 * AnyPopup32 (USER32.4)
2351 BOOL32 WINAPI AnyPopup32(void)
2354 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2355 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2360 /*******************************************************************
2361 * FlashWindow16 (USER.105)
2363 BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2365 return FlashWindow32( hWnd, bInvert );
2369 /*******************************************************************
2370 * FlashWindow32 (USER32.202)
2372 BOOL32 WINAPI FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2374 WND *wndPtr = WIN_FindWndPtr(hWnd);
2376 TRACE(win,"%04x\n", hWnd);
2378 if (!wndPtr) return FALSE;
2380 if (wndPtr->dwStyle & WS_MINIMIZE)
2382 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2384 HDC32 hDC = GetDC32(hWnd);
2386 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2387 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2389 ReleaseDC32( hWnd, hDC );
2390 wndPtr->flags |= WIN_NCACTIVATED;
2394 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2395 RDW_UPDATENOW | RDW_FRAME, 0 );
2396 wndPtr->flags &= ~WIN_NCACTIVATED;
2403 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2404 else wparam = (hWnd == GetActiveWindow32());
2406 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2412 /*******************************************************************
2413 * SetSysModalWindow16 (USER.188)
2415 HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
2417 HWND32 hWndOldModal = hwndSysModal;
2418 hwndSysModal = hWnd;
2419 FIXME(win, "EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2420 return hWndOldModal;
2424 /*******************************************************************
2425 * GetSysModalWindow16 (USER.52)
2427 HWND16 WINAPI GetSysModalWindow16(void)
2429 return hwndSysModal;
2433 /*******************************************************************
2434 * GetWindowContextHelpId (USER32.303)
2436 DWORD WINAPI GetWindowContextHelpId( HWND32 hwnd )
2438 WND *wnd = WIN_FindWndPtr( hwnd );
2440 return wnd->helpContext;
2444 /*******************************************************************
2445 * SetWindowContextHelpId (USER32.515)
2447 BOOL32 WINAPI SetWindowContextHelpId( HWND32 hwnd, DWORD id )
2449 WND *wnd = WIN_FindWndPtr( hwnd );
2450 if (!wnd) return FALSE;
2451 wnd->helpContext = id;
2456 /*******************************************************************
2459 * recursively find a child that contains spDragInfo->pt point
2460 * and send WM_QUERYDROPOBJECT
2462 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2464 BOOL16 wParam,bResult = 0;
2466 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2467 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2470 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2472 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2474 GetWindowRect32(hQueryWnd,&tempRect);
2476 if( !PtInRect32(&tempRect,pt) ||
2477 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2480 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2482 tempRect = ptrQueryWnd->rectClient;
2483 if(ptrQueryWnd->dwStyle & WS_CHILD)
2484 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2485 (LPPOINT32)&tempRect, 2 );
2487 if (PtInRect32( &tempRect, pt))
2491 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2492 if( ptrWnd->dwStyle & WS_VISIBLE )
2494 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2495 if (PtInRect32( &tempRect, pt )) break;
2500 TRACE(msg,"hwnd = %04x, %d %d - %d %d\n",
2501 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2502 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2503 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2504 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2507 if(bResult) return bResult;
2513 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2515 ptrDragInfo->hScope = hQueryWnd;
2517 bResult = ( bNoSend )
2518 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2519 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2520 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2522 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2528 /*******************************************************************
2529 * DragDetect (USER.465)
2531 BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
2534 CONV_POINT16TO32( &pt, &pt32 );
2535 return DragDetect32( hWnd, pt32 );
2538 /*******************************************************************
2539 * DragDetect32 (USER32.151)
2541 BOOL32 WINAPI DragDetect32( HWND32 hWnd, POINT32 pt )
2546 rect.left = pt.x - wDragWidth;
2547 rect.right = pt.x + wDragWidth;
2549 rect.top = pt.y - wDragHeight;
2550 rect.bottom = pt.y + wDragHeight;
2556 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2558 if( msg.message == WM_LBUTTONUP )
2563 if( msg.message == WM_MOUSEMOVE )
2565 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2577 /******************************************************************************
2578 * DragObject16 (USER.464)
2580 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2581 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2584 LPDRAGINFO lpDragInfo;
2586 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2587 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2588 WND *wndPtr = WIN_FindWndPtr(hWnd);
2589 HCURSOR16 hCurrentCursor = 0;
2590 HWND16 hCurrentWnd = 0;
2592 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2593 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2595 if( !lpDragInfo || !spDragInfo ) return 0L;
2597 hBummer = LoadCursor16(0, IDC_BUMMER16);
2599 if( !hBummer || !wndPtr )
2601 GlobalFree16(hDragInfo);
2607 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2609 GlobalFree16(hDragInfo);
2613 if( hDragCursor == hCursor ) hDragCursor = 0;
2614 else hCursor = hDragCursor;
2616 hOldCursor = SetCursor32(hDragCursor);
2619 lpDragInfo->hWnd = hWnd;
2620 lpDragInfo->hScope = 0;
2621 lpDragInfo->wFlags = wObj;
2622 lpDragInfo->hList = szList; /* near pointer! */
2623 lpDragInfo->hOfStruct = hOfStruct;
2627 ShowCursor32( TRUE );
2631 do{ WaitMessage(); }
2632 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2634 *(lpDragInfo+1) = *lpDragInfo;
2636 lpDragInfo->pt = msg.pt;
2638 /* update DRAGINFO struct */
2639 TRACE(msg,"lpDI->hScope = %04x\n",lpDragInfo->hScope);
2641 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2642 hCurrentCursor = hCursor;
2645 hCurrentCursor = hBummer;
2646 lpDragInfo->hScope = 0;
2648 if( hCurrentCursor )
2649 SetCursor32(hCurrentCursor);
2651 /* send WM_DRAGLOOP */
2652 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2653 (LPARAM) spDragInfo );
2654 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2655 if( hCurrentWnd != lpDragInfo->hScope )
2658 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2659 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2660 HIWORD(spDragInfo)) );
2661 hCurrentWnd = lpDragInfo->hScope;
2663 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2667 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2669 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2672 ShowCursor32( FALSE );
2676 SetCursor32( hOldCursor );
2677 if (hDragCursor) DestroyCursor32( hDragCursor );
2680 if( hCurrentCursor != hBummer )
2681 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2682 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2685 GlobalFree16(hDragInfo);
2687 return (DWORD)(msg.lParam);