2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
15 #include "sysmetrics.h"
16 #include "cursoricon.h"
21 #include "nonclient.h"
25 #include "shm_main_blk.h"
27 #include "clipboard.h"
36 static WND *pWndDesktop = NULL;
38 static HWND32 hwndSysModal = 0;
40 static WORD wDragWidth = 4;
41 static WORD wDragHeight= 3;
43 /***********************************************************************
46 * Return a pointer to the WND structure corresponding to a HWND.
48 WND * WIN_FindWndPtr( HWND32 hwnd )
52 if (!hwnd || HIWORD(hwnd)) return NULL;
53 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
54 if (ptr->dwMagic != WND_MAGIC) return NULL;
55 if (ptr->hwndSelf != hwnd)
57 ERR( win, "Can't happen: hwnd %04x self pointer is %04x\n",
58 hwnd, ptr->hwndSelf );
65 /***********************************************************************
68 * Dump the content of a window structure to stderr.
70 void WIN_DumpWindow( HWND32 hwnd )
76 if (!(ptr = WIN_FindWndPtr( hwnd )))
78 WARN( win, "%04x is not a window handle\n", hwnd );
82 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
83 strcpy( className, "#NULL#" );
85 TRACE( win, "Window %04x (%p):\n", hwnd, ptr );
86 DUMP( "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
87 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
88 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
89 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
90 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
91 ptr->next, ptr->child, ptr->parent, ptr->owner,
92 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
93 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
94 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
95 ptr->text ? ptr->text : "",
96 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
97 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
98 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
99 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
101 if (ptr->class->cbWndExtra)
103 DUMP( "extra bytes:" );
104 for (i = 0; i < ptr->class->cbWndExtra; i++)
105 DUMP( " %02x", *((BYTE*)ptr->wExtra+i) );
112 /***********************************************************************
115 * Walk the windows tree and print each window on stderr.
117 void WIN_WalkWindows( HWND32 hwnd, int indent )
122 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
125 WARN( win, "Invalid window handle %04x\n", hwnd );
129 if (!indent) /* first time around */
130 DUMP( "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
131 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc"
136 DUMP( "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
138 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
140 DUMP( "%08lx %-6.4x %-17.17s %08x %08x %.14s\n",
141 (DWORD)ptr, ptr->hmemTaskQ, className,
142 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc,
143 ptr->text?ptr->text:"<null>");
145 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
151 /***********************************************************************
154 * Return the X window associated to a window.
156 Window WIN_GetXWindow( HWND32 hwnd )
158 WND *wndPtr = WIN_FindWndPtr( hwnd );
159 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
160 return wndPtr ? wndPtr->window : 0;
164 /***********************************************************************
167 * Remove a window from the siblings linked list.
169 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
171 WND *wndPtr, **ppWnd;
173 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
174 ppWnd = &wndPtr->parent->child;
175 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
176 *ppWnd = wndPtr->next;
181 /***********************************************************************
184 * Insert a window into the siblings linked list.
185 * The window is inserted after the specified window, which can also
186 * be specified as HWND_TOP or HWND_BOTTOM.
188 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
190 WND *wndPtr, **ppWnd;
192 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
194 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
196 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
197 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
198 while (*ppWnd) ppWnd = &(*ppWnd)->next;
200 else /* Normal case */
202 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
203 if (!afterPtr) return FALSE;
204 ppWnd = &afterPtr->next;
206 wndPtr->next = *ppWnd;
212 /***********************************************************************
213 * WIN_FindWinToRepaint
215 * Find a window that needs repaint.
217 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
220 WND *pWnd = pWndDesktop;
222 /* Note: the desktop window never gets WM_PAINT messages
223 * The real reason why is because Windows DesktopWndProc
224 * does ValidateRgn inside WM_ERASEBKGND handler.
227 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
229 for ( ; pWnd ; pWnd = pWnd->next )
231 if (!(pWnd->dwStyle & WS_VISIBLE))
233 TRACE(win, "skipping window %04x\n",
237 if ((pWnd->hmemTaskQ == hQueue) &&
238 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
241 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
247 hwndRet = pWnd->hwndSelf;
249 /* look among siblings if we got a transparent window */
250 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
251 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
255 if (pWnd) hwndRet = pWnd->hwndSelf;
256 TRACE(win,"found %04x\n",hwndRet);
261 /***********************************************************************
264 * Destroy storage associated to a window. "Internals" p.358
266 static WND* WIN_DestroyWindow( WND* wndPtr )
268 HWND32 hwnd = wndPtr->hwndSelf;
271 TRACE(win, "%04x\n", wndPtr->hwndSelf );
275 DDE_DestroyWindow(wndPtr->hwndSelf);
276 #endif /* CONFIG_IPC */
278 /* free child windows */
280 while ((pWnd = wndPtr->child))
281 wndPtr->child = WIN_DestroyWindow( pWnd );
283 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
285 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
287 WINPOS_CheckInternalPos( hwnd );
288 if( hwnd == GetCapture32()) ReleaseCapture();
290 /* free resources associated with the window */
292 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
293 PROPERTY_RemoveWindowProps( wndPtr );
295 wndPtr->dwMagic = 0; /* Mark it as invalid */
297 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
299 if (wndPtr->hrgnUpdate > 1) DeleteObject32( wndPtr->hrgnUpdate );
300 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
303 /* toss stale messages from the queue */
305 if( wndPtr->hmemTaskQ )
308 BOOL32 bPostQuit = FALSE;
309 WPARAM32 wQuitParam = 0;
310 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
312 while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
314 if( msgQ->messages[pos].msg.message == WM_QUIT )
317 wQuitParam = msgQ->messages[pos].msg.wParam;
319 QUEUE_RemoveMsg(msgQ, pos);
321 /* repost WM_QUIT to make sure this app exits its message loop */
322 if( bPostQuit ) PostQuitMessage32(wQuitParam);
323 wndPtr->hmemTaskQ = 0;
326 if (!(wndPtr->dwStyle & WS_CHILD))
327 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
328 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
329 if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
330 DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */
331 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
332 wndPtr->hwndSelf = 0;
333 wndPtr->class->cWindows--;
334 wndPtr->class = NULL;
337 USER_HEAP_FREE( hwnd );
341 /***********************************************************************
342 * WIN_ResetQueueWindows
344 * Reset the queue of all the children of a given window.
345 * Return TRUE if something was done.
347 BOOL32 WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
351 if (hNew) /* Set a new queue */
353 for (wnd = wnd->child; (wnd); wnd = wnd->next)
355 if (wnd->hmemTaskQ == hQueue)
357 wnd->hmemTaskQ = hNew;
361 ret |= WIN_ResetQueueWindows( wnd->child, hQueue, hNew );
364 else /* Queue is being destroyed */
368 WND *tmp = wnd->child;
372 if (tmp->hmemTaskQ == hQueue)
374 DestroyWindow32( tmp->hwndSelf );
378 if (tmp->child && WIN_ResetQueueWindows(tmp->child,hQueue,0))
389 /***********************************************************************
390 * WIN_CreateDesktopWindow
392 * Create the desktop window.
394 BOOL32 WIN_CreateDesktopWindow(void)
399 TRACE(win,"Creating desktop window\n");
401 if (!ICONTITLE_Init() ||
402 !WINPOS_CreateInternalPosAtom() ||
403 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
406 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
407 if (!hwndDesktop) return FALSE;
408 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
410 pWndDesktop->next = NULL;
411 pWndDesktop->child = NULL;
412 pWndDesktop->parent = NULL;
413 pWndDesktop->owner = NULL;
414 pWndDesktop->class = class;
415 pWndDesktop->dwMagic = WND_MAGIC;
416 pWndDesktop->hwndSelf = hwndDesktop;
417 pWndDesktop->hInstance = 0;
418 pWndDesktop->rectWindow.left = 0;
419 pWndDesktop->rectWindow.top = 0;
420 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
421 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
422 pWndDesktop->rectClient = pWndDesktop->rectWindow;
423 pWndDesktop->text = NULL;
424 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
425 pWndDesktop->hrgnUpdate = 0;
426 pWndDesktop->hwndLastActive = hwndDesktop;
427 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
429 pWndDesktop->dwExStyle = 0;
430 pWndDesktop->dce = NULL;
431 pWndDesktop->pVScroll = NULL;
432 pWndDesktop->pHScroll = NULL;
433 pWndDesktop->pProp = NULL;
434 pWndDesktop->wIDmenu = 0;
435 pWndDesktop->helpContext = 0;
436 pWndDesktop->flags = 0;
437 pWndDesktop->window = rootWindow;
438 pWndDesktop->hSysMenu = 0;
439 pWndDesktop->userdata = 0;
440 pWndDesktop->pDriver = &X11DRV_WND_Driver;
442 pWndDesktop->winproc = (WNDPROC16)class->winproc;
444 EVENT_RegisterWindow( pWndDesktop );
445 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
446 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
451 /***********************************************************************
454 * Implementation of CreateWindowEx().
456 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
457 BOOL32 win32, BOOL32 unicode )
461 HWND16 hwnd, hwndLinkAfter;
462 POINT32 maxSize, maxPos, minTrack, maxTrack;
463 LRESULT (CALLBACK *localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
465 TRACE(win, "%s %s %08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
466 unicode ? debugres_w((LPWSTR)cs->lpszName) : debugres_a(cs->lpszName),
467 unicode ? debugres_w((LPWSTR)cs->lpszClass) : debugres_a(cs->lpszClass),
468 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
469 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
471 /* Find the parent window */
475 /* Make sure parent is valid */
476 if (!IsWindow32( cs->hwndParent ))
478 WARN( win, "Bad parent %04x\n", cs->hwndParent );
481 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
482 WARN( win, "No parent for child window\n" );
483 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
486 /* Find the window class */
487 if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
490 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
491 WARN( win, "Bad class '%s'\n", buffer );
495 /* Fix the coordinates */
497 if (cs->x == CW_USEDEFAULT32)
499 PDB32 *pdb = PROCESS_Current();
500 if ( !(cs->style & (WS_CHILD | WS_POPUP))
501 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
503 cs->x = pdb->env_db->startup_info->dwX;
504 cs->y = pdb->env_db->startup_info->dwY;
512 if (cs->cx == CW_USEDEFAULT32)
514 PDB32 *pdb = PROCESS_Current();
515 if ( !(cs->style & (WS_CHILD | WS_POPUP))
516 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
518 cs->cx = pdb->env_db->startup_info->dwXSize;
519 cs->cy = pdb->env_db->startup_info->dwYSize;
523 cs->cx = 600; /* FIXME */
528 /* Create the window structure */
530 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
531 - sizeof(wndPtr->wExtra) )))
533 TRACE(win, "out of memory\n" );
537 /* Fill the window structure */
539 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
541 wndPtr->child = NULL;
543 if ((cs->style & WS_CHILD) && cs->hwndParent)
545 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
546 wndPtr->owner = NULL;
550 wndPtr->parent = pWndDesktop;
551 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
552 wndPtr->owner = NULL;
554 wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
557 wndPtr->pDriver = &X11DRV_WND_Driver;
559 wndPtr->class = classPtr;
560 wndPtr->winproc = classPtr->winproc;
561 wndPtr->dwMagic = WND_MAGIC;
562 wndPtr->hwndSelf = hwnd;
563 wndPtr->hInstance = cs->hInstance;
565 wndPtr->hmemTaskQ = GetTaskQueue(0);
566 wndPtr->hrgnUpdate = 0;
567 wndPtr->hwndLastActive = hwnd;
568 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
569 wndPtr->dwExStyle = cs->dwExStyle;
571 wndPtr->helpContext = 0;
572 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
573 wndPtr->pVScroll = NULL;
574 wndPtr->pHScroll = NULL;
575 wndPtr->pProp = NULL;
576 wndPtr->userdata = 0;
577 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
578 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
580 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
582 /* Call the WH_CBT hook */
584 hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
586 if (HOOK_IsHooked( WH_CBT ))
588 CBT_CREATEWND32A cbtc;
592 cbtc.hwndInsertAfter = hwndLinkAfter;
593 ret = unicode ? HOOK_CallHooks32W(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc)
594 : HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc);
597 TRACE(win, "CBT-hook returned 0\n");
598 USER_HEAP_FREE( hwnd );
603 /* Increment class window counter */
605 classPtr->cWindows++;
607 /* Correct the window style */
609 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
611 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
612 wndPtr->flags |= WIN_NEED_SIZE;
614 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
616 /* Get class or window DC if needed */
618 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
619 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
620 else wndPtr->dce = NULL;
622 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
624 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
626 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
627 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
628 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
629 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
630 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
633 if(cs->style & WS_CHILD)
635 if(cs->cx < 0) cs->cx = 0;
636 if(cs->cy < 0) cs->cy = 0;
640 if (cs->cx <= 0) cs->cx = 1;
641 if (cs->cy <= 0) cs->cy = 1;
644 wndPtr->rectWindow.left = cs->x;
645 wndPtr->rectWindow.top = cs->y;
646 wndPtr->rectWindow.right = cs->x + cs->cx;
647 wndPtr->rectWindow.bottom = cs->y + cs->cy;
648 wndPtr->rectClient = wndPtr->rectWindow;
650 (*wndPtr->pDriver->pCreateWindow)(wndPtr, classPtr, cs, unicode);
652 /* Set the window menu */
654 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
656 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
659 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
660 if (classPtr->menuNameA)
661 cs->hMenu = HIWORD(classPtr->menuNameA) ?
662 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
663 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
665 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
668 if (HIWORD(cs->hInstance))
669 cs->hMenu = LoadMenu32A(cs->hInstance,PTR_SEG_TO_LIN(menuName));
671 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
673 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
678 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
680 /* Send the WM_CREATE message
681 * Perhaps we shouldn't allow width/height changes as well.
682 * See p327 in "Internals".
685 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
687 localSend32 = unicode ? SendMessage32W : SendMessage32A;
688 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
690 /* Insert the window in the linked list */
692 WIN_LinkWindow( hwnd, hwndLinkAfter );
694 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
695 NULL, NULL, 0, &wndPtr->rectClient );
696 OffsetRect32(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
697 maxPos.y - wndPtr->rectWindow.top);
698 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
700 /* Send the size messages */
702 if (!(wndPtr->flags & WIN_NEED_SIZE))
705 if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
706 ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
707 WARN(win,"sending bogus WM_SIZE message 0x%08lx\n",
708 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
709 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
710 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
711 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
712 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
713 SendMessage32A( hwnd, WM_MOVE, 0,
714 MAKELONG( wndPtr->rectClient.left,
715 wndPtr->rectClient.top ) );
718 /* Show the window, maximizing or minimizing if needed */
720 if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
723 UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
724 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
725 WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
726 swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow32()) ? SWP_NOACTIVATE : 0;
727 SetWindowPos32( hwnd, 0, newPos.left, newPos.top,
728 newPos.right, newPos.bottom, SWP_FRAMECHANGED | swFlag );
731 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
733 /* Notify the parent window only */
735 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
736 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
737 if( !IsWindow32(hwnd) ) return 0;
740 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
742 /* Call WH_SHELL hook */
744 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
745 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
747 TRACE(win, "created window %04x\n", hwnd);
750 WIN_UnlinkWindow( hwnd );
753 /* Abort window creation */
755 WARN(win, "aborted by WM_xxCREATE!\n");
756 WIN_DestroyWindow( wndPtr );
761 /***********************************************************************
762 * CreateWindow16 (USER.41)
764 HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
765 DWORD style, INT16 x, INT16 y, INT16 width,
766 INT16 height, HWND16 parent, HMENU16 menu,
767 HINSTANCE16 instance, LPVOID data )
769 return CreateWindowEx16( 0, className, windowName, style,
770 x, y, width, height, parent, menu, instance, data );
774 /***********************************************************************
775 * CreateWindowEx16 (USER.452)
777 HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
778 LPCSTR windowName, DWORD style, INT16 x,
779 INT16 y, INT16 width, INT16 height,
780 HWND16 parent, HMENU16 menu,
781 HINSTANCE16 instance, LPVOID data )
786 /* Find the class atom */
788 if (!(classAtom = GlobalFindAtom32A( className )))
790 fprintf( stderr, "CreateWindowEx16: bad class name " );
791 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
792 else fprintf( stderr, "'%s'\n", className );
796 /* Fix the coordinates */
798 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
799 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
800 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
801 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
803 /* Create the window */
805 cs.lpCreateParams = data;
806 cs.hInstance = (HINSTANCE32)instance;
807 cs.hMenu = (HMENU32)menu;
808 cs.hwndParent = (HWND32)parent;
810 cs.lpszName = windowName;
811 cs.lpszClass = className;
812 cs.dwExStyle = exStyle;
813 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
817 /***********************************************************************
818 * CreateWindowEx32A (USER32.83)
820 HWND32 WINAPI CreateWindowEx32A( DWORD exStyle, LPCSTR className,
821 LPCSTR windowName, DWORD style, INT32 x,
822 INT32 y, INT32 width, INT32 height,
823 HWND32 parent, HMENU32 menu,
824 HINSTANCE32 instance, LPVOID data )
829 if(exStyle & WS_EX_MDICHILD)
830 return MDI_CreateMDIWindow32A(className, windowName, style, x, y, width, height, parent, instance, data);
831 /* Find the class atom */
833 if (!(classAtom = GlobalFindAtom32A( className )))
835 fprintf( stderr, "CreateWindowEx32A: bad class name " );
836 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
837 else fprintf( stderr, "'%s'\n", className );
841 /* Create the window */
843 cs.lpCreateParams = data;
844 cs.hInstance = instance;
846 cs.hwndParent = parent;
852 cs.lpszName = windowName;
853 cs.lpszClass = className;
854 cs.dwExStyle = exStyle;
855 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
859 /***********************************************************************
860 * CreateWindowEx32W (USER32.84)
862 HWND32 WINAPI CreateWindowEx32W( DWORD exStyle, LPCWSTR className,
863 LPCWSTR windowName, DWORD style, INT32 x,
864 INT32 y, INT32 width, INT32 height,
865 HWND32 parent, HMENU32 menu,
866 HINSTANCE32 instance, LPVOID data )
871 if(exStyle & WS_EX_MDICHILD)
872 return MDI_CreateMDIWindow32W(className, windowName, style, x, y, width, height, parent, instance, data);
874 /* Find the class atom */
876 if (!(classAtom = GlobalFindAtom32W( className )))
878 if (HIWORD(className))
880 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
881 WARN( win, "Bad class name '%s'\n",cn);
882 HeapFree( GetProcessHeap(), 0, cn );
885 WARN( win, "Bad class name %p\n", className );
889 /* Create the window */
891 cs.lpCreateParams = data;
892 cs.hInstance = instance;
894 cs.hwndParent = parent;
900 cs.lpszName = windowName;
901 cs.lpszClass = className;
902 cs.dwExStyle = exStyle;
903 /* Note: we rely on the fact that CREATESTRUCT32A and */
904 /* CREATESTRUCT32W have the same layout. */
905 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
909 /***********************************************************************
912 static void WIN_CheckFocus( WND* pWnd )
914 if( GetFocus16() == pWnd->hwndSelf )
915 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
918 /***********************************************************************
921 static void WIN_SendDestroyMsg( WND* pWnd )
923 WIN_CheckFocus(pWnd);
925 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
926 if( !pWnd->window ) CLIPBOARD_ResetOwner( pWnd );
928 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
930 if( IsWindow32(pWnd->hwndSelf) )
932 WND* pChild = pWnd->child;
935 WIN_SendDestroyMsg( pChild );
936 pChild = pChild->next;
938 WIN_CheckFocus(pWnd);
941 WARN(win, "\tdestroyed itself while in WM_DESTROY!\n");
945 /***********************************************************************
946 * DestroyWindow16 (USER.53)
948 BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
950 return DestroyWindow32(hwnd);
954 /***********************************************************************
955 * DestroyWindow32 (USER32.135)
957 BOOL32 WINAPI DestroyWindow32( HWND32 hwnd )
961 TRACE(win, "(%04x)\n", hwnd);
965 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
966 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
970 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
973 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
975 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
976 /* FIXME: clean up palette - see "Internals" p.352 */
979 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
980 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
982 /* Notify the parent window only */
983 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
984 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
985 if( !IsWindow32(hwnd) ) return TRUE;
988 if( wndPtr->window ) CLIPBOARD_ResetOwner( wndPtr ); /* before the window is unmapped */
990 /* Hide the window */
992 if (wndPtr->dwStyle & WS_VISIBLE)
994 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
995 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
996 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
997 if (!IsWindow32(hwnd)) return TRUE;
1000 /* Recursively destroy owned windows */
1002 if( !(wndPtr->dwStyle & WS_CHILD) )
1004 /* make sure top menu popup doesn't get destroyed */
1005 MENU_PatchResidentPopup( (HQUEUE16)0xFFFF, wndPtr );
1009 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1012 if (siblingPtr->owner == wndPtr)
1014 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1017 siblingPtr->owner = NULL;
1019 siblingPtr = siblingPtr->next;
1021 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1025 if( !Options.managed || EVENT_CheckFocus() )
1026 WINPOS_ActivateOtherWindow(wndPtr);
1028 if( wndPtr->owner &&
1029 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1030 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1033 /* Send destroy messages */
1035 WIN_SendDestroyMsg( wndPtr );
1036 if (!IsWindow32(hwnd)) return TRUE;
1038 /* Unlink now so we won't bother with the children later on */
1040 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1042 /* Destroy the window storage */
1044 WIN_DestroyWindow( wndPtr );
1049 /***********************************************************************
1050 * CloseWindow16 (USER.43)
1052 BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
1054 return CloseWindow32( hwnd );
1058 /***********************************************************************
1059 * CloseWindow32 (USER32.56)
1061 BOOL32 WINAPI CloseWindow32( HWND32 hwnd )
1063 WND * wndPtr = WIN_FindWndPtr( hwnd );
1064 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1065 ShowWindow32( hwnd, SW_MINIMIZE );
1070 /***********************************************************************
1071 * OpenIcon16 (USER.44)
1073 BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
1075 return OpenIcon32( hwnd );
1079 /***********************************************************************
1080 * OpenIcon32 (USER32.410)
1082 BOOL32 WINAPI OpenIcon32( HWND32 hwnd )
1084 if (!IsIconic32( hwnd )) return FALSE;
1085 ShowWindow32( hwnd, SW_SHOWNORMAL );
1090 /***********************************************************************
1093 * Implementation of FindWindow() and FindWindowEx().
1095 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1099 CLASS *pClass = NULL;
1103 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1106 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1108 else if (pWnd->parent != pWndDesktop) return 0;
1113 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1116 if (!pWnd) return 0;
1118 /* For a child window, all siblings will have the same hInstance, */
1119 /* so we can look for the class once and for all. */
1121 if (className && (pWnd->dwStyle & WS_CHILD))
1123 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1128 for ( ; pWnd; pWnd = pWnd->next)
1130 if (className && !(pWnd->dwStyle & WS_CHILD))
1132 if (!(pClass = CLASS_FindClassByAtom( className, GetExePtr(pWnd->hInstance))))
1133 continue; /* Skip this window */
1136 if (pClass && (pWnd->class != pClass))
1137 continue; /* Not the right class */
1139 /* Now check the title */
1141 if (!title) return pWnd->hwndSelf;
1142 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1149 /***********************************************************************
1150 * FindWindow16 (USER.50)
1152 HWND16 WINAPI FindWindow16( SEGPTR className, LPCSTR title )
1154 return FindWindowEx16( 0, 0, className, title );
1158 /***********************************************************************
1159 * FindWindowEx16 (USER.427)
1161 HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child,
1162 SEGPTR className, LPCSTR title )
1166 TRACE(win, "%04x %04x '%s' '%s'\n", parent,
1167 child, HIWORD(className)?(char *)PTR_SEG_TO_LIN(className):"",
1168 title ? title : "");
1172 /* If the atom doesn't exist, then no class */
1173 /* with this name exists either. */
1174 if (!(atom = GlobalFindAtom16( className ))) return 0;
1176 return WIN_FindWindow( parent, child, atom, title );
1180 /***********************************************************************
1181 * FindWindow32A (USER32.198)
1183 HWND32 WINAPI FindWindow32A( LPCSTR className, LPCSTR title )
1185 HWND32 ret = FindWindowEx32A( 0, 0, className, title );
1186 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1191 /***********************************************************************
1192 * FindWindowEx32A (USER32.199)
1194 HWND32 WINAPI FindWindowEx32A( HWND32 parent, HWND32 child,
1195 LPCSTR className, LPCSTR title )
1201 /* If the atom doesn't exist, then no class */
1202 /* with this name exists either. */
1203 if (!(atom = GlobalFindAtom32A( className )))
1205 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1209 return WIN_FindWindow( parent, child, atom, title );
1213 /***********************************************************************
1214 * FindWindowEx32W (USER32.200)
1216 HWND32 WINAPI FindWindowEx32W( HWND32 parent, HWND32 child,
1217 LPCWSTR className, LPCWSTR title )
1225 /* If the atom doesn't exist, then no class */
1226 /* with this name exists either. */
1227 if (!(atom = GlobalFindAtom32W( className )))
1229 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1233 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1234 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1235 HeapFree( GetProcessHeap(), 0, buffer );
1240 /***********************************************************************
1241 * FindWindow32W (USER32.201)
1243 HWND32 WINAPI FindWindow32W( LPCWSTR className, LPCWSTR title )
1245 return FindWindowEx32W( 0, 0, className, title );
1249 /**********************************************************************
1252 WND *WIN_GetDesktop(void)
1258 /**********************************************************************
1259 * GetDesktopWindow16 (USER.286)
1261 HWND16 WINAPI GetDesktopWindow16(void)
1263 return (HWND16)pWndDesktop->hwndSelf;
1267 /**********************************************************************
1268 * GetDesktopWindow32 (USER32.232)
1270 HWND32 WINAPI GetDesktopWindow32(void)
1272 return pWndDesktop->hwndSelf;
1276 /**********************************************************************
1277 * GetDesktopHwnd (USER.278)
1279 * Exactly the same thing as GetDesktopWindow(), but not documented.
1280 * Don't ask me why...
1282 HWND16 WINAPI GetDesktopHwnd(void)
1284 return (HWND16)pWndDesktop->hwndSelf;
1288 /*******************************************************************
1289 * EnableWindow16 (USER.34)
1291 BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
1293 return EnableWindow32( hwnd, enable );
1297 /*******************************************************************
1298 * EnableWindow32 (USER32.172)
1300 BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
1304 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1305 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1308 wndPtr->dwStyle &= ~WS_DISABLED;
1309 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1312 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1314 /* Disable window */
1315 wndPtr->dwStyle |= WS_DISABLED;
1316 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1317 SetFocus32( 0 ); /* A disabled window can't have the focus */
1318 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1319 ReleaseCapture(); /* A disabled window can't capture the mouse */
1320 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1323 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1327 /***********************************************************************
1328 * IsWindowEnabled16 (USER.35)
1330 BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
1332 return IsWindowEnabled32(hWnd);
1336 /***********************************************************************
1337 * IsWindowEnabled32 (USER32.349)
1339 BOOL32 WINAPI IsWindowEnabled32(HWND32 hWnd)
1343 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1344 return !(wndPtr->dwStyle & WS_DISABLED);
1348 /***********************************************************************
1349 * IsWindowUnicode (USER32.350)
1351 BOOL32 WINAPI IsWindowUnicode( HWND32 hwnd )
1355 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1356 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1360 /**********************************************************************
1361 * GetWindowWord16 (USER.133)
1363 WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
1365 return GetWindowWord32( hwnd, offset );
1369 /**********************************************************************
1370 * GetWindowWord32 (USER32.314)
1372 WORD WINAPI GetWindowWord32( HWND32 hwnd, INT32 offset )
1374 WND * wndPtr = WIN_FindWndPtr( hwnd );
1375 if (!wndPtr) return 0;
1378 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1380 WARN( win, "Invalid offset %d\n", offset );
1383 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1388 if (HIWORD(wndPtr->wIDmenu))
1389 WARN( win,"GWW_ID: discards high bits of 0x%08x!\n",
1391 return (WORD)wndPtr->wIDmenu;
1392 case GWW_HWNDPARENT:
1393 return wndPtr->parent ?
1394 wndPtr->parent->hwndSelf : (
1396 wndPtr->owner->hwndSelf :
1399 if (HIWORD(wndPtr->hInstance))
1400 WARN(win,"GWW_HINSTANCE: discards high bits of 0x%08x!\n",
1402 return (WORD)wndPtr->hInstance;
1404 WARN( win, "Invalid offset %d\n", offset );
1410 /**********************************************************************
1411 * WIN_GetWindowInstance
1413 HINSTANCE32 WIN_GetWindowInstance( HWND32 hwnd )
1415 WND * wndPtr = WIN_FindWndPtr( hwnd );
1416 if (!wndPtr) return (HINSTANCE32)0;
1417 return wndPtr->hInstance;
1421 /**********************************************************************
1422 * SetWindowWord16 (USER.134)
1424 WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1426 return SetWindowWord32( hwnd, offset, newval );
1430 /**********************************************************************
1431 * SetWindowWord32 (USER32.524)
1433 WORD WINAPI SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1436 WND * wndPtr = WIN_FindWndPtr( hwnd );
1437 if (!wndPtr) return 0;
1440 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1442 WARN( win, "Invalid offset %d\n", offset );
1445 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1449 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1450 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1451 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1453 WARN( win, "Invalid offset %d\n", offset );
1462 /**********************************************************************
1465 * Helper function for GetWindowLong().
1467 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1470 WND * wndPtr = WIN_FindWndPtr( hwnd );
1471 if (!wndPtr) return 0;
1474 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1476 WARN( win, "Invalid offset %d\n", offset );
1479 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1480 /* Special case for dialog window procedure */
1481 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1482 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1487 case GWL_USERDATA: return wndPtr->userdata;
1488 case GWL_STYLE: return wndPtr->dwStyle;
1489 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1490 case GWL_ID: return (LONG)wndPtr->wIDmenu;
1491 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1493 case GWL_HWNDPARENT: return wndPtr->parent ?
1494 (HWND32)wndPtr->parent->hwndSelf : 0;
1495 case GWL_HINSTANCE: return wndPtr->hInstance;
1497 WARN( win, "Unknown offset %d\n", offset );
1503 /**********************************************************************
1506 * Helper function for SetWindowLong().
1508 * 0 is the failure code. However, in the case of failure SetLastError
1509 * must be set to distinguish between a 0 return value and a failure.
1511 * FIXME: The error values for SetLastError may not be right. Can
1512 * someone check with the real thing?
1514 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1515 WINDOWPROCTYPE type )
1518 WND * wndPtr = WIN_FindWndPtr( hwnd );
1521 TRACE(win,"%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
1525 /* Is this the right error? */
1526 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1532 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1534 WARN( win, "Invalid offset %d\n", offset );
1536 /* Is this the right error? */
1537 SetLastError( ERROR_OUTOFMEMORY );
1541 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1542 /* Special case for dialog window procedure */
1543 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1545 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1546 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1547 type, WIN_PROC_WINDOW );
1554 ptr = (DWORD*)&wndPtr->wIDmenu;
1557 return SetWindowWord32( hwnd, offset, newval );
1559 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1560 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1561 type, WIN_PROC_WINDOW );
1564 style.styleOld = wndPtr->dwStyle;
1565 newval &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way */
1566 style.styleNew = newval | (style.styleOld & (WS_VISIBLE | WS_CHILD));
1568 if (wndPtr->flags & WIN_ISWIN32)
1569 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
1570 wndPtr->dwStyle = style.styleNew;
1571 if (wndPtr->flags & WIN_ISWIN32)
1572 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
1573 return style.styleOld;
1576 ptr = &wndPtr->userdata;
1579 style.styleOld = wndPtr->dwExStyle;
1580 style.styleNew = newval;
1581 if (wndPtr->flags & WIN_ISWIN32)
1582 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
1583 wndPtr->dwExStyle = newval;
1584 if (wndPtr->flags & WIN_ISWIN32)
1585 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
1586 return style.styleOld;
1589 WARN( win, "Invalid offset %d\n", offset );
1591 /* Don't think this is right error but it should do */
1592 SetLastError( ERROR_OUTOFMEMORY );
1602 /**********************************************************************
1603 * GetWindowLong16 (USER.135)
1605 LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
1607 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1611 /**********************************************************************
1612 * GetWindowLong32A (USER32.305)
1614 LONG WINAPI GetWindowLong32A( HWND32 hwnd, INT32 offset )
1616 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1620 /**********************************************************************
1621 * GetWindowLong32W (USER32.306)
1623 LONG WINAPI GetWindowLong32W( HWND32 hwnd, INT32 offset )
1625 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1629 /**********************************************************************
1630 * SetWindowLong16 (USER.136)
1632 LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1634 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1638 /**********************************************************************
1639 * SetWindowLong32A (USER32.517)
1641 LONG WINAPI SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1643 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1647 /**********************************************************************
1648 * SetWindowLong32W (USER32.518) Set window attribute
1650 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
1651 * value in a window's extra memory.
1653 * The _hwnd_ parameter specifies the window. is the handle to a
1654 * window that has extra memory. The _newval_ parameter contains the
1655 * new attribute or extra memory value. If positive, the _offset_
1656 * parameter is the byte-addressed location in the window's extra
1657 * memory to set. If negative, _offset_ specifies the window
1658 * attribute to set, and should be one of the following values:
1660 * GWL_EXSTYLE The window's extended window style
1662 * GWL_STYLE The window's window style.
1664 * GWL_WNDPROC Pointer to the window's window procedure.
1666 * GWL_HINSTANCE The window's pplication instance handle.
1668 * GWL_ID The window's identifier.
1670 * GWL_USERDATA The window's user-specified data.
1672 * If the window is a dialog box, the _offset_ parameter can be one of
1673 * the following values:
1675 * DWL_DLGPROC The address of the window's dialog box procedure.
1677 * DWL_MSGRESULT The return value of a message
1678 * that the dialog box procedure processed.
1680 * DWL_USER Application specific information.
1684 * If successful, returns the previous value located at _offset_. Otherwise,
1689 * Extra memory for a window class is specified by a nonzero cbWndExtra
1690 * parameter of the WNDCLASS structure passed to RegisterClass() at the
1691 * time of class creation.
1693 * Using GWL_WNDPROC to set a new window procedure effectively creates
1694 * a window subclass. Use CallWindowProc() in the new windows procedure
1695 * to pass messages to the superclass's window procedure.
1697 * The user data is reserved for use by the application which created
1700 * Do not use GWL_STYLE to change the window's WS_DISABLE style;
1701 * instead, call the EnableWindow() function to change the window's
1704 * Do not use GWL_HWNDPARENT to reset the window's parent, use
1705 * SetParent() instead.
1709 * GWL_STYLE does not dispatch WM_STYLE_... messages.
1716 LONG WINAPI SetWindowLong32W(
1717 HWND32 hwnd, /* window to alter */
1718 INT32 offset, /* offset, in bytes, of location to alter */
1719 LONG newval /* new value of location */
1721 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1725 /*******************************************************************
1726 * GetWindowText16 (USER.36)
1728 INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1730 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1734 /*******************************************************************
1735 * GetWindowText32A (USER32.309)
1737 INT32 WINAPI GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1739 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1743 /*******************************************************************
1744 * InternalGetWindowText (USER32.326)
1746 INT32 WINAPI InternalGetWindowText(HWND32 hwnd,LPWSTR lpString,INT32 nMaxCount )
1748 FIXME(win,"(0x%08x,%p,0x%x),stub!\n",hwnd,lpString,nMaxCount);
1749 return GetWindowText32W(hwnd,lpString,nMaxCount);
1753 /*******************************************************************
1754 * GetWindowText32W (USER32.312)
1756 INT32 WINAPI GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1758 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1763 /*******************************************************************
1764 * SetWindowText16 (USER.37)
1766 void WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1768 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1772 /*******************************************************************
1773 * SetWindowText32A (USER32.521)
1775 void WINAPI SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1777 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1781 /*******************************************************************
1782 * SetWindowText32W (USER32.523)
1784 void WINAPI SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1786 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1790 /*******************************************************************
1791 * GetWindowTextLength16 (USER.38)
1793 INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
1795 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1799 /*******************************************************************
1800 * GetWindowTextLength32A (USER32.310)
1802 INT32 WINAPI GetWindowTextLength32A( HWND32 hwnd )
1804 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1807 /*******************************************************************
1808 * GetWindowTextLength32W (USER32.311)
1810 INT32 WINAPI GetWindowTextLength32W( HWND32 hwnd )
1812 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1816 /*******************************************************************
1817 * IsWindow16 (USER.47)
1819 BOOL16 WINAPI IsWindow16( HWND16 hwnd )
1821 return IsWindow32( hwnd );
1824 void WINAPI WIN16_IsWindow16( CONTEXT *context )
1826 WORD *stack = PTR_SEG_OFF_TO_LIN(SS_reg(context), SP_reg(context));
1827 HWND16 hwnd = (HWND16)stack[2];
1829 AX_reg(context) = IsWindow32( hwnd );
1830 ES_reg(context) = USER_HeapSel;
1834 /*******************************************************************
1835 * IsWindow32 (USER32.348)
1837 BOOL32 WINAPI IsWindow32( HWND32 hwnd )
1839 WND * wndPtr = WIN_FindWndPtr( hwnd );
1840 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1844 /*****************************************************************
1845 * GetParent16 (USER.46)
1847 HWND16 WINAPI GetParent16( HWND16 hwnd )
1849 return (HWND16)GetParent32( hwnd );
1853 /*****************************************************************
1854 * GetParent32 (USER32.278)
1856 HWND32 WINAPI GetParent32( HWND32 hwnd )
1858 WND *wndPtr = WIN_FindWndPtr(hwnd);
1859 if ((!wndPtr) || (!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD)))) return 0;
1860 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1861 return wndPtr ? wndPtr->hwndSelf : 0;
1864 /*****************************************************************
1867 * Get the top-level parent for a child window.
1869 WND* WIN_GetTopParentPtr( WND* pWnd )
1871 while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
1875 /*****************************************************************
1878 * Get the top-level parent for a child window.
1880 HWND32 WIN_GetTopParent( HWND32 hwnd )
1882 WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
1883 return wndPtr ? wndPtr->hwndSelf : 0;
1887 /*****************************************************************
1888 * SetParent16 (USER.233)
1890 HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1892 return SetParent32( hwndChild, hwndNewParent );
1896 /*****************************************************************
1897 * SetParent32 (USER32.495)
1899 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1901 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1902 WND *pWndNewParent =
1903 (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent ) : pWndDesktop;
1904 WND *pWndOldParent =
1905 (*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent);
1907 return pWndOldParent?pWndOldParent->hwndSelf:0;
1910 /*******************************************************************
1911 * IsChild16 (USER.48)
1913 BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
1915 return IsChild32(parent,child);
1919 /*******************************************************************
1920 * IsChild32 (USER32.339)
1922 BOOL32 WINAPI IsChild32( HWND32 parent, HWND32 child )
1924 WND * wndPtr = WIN_FindWndPtr( child );
1925 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1927 wndPtr = wndPtr->parent;
1928 if (wndPtr->hwndSelf == parent) return TRUE;
1934 /***********************************************************************
1935 * IsWindowVisible16 (USER.49)
1937 BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
1939 return IsWindowVisible32(hwnd);
1943 /***********************************************************************
1944 * IsWindowVisible32 (USER32.351)
1946 BOOL32 WINAPI IsWindowVisible32( HWND32 hwnd )
1948 WND *wndPtr = WIN_FindWndPtr( hwnd );
1949 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1951 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1952 wndPtr = wndPtr->parent;
1954 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1958 /***********************************************************************
1959 * WIN_IsWindowDrawable
1961 * hwnd is drawable when it is visible, all parents are not
1962 * minimized, and it is itself not minimized unless we are
1963 * trying to draw its default class icon.
1965 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
1967 if( (wnd->dwStyle & WS_MINIMIZE &&
1968 icon && wnd->class->hIcon) ||
1969 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
1970 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
1971 if( wnd->dwStyle & WS_MINIMIZE ||
1972 !(wnd->dwStyle & WS_VISIBLE) ) break;
1973 return (wnd == NULL);
1977 /*******************************************************************
1978 * GetTopWindow16 (USER.229)
1980 HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
1982 return GetTopWindow32(hwnd);
1986 /*******************************************************************
1987 * GetTopWindow32 (USER.229)
1989 HWND32 WINAPI GetTopWindow32( HWND32 hwnd )
1991 WND * wndPtr = WIN_FindWndPtr( hwnd );
1992 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1997 /*******************************************************************
1998 * GetWindow16 (USER.262)
2000 HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
2002 return GetWindow32( hwnd,rel );
2006 /*******************************************************************
2007 * GetWindow32 (USER32.302)
2009 HWND32 WINAPI GetWindow32( HWND32 hwnd, WORD rel )
2011 WND * wndPtr = WIN_FindWndPtr( hwnd );
2012 if (!wndPtr) return 0;
2016 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
2020 if (!wndPtr->parent) return 0; /* Desktop window */
2021 while (wndPtr->next) wndPtr = wndPtr->next;
2022 return wndPtr->hwndSelf;
2025 if (!wndPtr->next) return 0;
2026 return wndPtr->next->hwndSelf;
2029 if (!wndPtr->parent) return 0; /* Desktop window */
2030 wndPtr = wndPtr->parent->child; /* First sibling */
2031 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
2032 while (wndPtr->next)
2034 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
2035 wndPtr = wndPtr->next;
2040 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
2043 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
2049 /*******************************************************************
2050 * GetNextWindow16 (USER.230)
2052 HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
2054 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
2055 return GetWindow16( hwnd, flag );
2058 /*******************************************************************
2059 * ShowOwnedPopups16 (USER.265)
2061 void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
2063 ShowOwnedPopups32( owner, fShow );
2067 /*******************************************************************
2068 * ShowOwnedPopups32 (USER32.531)
2070 BOOL32 WINAPI ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
2072 WND *pWnd = pWndDesktop->child;
2075 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
2076 (pWnd->dwStyle & WS_POPUP))
2077 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
2084 /*******************************************************************
2085 * GetLastActivePopup16 (USER.287)
2087 HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
2089 return GetLastActivePopup32( hwnd );
2092 /*******************************************************************
2093 * GetLastActivePopup32 (USER32.256)
2095 HWND32 WINAPI GetLastActivePopup32( HWND32 hwnd )
2098 wndPtr = WIN_FindWndPtr(hwnd);
2099 if (wndPtr == NULL) return hwnd;
2100 return wndPtr->hwndLastActive;
2104 /*******************************************************************
2107 * Build an array of pointers to the children of a given window.
2108 * The array must be freed with HeapFree(SystemHeap). Return NULL
2109 * when no windows are found.
2111 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
2113 WND **list, **ppWnd;
2115 UINT32 count, skipOwned, skipHidden;
2118 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2119 skipOwned = bwaFlags & BWA_SKIPOWNED;
2120 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2121 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
2123 /* First count the windows */
2125 if (!wndPtr) wndPtr = pWndDesktop;
2126 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
2128 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2129 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
2134 /* Now build the list of all windows */
2136 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
2138 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
2140 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2141 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2152 if( pTotal ) *pTotal = count;
2157 /*******************************************************************
2158 * EnumWindows16 (USER.54)
2160 BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2162 WND **list, **ppWnd;
2164 /* We have to build a list of all windows first, to avoid */
2165 /* unpleasant side-effects, for instance if the callback */
2166 /* function changes the Z-order of the windows. */
2168 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2170 /* Now call the callback function for every window */
2172 for (ppWnd = list; *ppWnd; ppWnd++)
2174 /* Make sure that the window still exists */
2175 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2176 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2178 HeapFree( SystemHeap, 0, list );
2183 /*******************************************************************
2184 * EnumWindows32 (USER32.193)
2186 BOOL32 WINAPI EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2188 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2192 /**********************************************************************
2193 * EnumTaskWindows16 (USER.225)
2195 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2198 WND **list, **ppWnd;
2199 HQUEUE16 hQueue = GetTaskQueue( hTask );
2201 /* This function is the same as EnumWindows(), */
2202 /* except for an added check on the window queue. */
2204 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2206 /* Now call the callback function for every window */
2208 for (ppWnd = list; *ppWnd; ppWnd++)
2210 /* Make sure that the window still exists */
2211 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2212 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
2213 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2215 HeapFree( SystemHeap, 0, list );
2220 /**********************************************************************
2221 * EnumThreadWindows (USER32.190)
2223 BOOL32 WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2225 THDB *tdb = THREAD_ID_TO_THDB(id);
2227 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2231 /**********************************************************************
2232 * WIN_EnumChildWindows
2234 * Helper function for EnumChildWindows().
2236 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2242 for ( ; *ppWnd; ppWnd++)
2244 /* Make sure that the window still exists */
2245 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2246 /* Build children list first */
2247 childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
2248 ret = func( (*ppWnd)->hwndSelf, lParam );
2251 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
2252 HeapFree( SystemHeap, 0, childList );
2254 if (!ret) return FALSE;
2260 /**********************************************************************
2261 * EnumChildWindows16 (USER.55)
2263 BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2266 WND **list, *pParent;
2268 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2269 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2270 WIN_EnumChildWindows( list, func, lParam );
2271 HeapFree( SystemHeap, 0, list );
2276 /**********************************************************************
2277 * EnumChildWindows32 (USER32.178)
2279 BOOL32 WINAPI EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
2282 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2287 /*******************************************************************
2288 * AnyPopup16 (USER.52)
2290 BOOL16 WINAPI AnyPopup16(void)
2292 return AnyPopup32();
2296 /*******************************************************************
2297 * AnyPopup32 (USER32.4)
2299 BOOL32 WINAPI AnyPopup32(void)
2302 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2303 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2308 /*******************************************************************
2309 * FlashWindow16 (USER.105)
2311 BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2313 return FlashWindow32( hWnd, bInvert );
2317 /*******************************************************************
2318 * FlashWindow32 (USER32.202)
2320 BOOL32 WINAPI FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2322 WND *wndPtr = WIN_FindWndPtr(hWnd);
2324 TRACE(win,"%04x\n", hWnd);
2326 if (!wndPtr) return FALSE;
2328 if (wndPtr->dwStyle & WS_MINIMIZE)
2330 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2332 HDC32 hDC = GetDC32(hWnd);
2334 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2335 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2337 ReleaseDC32( hWnd, hDC );
2338 wndPtr->flags |= WIN_NCACTIVATED;
2342 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2343 RDW_UPDATENOW | RDW_FRAME, 0 );
2344 wndPtr->flags &= ~WIN_NCACTIVATED;
2351 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2352 else wparam = (hWnd == GetActiveWindow32());
2354 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2360 /*******************************************************************
2361 * SetSysModalWindow16 (USER.188)
2363 HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
2365 HWND32 hWndOldModal = hwndSysModal;
2366 hwndSysModal = hWnd;
2367 FIXME(win, "EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2368 return hWndOldModal;
2372 /*******************************************************************
2373 * GetSysModalWindow16 (USER.52)
2375 HWND16 WINAPI GetSysModalWindow16(void)
2377 return hwndSysModal;
2381 /*******************************************************************
2382 * GetWindowContextHelpId (USER32.303)
2384 DWORD WINAPI GetWindowContextHelpId( HWND32 hwnd )
2386 WND *wnd = WIN_FindWndPtr( hwnd );
2388 return wnd->helpContext;
2392 /*******************************************************************
2393 * SetWindowContextHelpId (USER32.515)
2395 BOOL32 WINAPI SetWindowContextHelpId( HWND32 hwnd, DWORD id )
2397 WND *wnd = WIN_FindWndPtr( hwnd );
2398 if (!wnd) return FALSE;
2399 wnd->helpContext = id;
2404 /*******************************************************************
2407 * recursively find a child that contains spDragInfo->pt point
2408 * and send WM_QUERYDROPOBJECT
2410 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2412 BOOL16 wParam,bResult = 0;
2414 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2415 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2418 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2420 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2422 GetWindowRect32(hQueryWnd,&tempRect);
2424 if( !PtInRect32(&tempRect,pt) ||
2425 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2428 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2430 tempRect = ptrQueryWnd->rectClient;
2431 if(ptrQueryWnd->dwStyle & WS_CHILD)
2432 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2433 (LPPOINT32)&tempRect, 2 );
2435 if (PtInRect32( &tempRect, pt))
2439 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2440 if( ptrWnd->dwStyle & WS_VISIBLE )
2442 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2443 if (PtInRect32( &tempRect, pt )) break;
2448 TRACE(msg,"hwnd = %04x, %d %d - %d %d\n",
2449 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2450 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2451 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2452 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2455 if(bResult) return bResult;
2461 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2463 ptrDragInfo->hScope = hQueryWnd;
2465 bResult = ( bNoSend )
2466 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2467 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2468 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2470 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2476 /*******************************************************************
2477 * DragDetect (USER.465)
2479 BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
2482 CONV_POINT16TO32( &pt, &pt32 );
2483 return DragDetect32( hWnd, pt32 );
2486 /*******************************************************************
2487 * DragDetect32 (USER32.151)
2489 BOOL32 WINAPI DragDetect32( HWND32 hWnd, POINT32 pt )
2494 rect.left = pt.x - wDragWidth;
2495 rect.right = pt.x + wDragWidth;
2497 rect.top = pt.y - wDragHeight;
2498 rect.bottom = pt.y + wDragHeight;
2504 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2506 if( msg.message == WM_LBUTTONUP )
2511 if( msg.message == WM_MOUSEMOVE )
2513 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2525 /******************************************************************************
2526 * DragObject16 (USER.464)
2528 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2529 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2532 LPDRAGINFO lpDragInfo;
2534 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2535 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2536 WND *wndPtr = WIN_FindWndPtr(hWnd);
2537 HCURSOR16 hCurrentCursor = 0;
2538 HWND16 hCurrentWnd = 0;
2540 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2541 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2543 if( !lpDragInfo || !spDragInfo ) return 0L;
2545 hBummer = LoadCursor16(0, IDC_BUMMER16);
2547 if( !hBummer || !wndPtr )
2549 GlobalFree16(hDragInfo);
2555 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2557 GlobalFree16(hDragInfo);
2561 if( hDragCursor == hCursor ) hDragCursor = 0;
2562 else hCursor = hDragCursor;
2564 hOldCursor = SetCursor32(hDragCursor);
2567 lpDragInfo->hWnd = hWnd;
2568 lpDragInfo->hScope = 0;
2569 lpDragInfo->wFlags = wObj;
2570 lpDragInfo->hList = szList; /* near pointer! */
2571 lpDragInfo->hOfStruct = hOfStruct;
2575 ShowCursor32( TRUE );
2579 do{ WaitMessage(); }
2580 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2582 *(lpDragInfo+1) = *lpDragInfo;
2584 lpDragInfo->pt = msg.pt;
2586 /* update DRAGINFO struct */
2587 TRACE(msg,"lpDI->hScope = %04x\n",lpDragInfo->hScope);
2589 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2590 hCurrentCursor = hCursor;
2593 hCurrentCursor = hBummer;
2594 lpDragInfo->hScope = 0;
2596 if( hCurrentCursor )
2597 SetCursor32(hCurrentCursor);
2599 /* send WM_DRAGLOOP */
2600 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2601 (LPARAM) spDragInfo );
2602 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2603 if( hCurrentWnd != lpDragInfo->hScope )
2606 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2607 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2608 HIWORD(spDragInfo)) );
2609 hCurrentWnd = lpDragInfo->hScope;
2611 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2615 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2617 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2620 ShowCursor32( FALSE );
2624 SetCursor32( hOldCursor );
2625 if (hDragCursor) DestroyCursor32( hDragCursor );
2628 if( hCurrentCursor != hBummer )
2629 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2630 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2633 GlobalFree16(hDragInfo);
2635 return (DWORD)(msg.lParam);