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"
34 extern WND_DRIVER X11DRV_WND_Driver;
37 static WND *pWndDesktop = NULL;
39 static HWND32 hwndSysModal = 0;
41 static WORD wDragWidth = 4;
42 static WORD wDragHeight= 3;
44 /***********************************************************************
47 * Return a pointer to the WND structure corresponding to a HWND.
49 WND * WIN_FindWndPtr( HWND32 hwnd )
53 if (!hwnd || HIWORD(hwnd)) return NULL;
54 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
55 if (ptr->dwMagic != WND_MAGIC) return NULL;
56 if (ptr->hwndSelf != hwnd)
58 ERR( win, "Can't happen: hwnd %04x self pointer is %04x\n",
59 hwnd, ptr->hwndSelf );
66 /***********************************************************************
69 * Dump the content of a window structure to stderr.
71 void WIN_DumpWindow( HWND32 hwnd )
77 if (!(ptr = WIN_FindWndPtr( hwnd )))
79 WARN( win, "%04x is not a window handle\n", hwnd );
83 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
84 strcpy( className, "#NULL#" );
86 TRACE( win, "Window %04x (%p):\n", hwnd, ptr );
87 DUMP( "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
88 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%08x\n"
89 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
90 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
91 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
92 ptr->next, ptr->child, ptr->parent, ptr->owner,
93 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
94 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
95 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
96 ptr->text ? ptr->text : "",
97 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
98 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
99 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
100 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
102 if (ptr->class->cbWndExtra)
104 DUMP( "extra bytes:" );
105 for (i = 0; i < ptr->class->cbWndExtra; i++)
106 DUMP( " %02x", *((BYTE*)ptr->wExtra+i) );
113 /***********************************************************************
116 * Walk the windows tree and print each window on stderr.
118 void WIN_WalkWindows( HWND32 hwnd, int indent )
123 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
126 WARN( win, "Invalid window handle %04x\n", hwnd );
130 if (!indent) /* first time around */
131 DUMP( "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
132 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc"
137 DUMP( "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
139 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
141 DUMP( "%08lx %-6.4x %-17.17s %08x %08x %.14s\n",
142 (DWORD)ptr, ptr->hmemTaskQ, className,
143 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc,
144 ptr->text?ptr->text:"<null>");
146 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
151 /***********************************************************************
154 * Remove a window from the siblings linked list.
156 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
158 WND *wndPtr, **ppWnd;
160 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
161 ppWnd = &wndPtr->parent->child;
162 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
163 *ppWnd = wndPtr->next;
168 /***********************************************************************
171 * Insert a window into the siblings linked list.
172 * The window is inserted after the specified window, which can also
173 * be specified as HWND_TOP or HWND_BOTTOM.
175 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
177 WND *wndPtr, **ppWnd;
179 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
181 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
183 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
184 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
185 while (*ppWnd) ppWnd = &(*ppWnd)->next;
187 else /* Normal case */
189 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
190 if (!afterPtr) return FALSE;
191 ppWnd = &afterPtr->next;
193 wndPtr->next = *ppWnd;
199 /***********************************************************************
200 * WIN_FindWinToRepaint
202 * Find a window that needs repaint.
204 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
207 WND *pWnd = pWndDesktop;
209 /* Note: the desktop window never gets WM_PAINT messages
210 * The real reason why is because Windows DesktopWndProc
211 * does ValidateRgn inside WM_ERASEBKGND handler.
214 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
216 for ( ; pWnd ; pWnd = pWnd->next )
218 if (!(pWnd->dwStyle & WS_VISIBLE))
220 TRACE(win, "skipping window %04x\n",
224 if ((pWnd->hmemTaskQ == hQueue) &&
225 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
228 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
234 hwndRet = pWnd->hwndSelf;
236 /* look among siblings if we got a transparent window */
237 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
238 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
242 if (pWnd) hwndRet = pWnd->hwndSelf;
243 TRACE(win,"found %04x\n",hwndRet);
248 /***********************************************************************
251 * Destroy storage associated to a window. "Internals" p.358
253 static WND* WIN_DestroyWindow( WND* wndPtr )
255 HWND32 hwnd = wndPtr->hwndSelf;
258 TRACE(win, "%04x\n", wndPtr->hwndSelf );
262 DDE_DestroyWindow(wndPtr->hwndSelf);
263 #endif /* CONFIG_IPC */
265 /* free child windows */
267 while ((pWnd = wndPtr->child))
268 wndPtr->child = WIN_DestroyWindow( pWnd );
270 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
272 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
274 WINPOS_CheckInternalPos( hwnd );
275 if( hwnd == GetCapture32()) ReleaseCapture();
277 /* free resources associated with the window */
279 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
280 PROPERTY_RemoveWindowProps( wndPtr );
282 wndPtr->dwMagic = 0; /* Mark it as invalid */
284 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
286 if (wndPtr->hrgnUpdate > 1) DeleteObject32( wndPtr->hrgnUpdate );
287 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
290 /* toss stale messages from the queue */
292 if( wndPtr->hmemTaskQ )
295 BOOL32 bPostQuit = FALSE;
296 WPARAM32 wQuitParam = 0;
297 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
299 while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
301 if( msgQ->messages[pos].msg.message == WM_QUIT )
304 wQuitParam = msgQ->messages[pos].msg.wParam;
306 QUEUE_RemoveMsg(msgQ, pos);
308 /* repost WM_QUIT to make sure this app exits its message loop */
309 if( bPostQuit ) PostQuitMessage32(wQuitParam);
310 wndPtr->hmemTaskQ = 0;
313 if (!(wndPtr->dwStyle & WS_CHILD))
314 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
315 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
316 wndPtr->pDriver->pDestroyWindow( wndPtr );
317 DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */
318 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
319 wndPtr->hwndSelf = 0;
320 wndPtr->class->cWindows--;
321 wndPtr->class = NULL;
324 USER_HEAP_FREE( hwnd );
328 /***********************************************************************
329 * WIN_ResetQueueWindows
331 * Reset the queue of all the children of a given window.
332 * Return TRUE if something was done.
334 BOOL32 WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
338 if (hNew) /* Set a new queue */
340 for (wnd = wnd->child; (wnd); wnd = wnd->next)
342 if (wnd->hmemTaskQ == hQueue)
344 wnd->hmemTaskQ = hNew;
348 ret |= WIN_ResetQueueWindows( wnd, hQueue, hNew );
351 else /* Queue is being destroyed */
355 WND *tmp = wnd->child;
359 if (tmp->hmemTaskQ == hQueue)
361 DestroyWindow32( tmp->hwndSelf );
365 if (tmp->child && WIN_ResetQueueWindows(tmp->child,hQueue,0))
376 /***********************************************************************
377 * WIN_CreateDesktopWindow
379 * Create the desktop window.
381 BOOL32 WIN_CreateDesktopWindow(void)
386 TRACE(win,"Creating desktop window\n");
388 if (!ICONTITLE_Init() ||
389 !WINPOS_CreateInternalPosAtom() ||
390 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
393 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
394 if (!hwndDesktop) return FALSE;
395 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
397 pWndDesktop->next = NULL;
398 pWndDesktop->child = NULL;
399 pWndDesktop->parent = NULL;
400 pWndDesktop->owner = NULL;
401 pWndDesktop->class = class;
402 pWndDesktop->dwMagic = WND_MAGIC;
403 pWndDesktop->hwndSelf = hwndDesktop;
404 pWndDesktop->hInstance = 0;
405 pWndDesktop->rectWindow.left = 0;
406 pWndDesktop->rectWindow.top = 0;
407 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
408 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
409 pWndDesktop->rectClient = pWndDesktop->rectWindow;
410 pWndDesktop->text = NULL;
411 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
412 pWndDesktop->hrgnUpdate = 0;
413 pWndDesktop->hwndLastActive = hwndDesktop;
414 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
416 pWndDesktop->dwExStyle = 0;
417 pWndDesktop->dce = NULL;
418 pWndDesktop->pVScroll = NULL;
419 pWndDesktop->pHScroll = NULL;
420 pWndDesktop->pProp = NULL;
421 pWndDesktop->wIDmenu = 0;
422 pWndDesktop->helpContext = 0;
423 pWndDesktop->flags = 0;
424 pWndDesktop->hSysMenu = 0;
425 pWndDesktop->userdata = 0;
426 pWndDesktop->pDriver = &X11DRV_WND_Driver;
427 pWndDesktop->winproc = (WNDPROC16)class->winproc;
429 /* FIXME: How do we know if it should be Unicode or not */
430 if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop, class, FALSE))
433 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
434 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
439 /***********************************************************************
442 * Implementation of CreateWindowEx().
444 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
445 BOOL32 win32, BOOL32 unicode )
449 HWND16 hwnd, hwndLinkAfter;
450 POINT32 maxSize, maxPos, minTrack, maxTrack;
451 LRESULT (CALLBACK *localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
453 TRACE(win, "%s %s %08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n",
454 unicode ? debugres_w((LPWSTR)cs->lpszName) : debugres_a(cs->lpszName),
455 unicode ? debugres_w((LPWSTR)cs->lpszClass) : debugres_a(cs->lpszClass),
456 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
457 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams );
459 /* Find the parent window */
463 /* Make sure parent is valid */
464 if (!IsWindow32( cs->hwndParent ))
466 WARN( win, "Bad parent %04x\n", cs->hwndParent );
469 } else if ((cs->style & WS_CHILD) && !(cs->style & WS_POPUP)) {
470 WARN( win, "No parent for child window\n" );
471 return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
474 /* Find the window class */
475 if (!(classPtr = CLASS_FindClassByAtom( classAtom, win32?cs->hInstance:GetExePtr(cs->hInstance) )))
478 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
479 WARN( win, "Bad class '%s'\n", buffer );
483 /* Fix the coordinates */
485 if (cs->x == CW_USEDEFAULT32)
487 PDB32 *pdb = PROCESS_Current();
488 if ( !(cs->style & (WS_CHILD | WS_POPUP))
489 && (pdb->env_db->startup_info->dwFlags & STARTF_USEPOSITION) )
491 cs->x = pdb->env_db->startup_info->dwX;
492 cs->y = pdb->env_db->startup_info->dwY;
500 if (cs->cx == CW_USEDEFAULT32)
502 PDB32 *pdb = PROCESS_Current();
503 if ( !(cs->style & (WS_CHILD | WS_POPUP))
504 && (pdb->env_db->startup_info->dwFlags & STARTF_USESIZE) )
506 cs->cx = pdb->env_db->startup_info->dwXSize;
507 cs->cy = pdb->env_db->startup_info->dwYSize;
511 cs->cx = 600; /* FIXME */
516 /* Create the window structure */
518 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
519 - sizeof(wndPtr->wExtra) )))
521 TRACE(win, "out of memory\n" );
525 /* Fill the window structure */
527 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
529 wndPtr->child = NULL;
531 if ((cs->style & WS_CHILD) && cs->hwndParent)
533 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
534 wndPtr->owner = NULL;
538 wndPtr->parent = pWndDesktop;
539 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
540 wndPtr->owner = NULL;
542 wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
545 wndPtr->pDriver = &X11DRV_WND_Driver;
547 wndPtr->class = classPtr;
548 wndPtr->winproc = classPtr->winproc;
549 wndPtr->dwMagic = WND_MAGIC;
550 wndPtr->hwndSelf = hwnd;
551 wndPtr->hInstance = cs->hInstance;
553 wndPtr->hmemTaskQ = GetTaskQueue(0);
554 wndPtr->hrgnUpdate = 0;
555 wndPtr->hwndLastActive = hwnd;
556 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
557 wndPtr->dwExStyle = cs->dwExStyle;
559 wndPtr->helpContext = 0;
560 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
561 wndPtr->pVScroll = NULL;
562 wndPtr->pHScroll = NULL;
563 wndPtr->pProp = NULL;
564 wndPtr->userdata = 0;
565 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
566 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
568 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
570 /* Call the WH_CBT hook */
572 hwndLinkAfter = ((cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
573 ? HWND_BOTTOM : HWND_TOP;
575 if (HOOK_IsHooked( WH_CBT ))
577 CBT_CREATEWND32A cbtc;
581 cbtc.hwndInsertAfter = hwndLinkAfter;
582 ret = unicode ? HOOK_CallHooks32W(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc)
583 : HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc);
586 TRACE(win, "CBT-hook returned 0\n");
587 USER_HEAP_FREE( hwnd );
592 /* Increment class window counter */
594 classPtr->cWindows++;
596 /* Correct the window style */
598 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
600 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
601 wndPtr->flags |= WIN_NEED_SIZE;
603 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
605 /* Get class or window DC if needed */
607 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
608 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
609 else wndPtr->dce = NULL;
611 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
613 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
615 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
616 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
617 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
618 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
619 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
622 if(cs->style & WS_CHILD)
624 if(cs->cx < 0) cs->cx = 0;
625 if(cs->cy < 0) cs->cy = 0;
629 if (cs->cx <= 0) cs->cx = 1;
630 if (cs->cy <= 0) cs->cy = 1;
633 wndPtr->rectWindow.left = cs->x;
634 wndPtr->rectWindow.top = cs->y;
635 wndPtr->rectWindow.right = cs->x + cs->cx;
636 wndPtr->rectWindow.bottom = cs->y + cs->cy;
637 wndPtr->rectClient = wndPtr->rectWindow;
639 if(!wndPtr->pDriver->pCreateWindow(wndPtr, classPtr, cs, unicode))
642 /* Set the window menu */
644 if ((wndPtr->dwStyle & (WS_CAPTION | WS_CHILD)) == WS_CAPTION )
646 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
649 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
650 if (classPtr->menuNameA)
651 cs->hMenu = HIWORD(classPtr->menuNameA) ?
652 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
653 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
655 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
658 if (HIWORD(cs->hInstance))
659 cs->hMenu = LoadMenu32A(cs->hInstance,PTR_SEG_TO_LIN(menuName));
661 cs->hMenu = LoadMenu16(cs->hInstance,menuName);
663 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
668 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
670 /* Send the WM_CREATE message
671 * Perhaps we shouldn't allow width/height changes as well.
672 * See p327 in "Internals".
675 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
677 localSend32 = unicode ? SendMessage32W : SendMessage32A;
678 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
680 /* Insert the window in the linked list */
682 WIN_LinkWindow( hwnd, hwndLinkAfter );
684 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
685 NULL, NULL, 0, &wndPtr->rectClient );
686 OffsetRect32(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
687 maxPos.y - wndPtr->rectWindow.top);
688 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
690 /* Send the size messages */
692 if (!(wndPtr->flags & WIN_NEED_SIZE))
695 if (((wndPtr->rectClient.right-wndPtr->rectClient.left) <0)
696 ||((wndPtr->rectClient.bottom-wndPtr->rectClient.top)<0))
697 WARN(win,"sending bogus WM_SIZE message 0x%08lx\n",
698 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
699 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
700 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
701 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
702 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
703 SendMessage32A( hwnd, WM_MOVE, 0,
704 MAKELONG( wndPtr->rectClient.left,
705 wndPtr->rectClient.top ) );
708 /* Show the window, maximizing or minimizing if needed */
710 if (wndPtr->dwStyle & (WS_MINIMIZE | WS_MAXIMIZE))
713 UINT16 swFlag = (wndPtr->dwStyle & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
714 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
715 WINPOS_MinMaximize( wndPtr, swFlag, &newPos );
716 swFlag = ((wndPtr->dwStyle & WS_CHILD) || GetActiveWindow32())
717 ? SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED
718 : SWP_NOZORDER | SWP_FRAMECHANGED;
719 SetWindowPos32( hwnd, 0, newPos.left, newPos.top,
720 newPos.right, newPos.bottom, swFlag );
723 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
725 /* Notify the parent window only */
727 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
728 MAKEWPARAM(WM_CREATE, wndPtr->wIDmenu), (LPARAM)hwnd );
729 if( !IsWindow32(hwnd) ) return 0;
732 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
734 /* Call WH_SHELL hook */
736 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
737 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
739 TRACE(win, "created window %04x\n", hwnd);
742 WIN_UnlinkWindow( hwnd );
745 /* Abort window creation */
747 WARN(win, "aborted by WM_xxCREATE!\n");
748 WIN_DestroyWindow( wndPtr );
753 /***********************************************************************
754 * CreateWindow16 (USER.41)
756 HWND16 WINAPI CreateWindow16( LPCSTR className, LPCSTR windowName,
757 DWORD style, INT16 x, INT16 y, INT16 width,
758 INT16 height, HWND16 parent, HMENU16 menu,
759 HINSTANCE16 instance, LPVOID data )
761 return CreateWindowEx16( 0, className, windowName, style,
762 x, y, width, height, parent, menu, instance, data );
766 /***********************************************************************
767 * CreateWindowEx16 (USER.452)
769 HWND16 WINAPI CreateWindowEx16( DWORD exStyle, LPCSTR className,
770 LPCSTR windowName, DWORD style, INT16 x,
771 INT16 y, INT16 width, INT16 height,
772 HWND16 parent, HMENU16 menu,
773 HINSTANCE16 instance, LPVOID data )
778 /* Find the class atom */
780 if (!(classAtom = GlobalFindAtom32A( className )))
782 fprintf( stderr, "CreateWindowEx16: bad class name " );
783 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
784 else fprintf( stderr, "'%s'\n", className );
788 /* Fix the coordinates */
790 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
791 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
792 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
793 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
795 /* Create the window */
797 cs.lpCreateParams = data;
798 cs.hInstance = (HINSTANCE32)instance;
799 cs.hMenu = (HMENU32)menu;
800 cs.hwndParent = (HWND32)parent;
802 cs.lpszName = windowName;
803 cs.lpszClass = className;
804 cs.dwExStyle = exStyle;
805 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
809 /***********************************************************************
810 * CreateWindowEx32A (USER32.83)
812 HWND32 WINAPI CreateWindowEx32A( DWORD exStyle, LPCSTR className,
813 LPCSTR windowName, DWORD style, INT32 x,
814 INT32 y, INT32 width, INT32 height,
815 HWND32 parent, HMENU32 menu,
816 HINSTANCE32 instance, LPVOID data )
821 if(exStyle & WS_EX_MDICHILD)
822 return MDI_CreateMDIWindow32A(className, windowName, style, x, y, width, height, parent, instance, data);
823 /* Find the class atom */
825 if (!(classAtom = GlobalFindAtom32A( className )))
827 fprintf( stderr, "CreateWindowEx32A: bad class name " );
828 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
829 else fprintf( stderr, "'%s'\n", className );
833 /* Create the window */
835 cs.lpCreateParams = data;
836 cs.hInstance = instance;
838 cs.hwndParent = parent;
844 cs.lpszName = windowName;
845 cs.lpszClass = className;
846 cs.dwExStyle = exStyle;
847 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
851 /***********************************************************************
852 * CreateWindowEx32W (USER32.84)
854 HWND32 WINAPI CreateWindowEx32W( DWORD exStyle, LPCWSTR className,
855 LPCWSTR windowName, DWORD style, INT32 x,
856 INT32 y, INT32 width, INT32 height,
857 HWND32 parent, HMENU32 menu,
858 HINSTANCE32 instance, LPVOID data )
863 if(exStyle & WS_EX_MDICHILD)
864 return MDI_CreateMDIWindow32W(className, windowName, style, x, y, width, height, parent, instance, data);
866 /* Find the class atom */
868 if (!(classAtom = GlobalFindAtom32W( className )))
870 if (HIWORD(className))
872 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
873 WARN( win, "Bad class name '%s'\n",cn);
874 HeapFree( GetProcessHeap(), 0, cn );
877 WARN( win, "Bad class name %p\n", className );
881 /* Create the window */
883 cs.lpCreateParams = data;
884 cs.hInstance = instance;
886 cs.hwndParent = parent;
892 cs.lpszName = windowName;
893 cs.lpszClass = className;
894 cs.dwExStyle = exStyle;
895 /* Note: we rely on the fact that CREATESTRUCT32A and */
896 /* CREATESTRUCT32W have the same layout. */
897 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
901 /***********************************************************************
904 static void WIN_CheckFocus( WND* pWnd )
906 if( GetFocus16() == pWnd->hwndSelf )
907 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
910 /***********************************************************************
913 static void WIN_SendDestroyMsg( WND* pWnd )
915 WIN_CheckFocus(pWnd);
917 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
918 if( !pWnd->window ) CLIPBOARD_GetDriver()->pResetOwner( pWnd );
920 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
922 if( IsWindow32(pWnd->hwndSelf) )
924 WND* pChild = pWnd->child;
927 WIN_SendDestroyMsg( pChild );
928 pChild = pChild->next;
930 WIN_CheckFocus(pWnd);
933 WARN(win, "\tdestroyed itself while in WM_DESTROY!\n");
937 /***********************************************************************
938 * DestroyWindow16 (USER.53)
940 BOOL16 WINAPI DestroyWindow16( HWND16 hwnd )
942 return DestroyWindow32(hwnd);
946 /***********************************************************************
947 * DestroyWindow32 (USER32.135)
949 BOOL32 WINAPI DestroyWindow32( HWND32 hwnd )
953 TRACE(win, "(%04x)\n", hwnd);
957 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
958 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
962 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
965 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
967 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
968 /* FIXME: clean up palette - see "Internals" p.352 */
971 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
972 if( wndPtr->dwStyle & WS_CHILD && !(wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) )
974 /* Notify the parent window only */
975 SendMessage32A( wndPtr->parent->hwndSelf, WM_PARENTNOTIFY,
976 MAKEWPARAM(WM_DESTROY, wndPtr->wIDmenu), (LPARAM)hwnd );
977 if( !IsWindow32(hwnd) ) return TRUE;
980 if( wndPtr->window ) CLIPBOARD_GetDriver()->pResetOwner( wndPtr ); /* before the window is unmapped */
982 /* Hide the window */
984 if (wndPtr->dwStyle & WS_VISIBLE)
986 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
987 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
988 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
989 if (!IsWindow32(hwnd)) return TRUE;
992 /* Recursively destroy owned windows */
994 if( !(wndPtr->dwStyle & WS_CHILD) )
996 /* make sure top menu popup doesn't get destroyed */
997 MENU_PatchResidentPopup( (HQUEUE16)0xFFFF, wndPtr );
1001 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1004 if (siblingPtr->owner == wndPtr)
1006 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1009 siblingPtr->owner = NULL;
1011 siblingPtr = siblingPtr->next;
1013 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1017 if( !Options.managed || EVENT_CheckFocus() )
1018 WINPOS_ActivateOtherWindow(wndPtr);
1020 if( wndPtr->owner &&
1021 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1022 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1025 /* Send destroy messages */
1027 WIN_SendDestroyMsg( wndPtr );
1028 if (!IsWindow32(hwnd)) return TRUE;
1030 /* Unlink now so we won't bother with the children later on */
1032 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1034 /* Destroy the window storage */
1036 WIN_DestroyWindow( wndPtr );
1041 /***********************************************************************
1042 * CloseWindow16 (USER.43)
1044 BOOL16 WINAPI CloseWindow16( HWND16 hwnd )
1046 return CloseWindow32( hwnd );
1050 /***********************************************************************
1051 * CloseWindow32 (USER32.56)
1053 BOOL32 WINAPI CloseWindow32( HWND32 hwnd )
1055 WND * wndPtr = WIN_FindWndPtr( hwnd );
1056 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1057 ShowWindow32( hwnd, SW_MINIMIZE );
1062 /***********************************************************************
1063 * OpenIcon16 (USER.44)
1065 BOOL16 WINAPI OpenIcon16( HWND16 hwnd )
1067 return OpenIcon32( hwnd );
1071 /***********************************************************************
1072 * OpenIcon32 (USER32.410)
1074 BOOL32 WINAPI OpenIcon32( HWND32 hwnd )
1076 if (!IsIconic32( hwnd )) return FALSE;
1077 ShowWindow32( hwnd, SW_SHOWNORMAL );
1082 /***********************************************************************
1085 * Implementation of FindWindow() and FindWindowEx().
1087 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1091 CLASS *pClass = NULL;
1095 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1098 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1100 else if (pWnd->parent != pWndDesktop) return 0;
1105 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1108 if (!pWnd) return 0;
1110 /* For a child window, all siblings will have the same hInstance, */
1111 /* so we can look for the class once and for all. */
1113 if (className && (pWnd->dwStyle & WS_CHILD))
1115 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1120 for ( ; pWnd; pWnd = pWnd->next)
1122 if (className && !(pWnd->dwStyle & WS_CHILD))
1124 if (!(pClass = CLASS_FindClassByAtom( className, GetExePtr(pWnd->hInstance))))
1125 continue; /* Skip this window */
1128 if (pClass && (pWnd->class != pClass))
1129 continue; /* Not the right class */
1131 /* Now check the title */
1133 if (!title) return pWnd->hwndSelf;
1134 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1141 /***********************************************************************
1142 * FindWindow16 (USER.50)
1144 HWND16 WINAPI FindWindow16( SEGPTR className, LPCSTR title )
1146 return FindWindowEx16( 0, 0, className, title );
1150 /***********************************************************************
1151 * FindWindowEx16 (USER.427)
1153 HWND16 WINAPI FindWindowEx16( HWND16 parent, HWND16 child,
1154 SEGPTR className, LPCSTR title )
1158 TRACE(win, "%04x %04x '%s' '%s'\n", parent,
1159 child, HIWORD(className)?(char *)PTR_SEG_TO_LIN(className):"",
1160 title ? title : "");
1164 /* If the atom doesn't exist, then no class */
1165 /* with this name exists either. */
1166 if (!(atom = GlobalFindAtom16( className ))) return 0;
1168 return WIN_FindWindow( parent, child, atom, title );
1172 /***********************************************************************
1173 * FindWindow32A (USER32.198)
1175 HWND32 WINAPI FindWindow32A( LPCSTR className, LPCSTR title )
1177 HWND32 ret = FindWindowEx32A( 0, 0, className, title );
1178 if (!ret) SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1183 /***********************************************************************
1184 * FindWindowEx32A (USER32.199)
1186 HWND32 WINAPI FindWindowEx32A( HWND32 parent, HWND32 child,
1187 LPCSTR className, LPCSTR title )
1193 /* If the atom doesn't exist, then no class */
1194 /* with this name exists either. */
1195 if (!(atom = GlobalFindAtom32A( className )))
1197 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1201 return WIN_FindWindow( parent, child, atom, title );
1205 /***********************************************************************
1206 * FindWindowEx32W (USER32.200)
1208 HWND32 WINAPI FindWindowEx32W( HWND32 parent, HWND32 child,
1209 LPCWSTR className, LPCWSTR title )
1217 /* If the atom doesn't exist, then no class */
1218 /* with this name exists either. */
1219 if (!(atom = GlobalFindAtom32W( className )))
1221 SetLastError (ERROR_CANNOT_FIND_WND_CLASS);
1225 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1226 hwnd = WIN_FindWindow( parent, child, atom, buffer );
1227 HeapFree( GetProcessHeap(), 0, buffer );
1232 /***********************************************************************
1233 * FindWindow32W (USER32.201)
1235 HWND32 WINAPI FindWindow32W( LPCWSTR className, LPCWSTR title )
1237 return FindWindowEx32W( 0, 0, className, title );
1241 /**********************************************************************
1244 WND *WIN_GetDesktop(void)
1250 /**********************************************************************
1251 * GetDesktopWindow16 (USER.286)
1253 HWND16 WINAPI GetDesktopWindow16(void)
1255 return (HWND16)pWndDesktop->hwndSelf;
1259 /**********************************************************************
1260 * GetDesktopWindow32 (USER32.232)
1262 HWND32 WINAPI GetDesktopWindow32(void)
1264 return pWndDesktop->hwndSelf;
1268 /**********************************************************************
1269 * GetDesktopHwnd (USER.278)
1271 * Exactly the same thing as GetDesktopWindow(), but not documented.
1272 * Don't ask me why...
1274 HWND16 WINAPI GetDesktopHwnd(void)
1276 return (HWND16)pWndDesktop->hwndSelf;
1280 /*******************************************************************
1281 * EnableWindow16 (USER.34)
1283 BOOL16 WINAPI EnableWindow16( HWND16 hwnd, BOOL16 enable )
1285 return EnableWindow32( hwnd, enable );
1289 /*******************************************************************
1290 * EnableWindow32 (USER32.172)
1292 BOOL32 WINAPI EnableWindow32( HWND32 hwnd, BOOL32 enable )
1296 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1297 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1300 wndPtr->dwStyle &= ~WS_DISABLED;
1301 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1304 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1306 /* Disable window */
1307 wndPtr->dwStyle |= WS_DISABLED;
1308 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1309 SetFocus32( 0 ); /* A disabled window can't have the focus */
1310 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1311 ReleaseCapture(); /* A disabled window can't capture the mouse */
1312 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1315 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1319 /***********************************************************************
1320 * IsWindowEnabled16 (USER.35)
1322 BOOL16 WINAPI IsWindowEnabled16(HWND16 hWnd)
1324 return IsWindowEnabled32(hWnd);
1328 /***********************************************************************
1329 * IsWindowEnabled32 (USER32.349)
1331 BOOL32 WINAPI IsWindowEnabled32(HWND32 hWnd)
1335 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1336 return !(wndPtr->dwStyle & WS_DISABLED);
1340 /***********************************************************************
1341 * IsWindowUnicode (USER32.350)
1343 BOOL32 WINAPI IsWindowUnicode( HWND32 hwnd )
1347 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1348 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1352 /**********************************************************************
1353 * GetWindowWord16 (USER.133)
1355 WORD WINAPI GetWindowWord16( HWND16 hwnd, INT16 offset )
1357 return GetWindowWord32( hwnd, offset );
1361 /**********************************************************************
1362 * GetWindowWord32 (USER32.314)
1364 WORD WINAPI GetWindowWord32( HWND32 hwnd, INT32 offset )
1366 WND * wndPtr = WIN_FindWndPtr( hwnd );
1367 if (!wndPtr) return 0;
1370 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1372 WARN( win, "Invalid offset %d\n", offset );
1375 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1380 if (HIWORD(wndPtr->wIDmenu))
1381 WARN( win,"GWW_ID: discards high bits of 0x%08x!\n",
1383 return (WORD)wndPtr->wIDmenu;
1384 case GWW_HWNDPARENT:
1385 return wndPtr->parent ?
1386 wndPtr->parent->hwndSelf : (
1388 wndPtr->owner->hwndSelf :
1391 if (HIWORD(wndPtr->hInstance))
1392 WARN(win,"GWW_HINSTANCE: discards high bits of 0x%08x!\n",
1394 return (WORD)wndPtr->hInstance;
1396 WARN( win, "Invalid offset %d\n", offset );
1402 /**********************************************************************
1403 * WIN_GetWindowInstance
1405 HINSTANCE32 WIN_GetWindowInstance( HWND32 hwnd )
1407 WND * wndPtr = WIN_FindWndPtr( hwnd );
1408 if (!wndPtr) return (HINSTANCE32)0;
1409 return wndPtr->hInstance;
1413 /**********************************************************************
1414 * SetWindowWord16 (USER.134)
1416 WORD WINAPI SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1418 return SetWindowWord32( hwnd, offset, newval );
1422 /**********************************************************************
1423 * SetWindowWord32 (USER32.524)
1425 WORD WINAPI SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1428 WND * wndPtr = WIN_FindWndPtr( hwnd );
1429 if (!wndPtr) return 0;
1432 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1434 WARN( win, "Invalid offset %d\n", offset );
1437 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1441 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1442 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1443 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1445 WARN( win, "Invalid offset %d\n", offset );
1454 /**********************************************************************
1457 * Helper function for GetWindowLong().
1459 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1462 WND * wndPtr = WIN_FindWndPtr( hwnd );
1463 if (!wndPtr) return 0;
1466 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1468 WARN( win, "Invalid offset %d\n", offset );
1471 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1472 /* Special case for dialog window procedure */
1473 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1474 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1479 case GWL_USERDATA: return wndPtr->userdata;
1480 case GWL_STYLE: return wndPtr->dwStyle;
1481 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1482 case GWL_ID: return (LONG)wndPtr->wIDmenu;
1483 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1485 case GWL_HWNDPARENT: return wndPtr->parent ?
1486 (HWND32)wndPtr->parent->hwndSelf : 0;
1487 case GWL_HINSTANCE: return wndPtr->hInstance;
1489 WARN( win, "Unknown offset %d\n", offset );
1495 /**********************************************************************
1498 * Helper function for SetWindowLong().
1500 * 0 is the failure code. However, in the case of failure SetLastError
1501 * must be set to distinguish between a 0 return value and a failure.
1503 * FIXME: The error values for SetLastError may not be right. Can
1504 * someone check with the real thing?
1506 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1507 WINDOWPROCTYPE type )
1510 WND * wndPtr = WIN_FindWndPtr( hwnd );
1513 TRACE(win,"%x=%p %x %lx %x\n",hwnd, wndPtr, offset, newval, type);
1517 /* Is this the right error? */
1518 SetLastError( ERROR_INVALID_WINDOW_HANDLE );
1524 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1526 WARN( win, "Invalid offset %d\n", offset );
1528 /* Is this the right error? */
1529 SetLastError( ERROR_OUTOFMEMORY );
1533 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1534 /* Special case for dialog window procedure */
1535 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1537 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1538 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1539 type, WIN_PROC_WINDOW );
1546 ptr = (DWORD*)&wndPtr->wIDmenu;
1549 return SetWindowWord32( hwnd, offset, newval );
1551 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1552 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1553 type, WIN_PROC_WINDOW );
1556 style.styleOld = wndPtr->dwStyle;
1557 newval &= ~(WS_VISIBLE | WS_CHILD); /* Some bits can't be changed this way */
1558 style.styleNew = newval | (style.styleOld & (WS_VISIBLE | WS_CHILD));
1560 if (wndPtr->flags & WIN_ISWIN32)
1561 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_STYLE,(LPARAM)&style);
1562 wndPtr->dwStyle = style.styleNew;
1563 if (wndPtr->flags & WIN_ISWIN32)
1564 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_STYLE,(LPARAM)&style);
1565 return style.styleOld;
1568 ptr = &wndPtr->userdata;
1571 style.styleOld = wndPtr->dwExStyle;
1572 style.styleNew = newval;
1573 if (wndPtr->flags & WIN_ISWIN32)
1574 SendMessage32A(hwnd,WM_STYLECHANGING,GWL_EXSTYLE,(LPARAM)&style);
1575 wndPtr->dwExStyle = newval;
1576 if (wndPtr->flags & WIN_ISWIN32)
1577 SendMessage32A(hwnd,WM_STYLECHANGED,GWL_EXSTYLE,(LPARAM)&style);
1578 return style.styleOld;
1581 WARN( win, "Invalid offset %d\n", offset );
1583 /* Don't think this is right error but it should do */
1584 SetLastError( ERROR_OUTOFMEMORY );
1594 /**********************************************************************
1595 * GetWindowLong16 (USER.135)
1597 LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset )
1599 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1603 /**********************************************************************
1604 * GetWindowLong32A (USER32.305)
1606 LONG WINAPI GetWindowLong32A( HWND32 hwnd, INT32 offset )
1608 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1612 /**********************************************************************
1613 * GetWindowLong32W (USER32.306)
1615 LONG WINAPI GetWindowLong32W( HWND32 hwnd, INT32 offset )
1617 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1621 /**********************************************************************
1622 * SetWindowLong16 (USER.136)
1624 LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1626 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1630 /**********************************************************************
1631 * SetWindowLong32A (USER32.517)
1633 LONG WINAPI SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1635 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1639 /**********************************************************************
1640 * SetWindowLong32W (USER32.518) Set window attribute
1642 * SetWindowLong() alters one of a window's attributes or sets a 32-bit (long)
1643 * value in a window's extra memory.
1645 * The _hwnd_ parameter specifies the window. is the handle to a
1646 * window that has extra memory. The _newval_ parameter contains the
1647 * new attribute or extra memory value. If positive, the _offset_
1648 * parameter is the byte-addressed location in the window's extra
1649 * memory to set. If negative, _offset_ specifies the window
1650 * attribute to set, and should be one of the following values:
1652 * GWL_EXSTYLE The window's extended window style
1654 * GWL_STYLE The window's window style.
1656 * GWL_WNDPROC Pointer to the window's window procedure.
1658 * GWL_HINSTANCE The window's pplication instance handle.
1660 * GWL_ID The window's identifier.
1662 * GWL_USERDATA The window's user-specified data.
1664 * If the window is a dialog box, the _offset_ parameter can be one of
1665 * the following values:
1667 * DWL_DLGPROC The address of the window's dialog box procedure.
1669 * DWL_MSGRESULT The return value of a message
1670 * that the dialog box procedure processed.
1672 * DWL_USER Application specific information.
1676 * If successful, returns the previous value located at _offset_. Otherwise,
1681 * Extra memory for a window class is specified by a nonzero cbWndExtra
1682 * parameter of the WNDCLASS structure passed to RegisterClass() at the
1683 * time of class creation.
1685 * Using GWL_WNDPROC to set a new window procedure effectively creates
1686 * a window subclass. Use CallWindowProc() in the new windows procedure
1687 * to pass messages to the superclass's window procedure.
1689 * The user data is reserved for use by the application which created
1692 * Do not use GWL_STYLE to change the window's WS_DISABLE style;
1693 * instead, call the EnableWindow() function to change the window's
1696 * Do not use GWL_HWNDPARENT to reset the window's parent, use
1697 * SetParent() instead.
1701 * GWL_STYLE does not dispatch WM_STYLE_... messages.
1708 LONG WINAPI SetWindowLong32W(
1709 HWND32 hwnd, /* window to alter */
1710 INT32 offset, /* offset, in bytes, of location to alter */
1711 LONG newval /* new value of location */
1713 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1717 /*******************************************************************
1718 * GetWindowText16 (USER.36)
1720 INT16 WINAPI GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1722 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1726 /*******************************************************************
1727 * GetWindowText32A (USER32.309)
1729 INT32 WINAPI GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1731 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1735 /*******************************************************************
1736 * InternalGetWindowText (USER32.326)
1738 INT32 WINAPI InternalGetWindowText(HWND32 hwnd,LPWSTR lpString,INT32 nMaxCount )
1740 FIXME(win,"(0x%08x,%p,0x%x),stub!\n",hwnd,lpString,nMaxCount);
1741 return GetWindowText32W(hwnd,lpString,nMaxCount);
1745 /*******************************************************************
1746 * GetWindowText32W (USER32.312)
1748 INT32 WINAPI GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1750 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1755 /*******************************************************************
1756 * SetWindowText16 (USER.37)
1758 void WINAPI SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1760 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1764 /*******************************************************************
1765 * SetWindowText32A (USER32.521)
1767 void WINAPI SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1769 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1773 /*******************************************************************
1774 * SetWindowText32W (USER32.523)
1776 void WINAPI SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1778 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1782 /*******************************************************************
1783 * GetWindowTextLength16 (USER.38)
1785 INT16 WINAPI GetWindowTextLength16( HWND16 hwnd )
1787 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1791 /*******************************************************************
1792 * GetWindowTextLength32A (USER32.310)
1794 INT32 WINAPI GetWindowTextLength32A( HWND32 hwnd )
1796 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1799 /*******************************************************************
1800 * GetWindowTextLength32W (USER32.311)
1802 INT32 WINAPI GetWindowTextLength32W( HWND32 hwnd )
1804 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1808 /*******************************************************************
1809 * IsWindow16 (USER.47)
1811 BOOL16 WINAPI IsWindow16( HWND16 hwnd )
1813 return IsWindow32( hwnd );
1816 void WINAPI WIN16_IsWindow16( CONTEXT *context )
1818 WORD *stack = PTR_SEG_OFF_TO_LIN(SS_reg(context), SP_reg(context));
1819 HWND16 hwnd = (HWND16)stack[2];
1821 AX_reg(context) = IsWindow32( hwnd );
1822 ES_reg(context) = USER_HeapSel;
1826 /*******************************************************************
1827 * IsWindow32 (USER32.348)
1829 BOOL32 WINAPI IsWindow32( HWND32 hwnd )
1831 WND * wndPtr = WIN_FindWndPtr( hwnd );
1832 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1836 /*****************************************************************
1837 * GetParent16 (USER.46)
1839 HWND16 WINAPI GetParent16( HWND16 hwnd )
1841 return (HWND16)GetParent32( hwnd );
1845 /*****************************************************************
1846 * GetParent32 (USER32.278)
1848 HWND32 WINAPI GetParent32( HWND32 hwnd )
1850 WND *wndPtr = WIN_FindWndPtr(hwnd);
1851 if ((!wndPtr) || (!(wndPtr->dwStyle & (WS_POPUP|WS_CHILD)))) return 0;
1852 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1853 return wndPtr ? wndPtr->hwndSelf : 0;
1856 /*****************************************************************
1859 * Get the top-level parent for a child window.
1861 WND* WIN_GetTopParentPtr( WND* pWnd )
1863 while( pWnd && (pWnd->dwStyle & WS_CHILD)) pWnd = pWnd->parent;
1867 /*****************************************************************
1870 * Get the top-level parent for a child window.
1872 HWND32 WIN_GetTopParent( HWND32 hwnd )
1874 WND *wndPtr = WIN_GetTopParentPtr ( WIN_FindWndPtr( hwnd ) );
1875 return wndPtr ? wndPtr->hwndSelf : 0;
1879 /*****************************************************************
1880 * SetParent16 (USER.233)
1882 HWND16 WINAPI SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1884 return SetParent32( hwndChild, hwndNewParent );
1888 /*****************************************************************
1889 * SetParent32 (USER32.495)
1891 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1893 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1894 WND *pWndNewParent =
1895 (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent ) : pWndDesktop;
1896 WND *pWndOldParent =
1897 (wndPtr)?(*wndPtr->pDriver->pSetParent)(wndPtr, pWndNewParent):NULL;
1899 return pWndOldParent?pWndOldParent->hwndSelf:0;
1902 /*******************************************************************
1903 * IsChild16 (USER.48)
1905 BOOL16 WINAPI IsChild16( HWND16 parent, HWND16 child )
1907 return IsChild32(parent,child);
1911 /*******************************************************************
1912 * IsChild32 (USER32.339)
1914 BOOL32 WINAPI IsChild32( HWND32 parent, HWND32 child )
1916 WND * wndPtr = WIN_FindWndPtr( child );
1917 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1919 wndPtr = wndPtr->parent;
1920 if (wndPtr->hwndSelf == parent) return TRUE;
1926 /***********************************************************************
1927 * IsWindowVisible16 (USER.49)
1929 BOOL16 WINAPI IsWindowVisible16( HWND16 hwnd )
1931 return IsWindowVisible32(hwnd);
1935 /***********************************************************************
1936 * IsWindowVisible32 (USER32.351)
1938 BOOL32 WINAPI IsWindowVisible32( HWND32 hwnd )
1940 WND *wndPtr = WIN_FindWndPtr( hwnd );
1941 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1943 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1944 wndPtr = wndPtr->parent;
1946 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1950 /***********************************************************************
1951 * WIN_IsWindowDrawable
1953 * hwnd is drawable when it is visible, all parents are not
1954 * minimized, and it is itself not minimized unless we are
1955 * trying to draw its default class icon.
1957 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
1959 if( (wnd->dwStyle & WS_MINIMIZE &&
1960 icon && wnd->class->hIcon) ||
1961 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
1962 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
1963 if( wnd->dwStyle & WS_MINIMIZE ||
1964 !(wnd->dwStyle & WS_VISIBLE) ) break;
1965 return (wnd == NULL);
1969 /*******************************************************************
1970 * GetTopWindow16 (USER.229)
1972 HWND16 WINAPI GetTopWindow16( HWND16 hwnd )
1974 return GetTopWindow32(hwnd);
1978 /*******************************************************************
1979 * GetTopWindow32 (USER.229)
1981 HWND32 WINAPI GetTopWindow32( HWND32 hwnd )
1983 WND * wndPtr = WIN_FindWndPtr( hwnd );
1984 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1989 /*******************************************************************
1990 * GetWindow16 (USER.262)
1992 HWND16 WINAPI GetWindow16( HWND16 hwnd, WORD rel )
1994 return GetWindow32( hwnd,rel );
1998 /*******************************************************************
1999 * GetWindow32 (USER32.302)
2001 HWND32 WINAPI GetWindow32( HWND32 hwnd, WORD rel )
2003 WND * wndPtr = WIN_FindWndPtr( hwnd );
2004 if (!wndPtr) return 0;
2008 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
2012 if (!wndPtr->parent) return 0; /* Desktop window */
2013 while (wndPtr->next) wndPtr = wndPtr->next;
2014 return wndPtr->hwndSelf;
2017 if (!wndPtr->next) return 0;
2018 return wndPtr->next->hwndSelf;
2021 if (!wndPtr->parent) return 0; /* Desktop window */
2022 wndPtr = wndPtr->parent->child; /* First sibling */
2023 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
2024 while (wndPtr->next)
2026 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
2027 wndPtr = wndPtr->next;
2032 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
2035 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
2041 /*******************************************************************
2042 * GetNextWindow16 (USER.230)
2044 HWND16 WINAPI GetNextWindow16( HWND16 hwnd, WORD flag )
2046 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
2047 return GetWindow16( hwnd, flag );
2050 /*******************************************************************
2051 * ShowOwnedPopups16 (USER.265)
2053 void WINAPI ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
2055 ShowOwnedPopups32( owner, fShow );
2059 /*******************************************************************
2060 * ShowOwnedPopups32 (USER32.531)
2062 BOOL32 WINAPI ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
2064 WND *pWnd = pWndDesktop->child;
2067 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
2068 (pWnd->dwStyle & WS_POPUP))
2069 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
2076 /*******************************************************************
2077 * GetLastActivePopup16 (USER.287)
2079 HWND16 WINAPI GetLastActivePopup16( HWND16 hwnd )
2081 return GetLastActivePopup32( hwnd );
2084 /*******************************************************************
2085 * GetLastActivePopup32 (USER32.256)
2087 HWND32 WINAPI GetLastActivePopup32( HWND32 hwnd )
2090 wndPtr = WIN_FindWndPtr(hwnd);
2091 if (wndPtr == NULL) return hwnd;
2092 return wndPtr->hwndLastActive;
2096 /*******************************************************************
2099 * Build an array of pointers to the children of a given window.
2100 * The array must be freed with HeapFree(SystemHeap). Return NULL
2101 * when no windows are found.
2103 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
2105 WND **list, **ppWnd;
2107 UINT32 count, skipOwned, skipHidden;
2110 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
2111 skipOwned = bwaFlags & BWA_SKIPOWNED;
2112 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
2113 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
2115 /* First count the windows */
2117 if (!wndPtr) wndPtr = pWndDesktop;
2118 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
2120 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2121 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
2126 /* Now build the list of all windows */
2128 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
2130 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
2132 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
2133 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2144 if( pTotal ) *pTotal = count;
2149 /*******************************************************************
2150 * EnumWindows16 (USER.54)
2152 BOOL16 WINAPI EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2154 WND **list, **ppWnd;
2156 /* We have to build a list of all windows first, to avoid */
2157 /* unpleasant side-effects, for instance if the callback */
2158 /* function changes the Z-order of the windows. */
2160 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2162 /* Now call the callback function for every window */
2164 for (ppWnd = list; *ppWnd; ppWnd++)
2166 /* Make sure that the window still exists */
2167 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2168 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2170 HeapFree( SystemHeap, 0, list );
2175 /*******************************************************************
2176 * EnumWindows32 (USER32.193)
2178 BOOL32 WINAPI EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2180 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2184 /**********************************************************************
2185 * EnumTaskWindows16 (USER.225)
2187 BOOL16 WINAPI EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
2190 WND **list, **ppWnd;
2192 /* This function is the same as EnumWindows(), */
2193 /* except for an added check on the window's task. */
2195 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2197 /* Now call the callback function for every window */
2199 for (ppWnd = list; *ppWnd; ppWnd++)
2201 /* Make sure that the window still exists */
2202 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2203 if (QUEUE_GetQueueTask((*ppWnd)->hmemTaskQ) != hTask) continue;
2204 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2206 HeapFree( SystemHeap, 0, list );
2211 /**********************************************************************
2212 * EnumThreadWindows (USER32.190)
2214 BOOL32 WINAPI EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2216 THDB *tdb = THREAD_ID_TO_THDB(id);
2218 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2222 /**********************************************************************
2223 * WIN_EnumChildWindows
2225 * Helper function for EnumChildWindows().
2227 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2233 for ( ; *ppWnd; ppWnd++)
2235 /* Make sure that the window still exists */
2236 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2237 /* Build children list first */
2238 childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL );
2239 ret = func( (*ppWnd)->hwndSelf, lParam );
2242 if (ret) ret = WIN_EnumChildWindows( childList, func, lParam );
2243 HeapFree( SystemHeap, 0, childList );
2245 if (!ret) return FALSE;
2251 /**********************************************************************
2252 * EnumChildWindows16 (USER.55)
2254 BOOL16 WINAPI EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
2257 WND **list, *pParent;
2259 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2260 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2261 WIN_EnumChildWindows( list, func, lParam );
2262 HeapFree( SystemHeap, 0, list );
2267 /**********************************************************************
2268 * EnumChildWindows32 (USER32.178)
2270 BOOL32 WINAPI EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
2273 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2278 /*******************************************************************
2279 * AnyPopup16 (USER.52)
2281 BOOL16 WINAPI AnyPopup16(void)
2283 return AnyPopup32();
2287 /*******************************************************************
2288 * AnyPopup32 (USER32.4)
2290 BOOL32 WINAPI AnyPopup32(void)
2293 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2294 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2299 /*******************************************************************
2300 * FlashWindow16 (USER.105)
2302 BOOL16 WINAPI FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2304 return FlashWindow32( hWnd, bInvert );
2308 /*******************************************************************
2309 * FlashWindow32 (USER32.202)
2311 BOOL32 WINAPI FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2313 WND *wndPtr = WIN_FindWndPtr(hWnd);
2315 TRACE(win,"%04x\n", hWnd);
2317 if (!wndPtr) return FALSE;
2319 if (wndPtr->dwStyle & WS_MINIMIZE)
2321 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2323 HDC32 hDC = GetDC32(hWnd);
2325 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2326 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2328 ReleaseDC32( hWnd, hDC );
2329 wndPtr->flags |= WIN_NCACTIVATED;
2333 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2334 RDW_UPDATENOW | RDW_FRAME, 0 );
2335 wndPtr->flags &= ~WIN_NCACTIVATED;
2342 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2343 else wparam = (hWnd == GetActiveWindow32());
2345 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2351 /*******************************************************************
2352 * SetSysModalWindow16 (USER.188)
2354 HWND16 WINAPI SetSysModalWindow16( HWND16 hWnd )
2356 HWND32 hWndOldModal = hwndSysModal;
2357 hwndSysModal = hWnd;
2358 FIXME(win, "EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2359 return hWndOldModal;
2363 /*******************************************************************
2364 * GetSysModalWindow16 (USER.52)
2366 HWND16 WINAPI GetSysModalWindow16(void)
2368 return hwndSysModal;
2372 /*******************************************************************
2373 * GetWindowContextHelpId (USER32.303)
2375 DWORD WINAPI GetWindowContextHelpId( HWND32 hwnd )
2377 WND *wnd = WIN_FindWndPtr( hwnd );
2379 return wnd->helpContext;
2383 /*******************************************************************
2384 * SetWindowContextHelpId (USER32.515)
2386 BOOL32 WINAPI SetWindowContextHelpId( HWND32 hwnd, DWORD id )
2388 WND *wnd = WIN_FindWndPtr( hwnd );
2389 if (!wnd) return FALSE;
2390 wnd->helpContext = id;
2395 /*******************************************************************
2398 * recursively find a child that contains spDragInfo->pt point
2399 * and send WM_QUERYDROPOBJECT
2401 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2403 BOOL16 wParam,bResult = 0;
2405 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2406 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2409 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2411 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2413 GetWindowRect32(hQueryWnd,&tempRect);
2415 if( !PtInRect32(&tempRect,pt) ||
2416 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2419 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2421 tempRect = ptrQueryWnd->rectClient;
2422 if(ptrQueryWnd->dwStyle & WS_CHILD)
2423 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2424 (LPPOINT32)&tempRect, 2 );
2426 if (PtInRect32( &tempRect, pt))
2430 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2431 if( ptrWnd->dwStyle & WS_VISIBLE )
2433 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2434 if (PtInRect32( &tempRect, pt )) break;
2439 TRACE(msg,"hwnd = %04x, %d %d - %d %d\n",
2440 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2441 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2442 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2443 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2446 if(bResult) return bResult;
2452 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2454 ptrDragInfo->hScope = hQueryWnd;
2456 bResult = ( bNoSend )
2457 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2458 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2459 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2461 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2467 /*******************************************************************
2468 * DragDetect (USER.465)
2470 BOOL16 WINAPI DragDetect16( HWND16 hWnd, POINT16 pt )
2473 CONV_POINT16TO32( &pt, &pt32 );
2474 return DragDetect32( hWnd, pt32 );
2477 /*******************************************************************
2478 * DragDetect32 (USER32.151)
2480 BOOL32 WINAPI DragDetect32( HWND32 hWnd, POINT32 pt )
2485 rect.left = pt.x - wDragWidth;
2486 rect.right = pt.x + wDragWidth;
2488 rect.top = pt.y - wDragHeight;
2489 rect.bottom = pt.y + wDragHeight;
2495 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2497 if( msg.message == WM_LBUTTONUP )
2502 if( msg.message == WM_MOUSEMOVE )
2504 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2516 /******************************************************************************
2517 * DragObject16 (USER.464)
2519 DWORD WINAPI DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2520 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2523 LPDRAGINFO lpDragInfo;
2525 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2526 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2527 WND *wndPtr = WIN_FindWndPtr(hWnd);
2528 HCURSOR16 hCurrentCursor = 0;
2529 HWND16 hCurrentWnd = 0;
2531 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2532 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2534 if( !lpDragInfo || !spDragInfo ) return 0L;
2536 hBummer = LoadCursor16(0, IDC_BUMMER16);
2538 if( !hBummer || !wndPtr )
2540 GlobalFree16(hDragInfo);
2546 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2548 GlobalFree16(hDragInfo);
2552 if( hDragCursor == hCursor ) hDragCursor = 0;
2553 else hCursor = hDragCursor;
2555 hOldCursor = SetCursor32(hDragCursor);
2558 lpDragInfo->hWnd = hWnd;
2559 lpDragInfo->hScope = 0;
2560 lpDragInfo->wFlags = wObj;
2561 lpDragInfo->hList = szList; /* near pointer! */
2562 lpDragInfo->hOfStruct = hOfStruct;
2566 ShowCursor32( TRUE );
2570 do{ WaitMessage(); }
2571 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2573 *(lpDragInfo+1) = *lpDragInfo;
2575 lpDragInfo->pt = msg.pt;
2577 /* update DRAGINFO struct */
2578 TRACE(msg,"lpDI->hScope = %04x\n",lpDragInfo->hScope);
2580 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2581 hCurrentCursor = hCursor;
2584 hCurrentCursor = hBummer;
2585 lpDragInfo->hScope = 0;
2587 if( hCurrentCursor )
2588 SetCursor32(hCurrentCursor);
2590 /* send WM_DRAGLOOP */
2591 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2592 (LPARAM) spDragInfo );
2593 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2594 if( hCurrentWnd != lpDragInfo->hScope )
2597 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2598 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2599 HIWORD(spDragInfo)) );
2600 hCurrentWnd = lpDragInfo->hScope;
2602 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2606 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2608 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2611 ShowCursor32( FALSE );
2615 SetCursor32( hOldCursor );
2616 if (hDragCursor) DestroyCursor32( hDragCursor );
2619 if( hCurrentCursor != hBummer )
2620 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2621 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2624 GlobalFree16(hDragInfo);
2626 return (DWORD)(msg.lParam);