2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
15 #include "sysmetrics.h"
16 #include "cursoricon.h"
21 #include "nonclient.h"
24 #include "shm_main_blk.h"
26 #include "clipboard.h"
35 extern WND_DRIVER X11DRV_WND_Driver;
38 static WND *pWndDesktop = NULL;
40 static HWND32 hwndSysModal = 0;
42 static WORD wDragWidth = 4;
43 static WORD wDragHeight= 3;
45 /***********************************************************************
48 * Return a pointer to the WND structure corresponding to a HWND.
50 WND * WIN_FindWndPtr( HWND32 hwnd )
54 if (!hwnd || HIWORD(hwnd)) return NULL;
55 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
56 if (ptr->dwMagic != WND_MAGIC) return NULL;
57 if (ptr->hwndSelf != hwnd)
59 ERR( win, "Can't happen: hwnd %04x self pointer is %04x\n",
60 hwnd, ptr->hwndSelf );
67 /***********************************************************************
70 * Dump the content of a window structure to stderr.
72 void WIN_DumpWindow( HWND32 hwnd )
78 if (!(ptr = WIN_FindWndPtr( hwnd )))
80 WARN( win, "%04x is not a window handle\n", hwnd );
84 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
85 strcpy( className, "#NULL#" );
87 TRACE( win, "Window %04x (%p):\n", hwnd, ptr );
88 DUMP( "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
89 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
90 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
91 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
92 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
93 ptr->next, ptr->child, ptr->parent, ptr->owner,
94 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
95 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
96 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
97 ptr->text ? ptr->text : "",
98 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
99 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
100 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
101 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
103 if (ptr->class->cbWndExtra)
105 DUMP( "extra bytes:" );
106 for (i = 0; i < ptr->class->cbWndExtra; i++)
107 DUMP( " %02x", *((BYTE*)ptr->wExtra+i) );
114 /***********************************************************************
117 * Walk the windows tree and print each window on stderr.
119 void WIN_WalkWindows( HWND32 hwnd, int indent )
124 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
127 WARN( win, "Invalid window handle %04x\n", hwnd );
131 if (!indent) /* first time around */
132 DUMP( "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
133 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc"
138 DUMP( "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
140 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
142 DUMP( "%08lx %-6.4x %-17.17s %08x %08x %.14s\n",
143 (DWORD)ptr, ptr->hmemTaskQ, className,
144 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc,
145 ptr->text?ptr->text:"<null>");
147 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
152 /***********************************************************************
155 * Remove a window from the siblings linked list.
157 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
159 WND *wndPtr, **ppWnd;
161 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
162 ppWnd = &wndPtr->parent->child;
163 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
164 *ppWnd = wndPtr->next;
169 /***********************************************************************
172 * Insert a window into the siblings linked list.
173 * The window is inserted after the specified window, which can also
174 * be specified as HWND_TOP or HWND_BOTTOM.
176 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
178 WND *wndPtr, **ppWnd;
180 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
182 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
184 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
185 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
186 while (*ppWnd) ppWnd = &(*ppWnd)->next;
188 else /* Normal case */
190 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
191 if (!afterPtr) return FALSE;
192 ppWnd = &afterPtr->next;
194 wndPtr->next = *ppWnd;
200 /***********************************************************************
201 * WIN_FindWinToRepaint
203 * Find a window that needs repaint.
205 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
208 WND *pWnd = pWndDesktop;
210 /* Note: the desktop window never gets WM_PAINT messages
211 * The real reason why is because Windows DesktopWndProc
212 * does ValidateRgn inside WM_ERASEBKGND handler.
215 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
217 for ( ; pWnd ; pWnd = pWnd->next )
219 if (!(pWnd->dwStyle & WS_VISIBLE))
221 TRACE(win, "skipping window %04x\n",
225 if ((pWnd->hmemTaskQ == hQueue) &&
226 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
229 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
235 hwndRet = pWnd->hwndSelf;
237 /* look among siblings if we got a transparent window */
238 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
239 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
243 if (pWnd) hwndRet = pWnd->hwndSelf;
244 TRACE(win,"found %04x\n",hwndRet);
249 /***********************************************************************
252 * Destroy storage associated to a window. "Internals" p.358
254 static WND* WIN_DestroyWindow( WND* wndPtr )
256 HWND32 hwnd = wndPtr->hwndSelf;
259 TRACE(win, "%04x\n", wndPtr->hwndSelf );
263 DDE_DestroyWindow(wndPtr->hwndSelf);
264 #endif /* CONFIG_IPC */
266 /* free child windows */
268 while ((pWnd = wndPtr->child))
269 wndPtr->child = WIN_DestroyWindow( pWnd );
271 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
273 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
275 WINPOS_CheckInternalPos( hwnd );
276 if( hwnd == GetCapture32()) ReleaseCapture();
278 /* free resources associated with the window */
280 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
281 PROPERTY_RemoveWindowProps( wndPtr );
283 wndPtr->dwMagic = 0; /* Mark it as invalid */
285 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
287 if (wndPtr->hrgnUpdate > 1) DeleteObject32( wndPtr->hrgnUpdate );
288 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
291 /* toss stale messages from the queue */
293 if( wndPtr->hmemTaskQ )
295 BOOL32 bPostQuit = FALSE;
296 WPARAM32 wQuitParam = 0;
297 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
300 while( (qmsg = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != 0 )
302 if( qmsg->msg.message == WM_QUIT )
305 wQuitParam = qmsg->msg.wParam;
307 QUEUE_RemoveMsg(msgQ, qmsg);
309 /* repost WM_QUIT to make sure this app exits its message loop */
310 if( bPostQuit ) PostQuitMessage32(wQuitParam);
311 wndPtr->hmemTaskQ = 0;
314 if (!(wndPtr->dwStyle & WS_CHILD))
315 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
316 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
317 wndPtr->pDriver->pDestroyWindow( wndPtr );
318 DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */
319 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
320 wndPtr->hwndSelf = 0;
321 wndPtr->class->cWindows--;
322 wndPtr->class = NULL;
325 wndPtr->pDriver->pFinalize(wndPtr);
326 USER_HEAP_FREE( hwnd );
330 /***********************************************************************
331 * WIN_ResetQueueWindows
333 * Reset the queue of all the children of a given window.
334 * Return TRUE if something was done.
336 BOOL32 WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
340 if (hNew) /* Set a new queue */
342 for (wnd = wnd->child; (wnd); wnd = wnd->next)
344 if (wnd->hmemTaskQ == hQueue)
346 wnd->hmemTaskQ = hNew;
350 ret |= WIN_ResetQueueWindows( wnd, hQueue, hNew );
353 else /* Queue is being destroyed */
357 WND *tmp = wnd->child;
361 if (tmp->hmemTaskQ == hQueue)
363 DestroyWindow32( tmp->hwndSelf );
367 if (tmp->child && WIN_ResetQueueWindows(tmp->child,hQueue,0))
378 /***********************************************************************
379 * WIN_CreateDesktopWindow
381 * Create the desktop window.
383 BOOL32 WIN_CreateDesktopWindow(void)
388 TRACE(win,"Creating desktop window\n");
390 if (!ICONTITLE_Init() ||
391 !WINPOS_CreateInternalPosAtom() ||
392 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
395 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
396 if (!hwndDesktop) return FALSE;
397 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
399 pWndDesktop->pDriver = &X11DRV_WND_Driver;
400 pWndDesktop->pDriver->pInitialize(pWndDesktop);
402 pWndDesktop->next = NULL;
403 pWndDesktop->child = NULL;
404 pWndDesktop->parent = NULL;
405 pWndDesktop->owner = NULL;
406 pWndDesktop->class = class;
407 pWndDesktop->dwMagic = WND_MAGIC;
408 pWndDesktop->hwndSelf = hwndDesktop;
409 pWndDesktop->hInstance = 0;
410 pWndDesktop->rectWindow.left = 0;
411 pWndDesktop->rectWindow.top = 0;
412 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
413 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
414 pWndDesktop->rectClient = pWndDesktop->rectWindow;
415 pWndDesktop->text = NULL;
416 pWndDesktop->hmemTaskQ = GetFastQueue();
417 pWndDesktop->hrgnUpdate = 0;
418 pWndDesktop->hwndLastActive = hwndDesktop;
419 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
421 pWndDesktop->dwExStyle = 0;
422 pWndDesktop->dce = NULL;
423 pWndDesktop->pVScroll = NULL;
424 pWndDesktop->pHScroll = NULL;
425 pWndDesktop->pProp = NULL;
426 pWndDesktop->wIDmenu = 0;
427 pWndDesktop->helpContext = 0;
428 pWndDesktop->flags = 0;
429 pWndDesktop->hSysMenu = 0;
430 pWndDesktop->userdata = 0;
431 pWndDesktop->winproc = (WNDPROC16)class->winproc;
433 /* FIXME: How do we know if it should be Unicode or not */
434 if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop, class, FALSE))
437 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
438 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
443 /***********************************************************************
446 * Implementation of CreateWindowEx().
448 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
449 BOOL32 win32, BOOL32 unicode )
453 HWND16 hwnd, hwndLinkAfter;
454 POINT32 maxSize, maxPos, minTrack, maxTrack;
455 LRESULT (CALLBACK *localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
457 TRACE(win, "%s %s %08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
458 unicode ? debugres_w((LPWSTR)cs->lpszName) : debugres_a(cs->lpszName),
459 unicode ? debugres_w((LPWSTR)cs->lpszClass) : debugres_a(cs->lpszClass),
460 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
461 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
463 /* Find the parent window */
467 /* Make sure parent is valid */
468 if (!IsWindow32( cs->hwndParent ))
470 WARN( win, "Bad parent %04x\n", cs->hwndParent );
473 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
474 WARN( win, "No parent for child window\n" );
475 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
478 /* Find the window class */
479 if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
482 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
483 WARN( win, "Bad class '%s'\n", buffer );
487 /* Fix the coordinates */
489 if (cs->x == CW_USEDEFAULT32)
491 PDB32 *pdb = PROCESS_Current();
492 if ( !(cs->style & (WS_CHILD | WS_POPUP))
493 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
495 cs->x = pdb->env_db->startup_info->dwX;
496 cs->y = pdb->env_db->startup_info->dwY;
504 if (cs->cx == CW_USEDEFAULT32)
506 PDB32 *pdb = PROCESS_Current();
507 if ( !(cs->style & (WS_CHILD | WS_POPUP))
508 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
510 cs->cx = pdb->env_db->startup_info->dwXSize;
511 cs->cy = pdb->env_db->startup_info->dwYSize;
515 cs->cx = 600; /* FIXME */
520 /* Create the window structure */
522 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
523 - sizeof(wndPtr->wExtra) )))
525 TRACE(win, "out of memory\n" );
529 /* Fill the window structure */
531 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
533 wndPtr->child = NULL;
535 if ((cs->style & WS_CHILD) && cs->hwndParent)
537 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
538 wndPtr->owner = NULL;
542 wndPtr->parent = pWndDesktop;
543 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
544 wndPtr->owner = NULL;
546 wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
549 wndPtr->pDriver = wndPtr->parent->pDriver;
550 wndPtr->pDriver->pInitialize(wndPtr);
552 wndPtr->class = classPtr;
553 wndPtr->winproc = classPtr->winproc;
554 wndPtr->dwMagic = WND_MAGIC;
555 wndPtr->hwndSelf = hwnd;
556 wndPtr->hInstance = cs->hInstance;
558 wndPtr->hmemTaskQ = GetFastQueue();
559 wndPtr->hrgnUpdate = 0;
560 wndPtr->hwndLastActive = hwnd;
561 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
562 wndPtr->dwExStyle = cs->dwExStyle;
564 wndPtr->helpContext = 0;
565 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
566 wndPtr->pVScroll = NULL;
567 wndPtr->pHScroll = NULL;
568 wndPtr->pProp = NULL;
569 wndPtr->userdata = 0;
570 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
571 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
573 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
575 /* Call the WH_CBT hook */
577 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
578 ? HWND_BOTTOM : HWND_TOP;
580 if (HOOK_IsHooked( WH_CBT ))
582 CBT_CREATEWND32A cbtc;
586 cbtc.hwndInsertAfter = hwndLinkAfter;
587 ret = unicode ? HOOK_CallHooks32W(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc)
588 : HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc);
591 TRACE(win, "CBT-hook returned 0\n");
592 wndPtr->pDriver->pFinalize(wndPtr);
593 USER_HEAP_FREE( hwnd );
598 /* Increment class window counter */
600 classPtr->cWindows++;
602 /* Correct the window style */
604 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
606 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
607 wndPtr->flags |= WIN_NEED_SIZE;
609 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
611 /* Get class or window DC if needed */
613 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
614 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
615 else wndPtr->dce = NULL;
617 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
619 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
621 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
622 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
623 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
624 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
625 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
628 if(cs->style & WS_CHILD)
630 if(cs->cx < 0) cs->cx = 0;
631 if(cs->cy < 0) cs->cy = 0;
635 if (cs->cx <= 0) cs->cx = 1;
636 if (cs->cy <= 0) cs->cy = 1;
639 wndPtr->rectWindow.left = cs->x;
640 wndPtr->rectWindow.top = cs->y;
641 wndPtr->rectWindow.right = cs->x + cs->cx;
642 wndPtr->rectWindow.bottom = cs->y + cs->cy;
643 wndPtr->rectClient = wndPtr->rectWindow;
645 if(!wndPtr->pDriver->pCreateWindow(wndPtr, classPtr, cs, unicode))
648 /* Set the window menu */
650 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
652 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
655 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
656 if (classPtr->menuNameA)
657 cs->hMenu = HIWORD(classPtr->menuNameA) ?
658 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
659 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
661 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
664 if (HIWORD(cs->hInstance))
665 cs->hMenu = LoadMenu32A(cs->hInstance,PTR_SEG_TO_LIN(menuName));
667 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
669 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
674 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
676 /* Send the WM_CREATE message
677 * Perhaps we shouldn't allow width/height changes as well.
678 * See p327 in "Internals".
681 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
683 localSend32 = unicode ? SendMessage32W : SendMessage32A;
684 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
686 /* Insert the window in the linked list */
688 WIN_LinkWindow( hwnd, hwndLinkAfter );
690 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
691 NULL, NULL, 0, &wndPtr->rectClient );
692 OffsetRect32(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
693 maxPos.y - wndPtr->rectWindow.top);
694 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
696 /* Send the size messages */
698 if (!(wndPtr->flags & WIN_NEED_SIZE))
701 if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
702 ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
703 WARN(win,"sending bogus WM_SIZE message 0x%08lx\n",
704 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
705 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
706 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
707 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
708 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
709 SendMessage32A( hwnd, WM_MOVE, 0,
710 MAKELONG( wndPtr->rectClient.left,
711 wndPtr->rectClient.top ) );
714 /* Show the window, maximizing or minimizing if needed */
716 if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
719 UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
720 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
721 WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
722 swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow32())
723 ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
724 : SWP_NOZORDER | SWP_FRAMECHANGED;
725 SetWindowPos32( hwnd, 0, newPos.left, newPos.top,
726 newPos.right, newPos.bottom, swFlag );
729 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
731 /* Notify the parent window only */
733 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
734 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
735 if( !IsWindow32(hwnd) ) return 0;
738 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
740 /* Call WH_SHELL hook */
742 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
743 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
745 TRACE(win, "created window %04x\n", hwnd);
748 WIN_UnlinkWindow( hwnd );
751 /* Abort window creation */
753 WARN(win, "aborted by WM_xxCREATE!\n");
754 WIN_DestroyWindow( wndPtr );
759 /***********************************************************************
760 * CreateWindow16 (USER.41)
762 HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
763 DWORD style, INT16 x, INT16 y, INT16 width,
764 INT16 height, HWND16 parent, HMENU16 menu,
765 HINSTANCE16 instance, LPVOID data )
767 return CreateWindowEx16( 0, className, windowName, style,
768 x, y, width, height, parent, menu, instance, data );
772 /***********************************************************************
773 * CreateWindowEx16 (USER.452)
775 HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
776 LPCSTR windowName, DWORD style, INT16 x,
777 INT16 y, INT16 width, INT16 height,
778 HWND16 parent, HMENU16 menu,
779 HINSTANCE16 instance, LPVOID data )
784 /* Find the class atom */
786 if (!(classAtom = GlobalFindAtom32A( className )))
788 fprintf( stderr, "CreateWindowEx16: bad class name " );
789 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
790 else fprintf( stderr, "'%s'\n", className );
794 /* Fix the coordinates */
796 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
797 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
798 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
799 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
801 /* Create the window */
803 cs.lpCreateParams = data;
804 cs.hInstance = (HINSTANCE32)instance;
805 cs.hMenu = (HMENU32)menu;
806 cs.hwndParent = (HWND32)parent;
808 cs.lpszName = windowName;
809 cs.lpszClass = className;
810 cs.dwExStyle = exStyle;
811 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
815 /***********************************************************************
816 * CreateWindowEx32A (USER32.83)
818 HWND32 WINAPI CreateWindowEx32A( DWORD exStyle, LPCSTR className,
819 LPCSTR windowName, DWORD style, INT32 x,
820 INT32 y, INT32 width, INT32 height,
821 HWND32 parent, HMENU32 menu,
822 HINSTANCE32 instance, LPVOID data )
827 if(exStyle & WS_EX_MDICHILD)
828 return MDI_CreateMDIWindow32A(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
829 /* Find the class atom */
831 if (!(classAtom = GlobalFindAtom32A( className )))
833 fprintf( stderr, "CreateWindowEx32A: bad class name " );
834 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
835 else fprintf( stderr, "'%s'\n", className );
839 /* Create the window */
841 cs.lpCreateParams = data;
842 cs.hInstance = instance;
844 cs.hwndParent = parent;
850 cs.lpszName = windowName;
851 cs.lpszClass = className;
852 cs.dwExStyle = exStyle;
853 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
857 /***********************************************************************
858 * CreateWindowEx32W (USER32.84)
860 HWND32 WINAPI CreateWindowEx32W( DWORD exStyle, LPCWSTR className,
861 LPCWSTR windowName, DWORD style, INT32 x,
862 INT32 y, INT32 width, INT32 height,
863 HWND32 parent, HMENU32 menu,
864 HINSTANCE32 instance, LPVOID data )
869 if(exStyle & WS_EX_MDICHILD)
870 return MDI_CreateMDIWindow32W(className, windowName, style, x, y, width, height, parent, instance, (LPARAM)data);
872 /* Find the class atom */
874 if (!(classAtom = GlobalFindAtom32W( className )))
876 if (HIWORD(className))
878 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
879 WARN( win, "Bad class name '%s'\n",cn);
880 HeapFree( GetProcessHeap(), 0, cn );
883 WARN( win, "Bad class name %p\n", className );
887 /* Create the window */
889 cs.lpCreateParams = data;
890 cs.hInstance = instance;
892 cs.hwndParent = parent;
898 cs.lpszName = windowName;
899 cs.lpszClass = className;
900 cs.dwExStyle = exStyle;
901 /* Note: we rely on the fact that CREATESTRUCT32A and */
902 /* CREATESTRUCT32W have the same layout. */
903 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
907 /***********************************************************************
910 static void WIN_CheckFocus( WND* pWnd )
912 if( GetFocus16() == pWnd->hwndSelf )
913 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
916 /***********************************************************************
919 static void WIN_SendDestroyMsg( WND* pWnd )
921 WIN_CheckFocus(pWnd);
923 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
924 CLIPBOARD_GetDriver()->pResetOwner( pWnd, TRUE );
926 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
928 if( IsWindow32(pWnd->hwndSelf) )
930 WND* pChild = pWnd->child;
933 WIN_SendDestroyMsg( pChild );
934 pChild = pChild->next;
936 WIN_CheckFocus(pWnd);
939 WARN(win, "\tdestroyed itself while in WM_DESTROY!\n");
943 /***********************************************************************
944 * DestroyWindow16 (USER.53)
946 BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
948 return DestroyWindow32(hwnd);
952 /***********************************************************************
953 * DestroyWindow32 (USER32.135)
955 BOOL32 WINAPI DestroyWindow32( HWND32 hwnd )
959 TRACE(win, "(%04x)\n", hwnd);
963 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
964 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
968 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
971 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
973 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
974 /* FIXME: clean up palette - see "Internals" p.352 */
977 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
978 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
980 /* Notify the parent window only */
981 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
982 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
983 if( !IsWindow32(hwnd) ) return TRUE;
986 CLIPBOARD_GetDriver()->pResetOwner( wndPtr, FALSE ); /* before the window is unmapped */
988 /* Hide the window */
990 if (wndPtr->dwStyle & WS_VISIBLE)
992 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
993 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
994 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
995 if (!IsWindow32(hwnd)) return TRUE;
998 /* Recursively destroy owned windows */
1000 if( !(wndPtr->dwStyle & WS_CHILD) )
1002 /* make sure top menu popup doesn't get destroyed */
1003 MENU_PatchResidentPopup( (HQUEUE16)0xFFFF, wndPtr );
1007 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1010 if (siblingPtr->owner == wndPtr)
1012 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1015 siblingPtr->owner = NULL;
1017 siblingPtr = siblingPtr->next;
1019 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1023 if( !Options.managed || EVENT_CheckFocus() )
1024 WINPOS_ActivateOtherWindow(wndPtr);
1026 if( wndPtr->owner &&
1027 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1028 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1031 /* Send destroy messages */
1033 WIN_SendDestroyMsg( wndPtr );
1034 if (!IsWindow32(hwnd)) return TRUE;
1036 /* Unlink now so we won't bother with the children later on */
1038 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1040 /* Destroy the window storage */
1042 WIN_DestroyWindow( wndPtr );
1047 /***********************************************************************
1048 * CloseWindow16 (USER.43)
1050 BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
1052 return CloseWindow32( hwnd );
1056 /***********************************************************************
1057 * CloseWindow32 (USER32.56)
1059 BOOL32 WINAPI CloseWindow32( HWND32 hwnd )
1061 WND * wndPtr = WIN_FindWndPtr( hwnd );
1062 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1063 ShowWindow32( hwnd, SW_MINIMIZE );
1068 /***********************************************************************
1069 * OpenIcon16 (USER.44)
1071 BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
1073 return OpenIcon32( hwnd );
1077 /***********************************************************************
1078 * OpenIcon32 (USER32.410)
1080 BOOL32 WINAPI OpenIcon32( HWND32 hwnd )
1082 if (!IsIconic32( hwnd )) return FALSE;
1083 ShowWindow32( hwnd, SW_SHOWNORMAL );
1088 /***********************************************************************
1091 * Implementation of FindWindow() and FindWindowEx().
1093 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1097 CLASS *pClass = NULL;
1101 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1104 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1106 else if (pWnd->parent != pWndDesktop) return 0;
1111 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1114 if (!pWnd) return 0;
1116 /* For a child window, all siblings will have the same hInstance, */
1117 /* so we can look for the class once and for all. */
1119 if (className && (pWnd->dwStyle & WS_CHILD))
1121 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1126 for ( ; pWnd; pWnd = pWnd->next)
1128 if (className && !(pWnd->dwStyle & WS_CHILD))
1130 if (!(pClass = CLASS_FindClassByAtom( className, GetExePtr(pWnd->hInstance))))
1131 continue; /* Skip this window */
1134 if (pClass && (pWnd->class != pClass))
1135 continue; /* Not the right class */
1137 /* Now check the title */
1139 if (!title) return pWnd->hwndSelf;
1140 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1147 /***********************************************************************
1148 * FindWindow16 (USER.50)
1150 HWND16 WINAPI FindWindow16( SEGPTR className, LPCSTR title )
1152 return FindWindowEx16( 0, 0, className, title );
1156 /***********************************************************************
1157 * FindWindowEx16 (USER.427)
1159 HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child,
1160 SEGPTR className, LPCSTR title )
1164 TRACE(win, "%04x %04x '%s' '%s'\n", parent,
1165 child, HIWORD(className)?(char *)PTR_SEG_TO_LIN(className):"",
1166 title ? title : "");
1170 /* If the atom doesn't exist, then no class */
1171 /* with this name exists either. */
1172 if (!(atom = GlobalFindAtom16( className ))) return 0;
1174 return WIN_FindWindow( parent, child, atom, title );
1178 /***********************************************************************
1179 * FindWindow32A (USER32.198)
1181 HWND32 WINAPI FindWindow32A( LPCSTR className, LPCSTR title )
1183 HWND32 ret = FindWindowEx32A( 0, 0, className, title );
1184 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1189 /***********************************************************************
1190 * FindWindowEx32A (USER32.199)
1192 HWND32 WINAPI FindWindowEx32A( HWND32 parent, HWND32 child,
1193 LPCSTR className, LPCSTR title )
1199 /* If the atom doesn't exist, then no class */
1200 /* with this name exists either. */
1201 if (!(atom = GlobalFindAtom32A( className )))
1203 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1207 return WIN_FindWindow( parent, child, atom, title );
1211 /***********************************************************************
1212 * FindWindowEx32W (USER32.200)
1214 HWND32 WINAPI FindWindowEx32W( HWND32 parent, HWND32 child,
1215 LPCWSTR className, LPCWSTR title )
1223 /* If the atom doesn't exist, then no class */
1224 /* with this name exists either. */
1225 if (!(atom = GlobalFindAtom32W( className )))
1227 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1231 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1232 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1233 HeapFree( GetProcessHeap(), 0, buffer );
1238 /***********************************************************************
1239 * FindWindow32W (USER32.201)
1241 HWND32 WINAPI FindWindow32W( LPCWSTR className, LPCWSTR title )
1243 return FindWindowEx32W( 0, 0, className, title );
1247 /**********************************************************************
1250 WND *WIN_GetDesktop(void)
1256 /**********************************************************************
1257 * GetDesktopWindow16 (USER.286)
1259 HWND16 WINAPI GetDesktopWindow16(void)
1261 return (HWND16)pWndDesktop->hwndSelf;
1265 /**********************************************************************
1266 * GetDesktopWindow32 (USER32.232)
1268 HWND32 WINAPI GetDesktopWindow32(void)
1270 return pWndDesktop->hwndSelf;
1274 /**********************************************************************
1275 * GetDesktopHwnd (USER.278)
1277 * Exactly the same thing as GetDesktopWindow(), but not documented.
1278 * Don't ask me why...
1280 HWND16 WINAPI GetDesktopHwnd(void)
1282 return (HWND16)pWndDesktop->hwndSelf;
1286 /*******************************************************************
1287 * EnableWindow16 (USER.34)
1289 BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
1291 return EnableWindow32( hwnd, enable );
1295 /*******************************************************************
1296 * EnableWindow32 (USER32.172)
1298 BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
1302 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1303 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1306 wndPtr->dwStyle &= ~WS_DISABLED;
1307 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1310 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1312 /* Disable window */
1313 wndPtr->dwStyle |= WS_DISABLED;
1314 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1315 SetFocus32( 0 ); /* A disabled window can't have the focus */
1316 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1317 ReleaseCapture(); /* A disabled window can't capture the mouse */
1318 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1321 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1325 /***********************************************************************
1326 * IsWindowEnabled16 (USER.35)
1328 BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
1330 return IsWindowEnabled32(hWnd);
1334 /***********************************************************************
1335 * IsWindowEnabled32 (USER32.349)
1337 BOOL32 WINAPI IsWindowEnabled32(HWND32 hWnd)
1341 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1342 return !(wndPtr->dwStyle & WS_DISABLED);
1346 /***********************************************************************
1347 * IsWindowUnicode (USER32.350)
1349 BOOL32 WINAPI IsWindowUnicode( HWND32 hwnd )
1353 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1354 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1358 /**********************************************************************
1359 * GetWindowWord16 (USER.133)
1361 WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
1363 return GetWindowWord32( hwnd, offset );
1367 /**********************************************************************
1368 * GetWindowWord32 (USER32.314)
1370 WORD WINAPI GetWindowWord32( HWND32 hwnd, INT32 offset )
1372 WND * wndPtr = WIN_FindWndPtr( hwnd );
1373 if (!wndPtr) return 0;
1376 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1378 WARN( win, "Invalid offset %d\n", offset );
1381 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1386 if (HIWORD(wndPtr->wIDmenu))
1387 WARN( win,"GWW_ID: discards high bits of 0x%08x!\n",
1389 return (WORD)wndPtr->wIDmenu;
1390 case GWW_HWNDPARENT:
1391 return wndPtr->parent ?
1392 wndPtr->parent->hwndSelf : (
1394 wndPtr->owner->hwndSelf :
1397 if (HIWORD(wndPtr->hInstance))
1398 WARN(win,"GWW_HINSTANCE: discards high bits of 0x%08x!\n",
1400 return (WORD)wndPtr->hInstance;
1402 WARN( win, "Invalid offset %d\n", offset );
1408 /**********************************************************************
1409 * WIN_GetWindowInstance
1411 HINSTANCE32 WIN_GetWindowInstance( HWND32 hwnd )
1413 WND * wndPtr = WIN_FindWndPtr( hwnd );
1414 if (!wndPtr) return (HINSTANCE32)0;
1415 return wndPtr->hInstance;
1419 /**********************************************************************
1420 * SetWindowWord16 (USER.134)
1422 WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1424 return SetWindowWord32( hwnd, offset, newval );
1428 /**********************************************************************
1429 * SetWindowWord32 (USER32.524)
1431 WORD WINAPI SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1434 WND * wndPtr = WIN_FindWndPtr( hwnd );
1435 if (!wndPtr) return 0;
1438 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1440 WARN( win, "Invalid offset %d\n", offset );
1443 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1447 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1448 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1449 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1451 WARN( win, "Invalid offset %d\n", offset );
1460 /**********************************************************************
1463 * Helper function for GetWindowLong().
1465 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1468 WND * wndPtr = WIN_FindWndPtr( hwnd );
1469 if (!wndPtr) return 0;
1472 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1474 WARN( win, "Invalid offset %d\n", offset );
1477 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1478 /* Special case for dialog window procedure */
1479 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1480 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1485 case GWL_USERDATA: return wndPtr->userdata;
1486 case GWL_STYLE: return wndPtr->dwStyle;
1487 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1488 case GWL_ID: return (LONG)wndPtr->wIDmenu;
1489 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1491 case GWL_HWNDPARENT: return wndPtr->parent ?
1492 (HWND32)wndPtr->parent->hwndSelf : 0;
1493 case GWL_HINSTANCE: return wndPtr->hInstance;
1495 WARN( win, "Unknown offset %d\n", offset );
1501 /**********************************************************************
1504 * Helper function for SetWindowLong().
1506 * 0 is the failure code. However, in the case of failure SetLastError
1507 * must be set to distinguish between a 0 return value and a failure.
1509 * FIXME: The error values for SetLastError may not be right. Can
1510 * someone check with the real thing?
1512 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1513 WINDOWPROCTYPE type )
1516 WND * wndPtr = WIN_FindWndPtr( hwnd );
1519 TRACE(win,"%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
1523 /* Is this the right error? */
1524 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1530 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1532 WARN( win, "Invalid offset %d\n", offset );
1534 /* Is this the right error? */
1535 SetLastError( ERROR_OUTOFMEMORY );
1539 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1540 /* Special case for dialog window procedure */
1541 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1543 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1544 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1545 type, WIN_PROC_WINDOW );
1552 ptr = (DWORD*)&wndPtr->wIDmenu;
1555 return SetWindowWord32( hwnd, offset, newval );
1557 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1558 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1559 type, WIN_PROC_WINDOW );
1562 style.styleOld = wndPtr->dwStyle;
1563 newval &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way */
1564 style.styleNew = newval | (style.styleOld & (WS_VISIBLE | WS_CHILD));
1566 if (wndPtr->flags & WIN_ISWIN32)
1567 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
1568 wndPtr->dwStyle = style.styleNew;
1569 if (wndPtr->flags & WIN_ISWIN32)
1570 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
1571 return style.styleOld;
1574 ptr = &wndPtr->userdata;
1577 style.styleOld = wndPtr->dwExStyle;
1578 style.styleNew = newval;
1579 if (wndPtr->flags & WIN_ISWIN32)
1580 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
1581 wndPtr->dwExStyle = newval;
1582 if (wndPtr->flags & WIN_ISWIN32)
1583 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
1584 return style.styleOld;
1587 WARN( win, "Invalid offset %d\n", offset );
1589 /* Don't think this is right error but it should do */
1590 SetLastError( ERROR_OUTOFMEMORY );
1600 /**********************************************************************
1601 * GetWindowLong16 (USER.135)
1603 LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
1605 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1609 /**********************************************************************
1610 * GetWindowLong32A (USER32.305)
1612 LONG WINAPI GetWindowLong32A( HWND32 hwnd, INT32 offset )
1614 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1618 /**********************************************************************
1619 * GetWindowLong32W (USER32.306)
1621 LONG WINAPI GetWindowLong32W( HWND32 hwnd, INT32 offset )
1623 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1627 /**********************************************************************
1628 * SetWindowLong16 (USER.136)
1630 LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1632 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1636 /**********************************************************************
1637 * SetWindowLong32A (USER32.517)
1639 LONG WINAPI SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1641 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1645 /**********************************************************************
1646 * SetWindowLong32W (USER32.518) Set window attribute
1648 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
1649 * value in a window's extra memory.
1651 * The _hwnd_ parameter specifies the window. is the handle to a
1652 * window that has extra memory. The _newval_ parameter contains the
1653 * new attribute or extra memory value. If positive, the _offset_
1654 * parameter is the byte-addressed location in the window's extra
1655 * memory to set. If negative, _offset_ specifies the window
1656 * attribute to set, and should be one of the following values:
1658 * GWL_EXSTYLE The window's extended window style
1660 * GWL_STYLE The window's window style.
1662 * GWL_WNDPROC Pointer to the window's window procedure.
1664 * GWL_HINSTANCE The window's pplication instance handle.
1666 * GWL_ID The window's identifier.
1668 * GWL_USERDATA The window's user-specified data.
1670 * If the window is a dialog box, the _offset_ parameter can be one of
1671 * the following values:
1673 * DWL_DLGPROC The address of the window's dialog box procedure.
1675 * DWL_MSGRESULT The return value of a message
1676 * that the dialog box procedure processed.
1678 * DWL_USER Application specific information.
1682 * If successful, returns the previous value located at _offset_. Otherwise,
1687 * Extra memory for a window class is specified by a nonzero cbWndExtra
1688 * parameter of the WNDCLASS structure passed to RegisterClass() at the
1689 * time of class creation.
1691 * Using GWL_WNDPROC to set a new window procedure effectively creates
1692 * a window subclass. Use CallWindowProc() in the new windows procedure
1693 * to pass messages to the superclass's window procedure.
1695 * The user data is reserved for use by the application which created
1698 * Do not use GWL_STYLE to change the window's WS_DISABLE style;
1699 * instead, call the EnableWindow() function to change the window's
1702 * Do not use GWL_HWNDPARENT to reset the window's parent, use
1703 * SetParent() instead.
1706 * When offset is GWL_STYLE and the calling app's ver is 4.0,
1707 * it sends WM_STYLECHANGING before changing the settings
1708 * and WM_STYLECHANGED afterwards.
1709 * App ver 4.0 can't use SetWindowLong to change WS_EX_TOPMOST.
1713 * GWL_STYLE does not dispatch WM_STYLE... messages.
1720 LONG WINAPI SetWindowLong32W(
1721 HWND32 hwnd, /* window to alter */
1722 INT32 offset, /* offset, in bytes, of location to alter */
1723 LONG newval /* new value of location */
1725 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1729 /*******************************************************************
1730 * GetWindowText16 (USER.36)
1732 INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1734 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1738 /*******************************************************************
1739 * GetWindowText32A (USER32.309)
1741 INT32 WINAPI GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1743 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1747 /*******************************************************************
1748 * InternalGetWindowText (USER32.326)
1750 INT32 WINAPI InternalGetWindowText(HWND32 hwnd,LPWSTR lpString,INT32 nMaxCount )
1752 FIXME(win,"(0x%08x,%p,0x%x),stub!\n",hwnd,lpString,nMaxCount);
1753 return GetWindowText32W(hwnd,lpString,nMaxCount);
1757 /*******************************************************************
1758 * GetWindowText32W (USER32.312)
1760 INT32 WINAPI GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1762 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1767 /*******************************************************************
1768 * SetWindowText16 (USER.37)
1770 BOOL16 WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1772 return (BOOL16)SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1776 /*******************************************************************
1777 * SetWindowText32A (USER32.521)
1779 BOOL32 WINAPI SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1781 return (BOOL32)SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1785 /*******************************************************************
1786 * SetWindowText32W (USER32.523)
1788 BOOL32 WINAPI SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1790 return (BOOL32)SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1794 /*******************************************************************
1795 * GetWindowTextLength16 (USER.38)
1797 INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
1799 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1803 /*******************************************************************
1804 * GetWindowTextLength32A (USER32.310)
1806 INT32 WINAPI GetWindowTextLength32A( HWND32 hwnd )
1808 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1811 /*******************************************************************
1812 * GetWindowTextLength32W (USER32.311)
1814 INT32 WINAPI GetWindowTextLength32W( HWND32 hwnd )
1816 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1820 /*******************************************************************
1821 * IsWindow16 (USER.47)
1823 BOOL16 WINAPI IsWindow16( HWND16 hwnd )
1825 return IsWindow32( hwnd );
1828 void WINAPI WIN16_IsWindow16( CONTEXT *context )
1830 WORD *stack = PTR_SEG_OFF_TO_LIN(SS_reg(context), SP_reg(context));
1831 HWND16 hwnd = (HWND16)stack[2];
1833 AX_reg(context) = IsWindow32( hwnd );
1834 ES_reg(context) = USER_HeapSel;
1838 /*******************************************************************
1839 * IsWindow32 (USER32.348)
1841 BOOL32 WINAPI IsWindow32( HWND32 hwnd )
1843 WND * wndPtr = WIN_FindWndPtr( hwnd );
1844 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1848 /*****************************************************************
1849 * GetParent16 (USER.46)
1851 HWND16 WINAPI GetParent16( HWND16 hwnd )
1853 return (HWND16)GetParent32( hwnd );
1857 /*****************************************************************
1858 * GetParent32 (USER32.278)
1860 HWND32 WINAPI GetParent32( HWND32 hwnd )
1862 WND *wndPtr = WIN_FindWndPtr(hwnd);
1863 if ((!wndPtr) || (!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD)))) return 0;
1864 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1865 return wndPtr ? wndPtr->hwndSelf : 0;
1868 /*****************************************************************
1871 * Get the top-level parent for a child window.
1873 WND* WIN_GetTopParentPtr( WND* pWnd )
1875 while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
1879 /*****************************************************************
1882 * Get the top-level parent for a child window.
1884 HWND32 WIN_GetTopParent( HWND32 hwnd )
1886 WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
1887 return wndPtr ? wndPtr->hwndSelf : 0;
1891 /*****************************************************************
1892 * SetParent16 (USER.233)
1894 HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1896 return SetParent32( hwndChild, hwndNewParent );
1900 /*****************************************************************
1901 * SetParent32 (USER32.495)
1903 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1905 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1906 WND *pWndNewParent =
1907 (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent ) : pWndDesktop;
1908 WND *pWndOldParent =
1909 (wndPtr)?(*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent):NULL;
1911 /* SetParent32 additionally needs to make hwndChild the topmost window
1912 in the x-order and send the expected WM_WINDOWPOSCHANGING and
1913 WM_WINDOWPOSCHANGED notification messages.
1915 SetWindowPos32( hwndChild, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
1917 return pWndOldParent?pWndOldParent->hwndSelf:0;
1920 /*******************************************************************
1921 * IsChild16 (USER.48)
1923 BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
1925 return IsChild32(parent,child);
1929 /*******************************************************************
1930 * IsChild32 (USER32.339)
1932 BOOL32 WINAPI IsChild32( HWND32 parent, HWND32 child )
1934 WND * wndPtr = WIN_FindWndPtr( child );
1935 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1937 wndPtr = wndPtr->parent;
1938 if (wndPtr->hwndSelf == parent) return TRUE;
1944 /***********************************************************************
1945 * IsWindowVisible16 (USER.49)
1947 BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
1949 return IsWindowVisible32(hwnd);
1953 /***********************************************************************
1954 * IsWindowVisible32 (USER32.351)
1956 BOOL32 WINAPI IsWindowVisible32( HWND32 hwnd )
1958 WND *wndPtr = WIN_FindWndPtr( hwnd );
1959 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1961 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1962 wndPtr = wndPtr->parent;
1964 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1968 /***********************************************************************
1969 * WIN_IsWindowDrawable
1971 * hwnd is drawable when it is visible, all parents are not
1972 * minimized, and it is itself not minimized unless we are
1973 * trying to draw its default class icon.
1975 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
1977 if( (wnd->dwStyle & WS_MINIMIZE &&
1978 icon && wnd->class->hIcon) ||
1979 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
1980 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
1981 if( wnd->dwStyle & WS_MINIMIZE ||
1982 !(wnd->dwStyle & WS_VISIBLE) ) break;
1983 return (wnd == NULL);
1987 /*******************************************************************
1988 * GetTopWindow16 (USER.229)
1990 HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
1992 return GetTopWindow32(hwnd);
1996 /*******************************************************************
1997 * GetTopWindow32 (USER.229)
1999 HWND32 WINAPI GetTopWindow32( HWND32 hwnd )
2001 WND * wndPtr = WIN_FindWndPtr( hwnd );
2002 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
2007 /*******************************************************************
2008 * GetWindow16 (USER.262)
2010 HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
2012 return GetWindow32( hwnd,rel );
2016 /*******************************************************************
2017 * GetWindow32 (USER32.302)
2019 HWND32 WINAPI GetWindow32( HWND32 hwnd, WORD rel )
2021 WND * wndPtr = WIN_FindWndPtr( hwnd );
2022 if (!wndPtr) return 0;
2026 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
2030 if (!wndPtr->parent) return 0; /* Desktop window */
2031 while (wndPtr->next) wndPtr = wndPtr->next;
2032 return wndPtr->hwndSelf;
2035 if (!wndPtr->next) return 0;
2036 return wndPtr->next->hwndSelf;
2039 if (!wndPtr->parent) return 0; /* Desktop window */
2040 wndPtr = wndPtr->parent->child; /* First sibling */
2041 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
2042 while (wndPtr->next)
2044 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
2045 wndPtr = wndPtr->next;
2050 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
2053 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
2059 /*******************************************************************
2060 * GetNextWindow16 (USER.230)
2062 HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
2064 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
2065 return GetWindow16( hwnd, flag );
2068 /*******************************************************************
2069 * ShowOwnedPopups16 (USER.265)
2071 void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
2073 ShowOwnedPopups32( owner, fShow );
2077 /*******************************************************************
2078 * ShowOwnedPopups32 (USER32.531)
2080 BOOL32 WINAPI ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
2082 WND *pWnd = pWndDesktop->child;
2085 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
2086 (pWnd->dwStyle & WS_POPUP))
2087 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
2094 /*******************************************************************
2095 * GetLastActivePopup16 (USER.287)
2097 HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
2099 return GetLastActivePopup32( hwnd );
2102 /*******************************************************************
2103 * GetLastActivePopup32 (USER32.256)
2105 HWND32 WINAPI GetLastActivePopup32( HWND32 hwnd )
2108 wndPtr = WIN_FindWndPtr(hwnd);
2109 if (wndPtr == NULL) return hwnd;
2110 return wndPtr->hwndLastActive;
2114 /*******************************************************************
2117 * Build an array of pointers to the children of a given window.
2118 * The array must be freed with HeapFree(SystemHeap). Return NULL
2119 * when no windows are found.
2121 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
2123 WND **list, **ppWnd;
2125 UINT32 count, skipOwned, skipHidden;
2128 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2129 skipOwned = bwaFlags & BWA_SKIPOWNED;
2130 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2131 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
2133 /* First count the windows */
2135 if (!wndPtr) wndPtr = pWndDesktop;
2136 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
2138 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2139 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
2144 /* Now build the list of all windows */
2146 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
2148 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
2150 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2151 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2162 if( pTotal ) *pTotal = count;
2167 /*******************************************************************
2168 * EnumWindows16 (USER.54)
2170 BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2172 WND **list, **ppWnd;
2174 /* We have to build a list of all windows first, to avoid */
2175 /* unpleasant side-effects, for instance if the callback */
2176 /* function changes the Z-order of the windows. */
2178 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2180 /* Now call the callback function for every window */
2182 for (ppWnd = list; *ppWnd; ppWnd++)
2184 /* Make sure that the window still exists */
2185 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2186 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2188 HeapFree( SystemHeap, 0, list );
2193 /*******************************************************************
2194 * EnumWindows32 (USER32.193)
2196 BOOL32 WINAPI EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2198 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2202 /**********************************************************************
2203 * EnumTaskWindows16 (USER.225)
2205 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2208 WND **list, **ppWnd;
2210 /* This function is the same as EnumWindows(), */
2211 /* except for an added check on the window's task. */
2213 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2215 /* Now call the callback function for every window */
2217 for (ppWnd = list; *ppWnd; ppWnd++)
2219 /* Make sure that the window still exists */
2220 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2221 if (QUEUE_GetQueueTask((*ppWnd)->hmemTaskQ) != hTask) continue;
2222 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2224 HeapFree( SystemHeap, 0, list );
2229 /**********************************************************************
2230 * EnumThreadWindows (USER32.190)
2232 BOOL32 WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2234 THDB *tdb = THREAD_ID_TO_THDB(id);
2236 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2240 /**********************************************************************
2241 * WIN_EnumChildWindows
2243 * Helper function for EnumChildWindows().
2245 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2251 for ( ; *ppWnd; ppWnd++)
2253 /* Make sure that the window still exists */
2254 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2255 /* Build children list first */
2256 childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
2257 ret = func( (*ppWnd)->hwndSelf, lParam );
2260 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
2261 HeapFree( SystemHeap, 0, childList );
2263 if (!ret) return FALSE;
2269 /**********************************************************************
2270 * EnumChildWindows16 (USER.55)
2272 BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2275 WND **list, *pParent;
2277 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2278 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2279 WIN_EnumChildWindows( list, func, lParam );
2280 HeapFree( SystemHeap, 0, list );
2285 /**********************************************************************
2286 * EnumChildWindows32 (USER32.178)
2288 BOOL32 WINAPI EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
2291 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2296 /*******************************************************************
2297 * AnyPopup16 (USER.52)
2299 BOOL16 WINAPI AnyPopup16(void)
2301 return AnyPopup32();
2305 /*******************************************************************
2306 * AnyPopup32 (USER32.4)
2308 BOOL32 WINAPI AnyPopup32(void)
2311 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2312 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2317 /*******************************************************************
2318 * FlashWindow16 (USER.105)
2320 BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2322 return FlashWindow32( hWnd, bInvert );
2326 /*******************************************************************
2327 * FlashWindow32 (USER32.202)
2329 BOOL32 WINAPI FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2331 WND *wndPtr = WIN_FindWndPtr(hWnd);
2333 TRACE(win,"%04x\n", hWnd);
2335 if (!wndPtr) return FALSE;
2337 if (wndPtr->dwStyle & WS_MINIMIZE)
2339 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2341 HDC32 hDC = GetDC32(hWnd);
2343 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2344 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2346 ReleaseDC32( hWnd, hDC );
2347 wndPtr->flags |= WIN_NCACTIVATED;
2351 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2352 RDW_UPDATENOW | RDW_FRAME, 0 );
2353 wndPtr->flags &= ~WIN_NCACTIVATED;
2360 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2361 else wparam = (hWnd == GetActiveWindow32());
2363 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2369 /*******************************************************************
2370 * SetSysModalWindow16 (USER.188)
2372 HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
2374 HWND32 hWndOldModal = hwndSysModal;
2375 hwndSysModal = hWnd;
2376 FIXME(win, "EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2377 return hWndOldModal;
2381 /*******************************************************************
2382 * GetSysModalWindow16 (USER.52)
2384 HWND16 WINAPI GetSysModalWindow16(void)
2386 return hwndSysModal;
2390 /*******************************************************************
2391 * GetWindowContextHelpId (USER32.303)
2393 DWORD WINAPI GetWindowContextHelpId( HWND32 hwnd )
2395 WND *wnd = WIN_FindWndPtr( hwnd );
2397 return wnd->helpContext;
2401 /*******************************************************************
2402 * SetWindowContextHelpId (USER32.515)
2404 BOOL32 WINAPI SetWindowContextHelpId( HWND32 hwnd, DWORD id )
2406 WND *wnd = WIN_FindWndPtr( hwnd );
2407 if (!wnd) return FALSE;
2408 wnd->helpContext = id;
2413 /*******************************************************************
2416 * recursively find a child that contains spDragInfo->pt point
2417 * and send WM_QUERYDROPOBJECT
2419 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2421 BOOL16 wParam,bResult = 0;
2423 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2424 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2427 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2429 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2431 GetWindowRect32(hQueryWnd,&tempRect);
2433 if( !PtInRect32(&tempRect,pt) ||
2434 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2437 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2439 tempRect = ptrQueryWnd->rectClient;
2440 if(ptrQueryWnd->dwStyle & WS_CHILD)
2441 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2442 (LPPOINT32)&tempRect, 2 );
2444 if (PtInRect32( &tempRect, pt))
2448 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2449 if( ptrWnd->dwStyle & WS_VISIBLE )
2451 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2452 if (PtInRect32( &tempRect, pt )) break;
2457 TRACE(msg,"hwnd = %04x, %d %d - %d %d\n",
2458 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2459 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2460 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2461 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2464 if(bResult) return bResult;
2470 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2472 ptrDragInfo->hScope = hQueryWnd;
2474 bResult = ( bNoSend )
2475 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2476 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2477 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2479 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2485 /*******************************************************************
2486 * DragDetect (USER.465)
2488 BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
2491 CONV_POINT16TO32( &pt, &pt32 );
2492 return DragDetect32( hWnd, pt32 );
2495 /*******************************************************************
2496 * DragDetect32 (USER32.151)
2498 BOOL32 WINAPI DragDetect32( HWND32 hWnd, POINT32 pt )
2503 rect.left = pt.x - wDragWidth;
2504 rect.right = pt.x + wDragWidth;
2506 rect.top = pt.y - wDragHeight;
2507 rect.bottom = pt.y + wDragHeight;
2513 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2515 if( msg.message == WM_LBUTTONUP )
2520 if( msg.message == WM_MOUSEMOVE )
2522 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2534 /******************************************************************************
2535 * DragObject16 (USER.464)
2537 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2538 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2541 LPDRAGINFO lpDragInfo;
2543 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2544 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2545 WND *wndPtr = WIN_FindWndPtr(hWnd);
2546 HCURSOR16 hCurrentCursor = 0;
2547 HWND16 hCurrentWnd = 0;
2549 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2550 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2552 if( !lpDragInfo || !spDragInfo ) return 0L;
2554 hBummer = LoadCursor16(0, IDC_BUMMER16);
2556 if( !hBummer || !wndPtr )
2558 GlobalFree16(hDragInfo);
2564 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2566 GlobalFree16(hDragInfo);
2570 if( hDragCursor == hCursor ) hDragCursor = 0;
2571 else hCursor = hDragCursor;
2573 hOldCursor = SetCursor32(hDragCursor);
2576 lpDragInfo->hWnd = hWnd;
2577 lpDragInfo->hScope = 0;
2578 lpDragInfo->wFlags = wObj;
2579 lpDragInfo->hList = szList; /* near pointer! */
2580 lpDragInfo->hOfStruct = hOfStruct;
2584 ShowCursor32( TRUE );
2588 do{ WaitMessage(); }
2589 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2591 *(lpDragInfo+1) = *lpDragInfo;
2593 lpDragInfo->pt = msg.pt;
2595 /* update DRAGINFO struct */
2596 TRACE(msg,"lpDI->hScope = %04x\n",lpDragInfo->hScope);
2598 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2599 hCurrentCursor = hCursor;
2602 hCurrentCursor = hBummer;
2603 lpDragInfo->hScope = 0;
2605 if( hCurrentCursor )
2606 SetCursor32(hCurrentCursor);
2608 /* send WM_DRAGLOOP */
2609 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2610 (LPARAM) spDragInfo );
2611 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2612 if( hCurrentWnd != lpDragInfo->hScope )
2615 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2616 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2617 HIWORD(spDragInfo)) );
2618 hCurrentWnd = lpDragInfo->hScope;
2620 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2624 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2626 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2629 ShowCursor32( FALSE );
2633 SetCursor32( hOldCursor );
2634 if (hDragCursor) DestroyCursor32( hDragCursor );
2637 if( hCurrentCursor != hBummer )
2638 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2639 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2642 GlobalFree16(hDragInfo);
2644 return (DWORD)(msg.lParam);