2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
10 #include <X11/Xatom.h>
18 #include "sysmetrics.h"
19 #include "cursoricon.h"
24 #include "nonclient.h"
28 #include "shm_main_blk.h"
30 #include "clipboard.h"
34 /* #define DEBUG_WIN */
35 /* #define DEBUG_MENU */
39 static WND *pWndDesktop = NULL;
41 static HWND32 hwndSysModal = 0;
43 static WORD wDragWidth = 4;
44 static WORD wDragHeight= 3;
46 extern BOOL32 ICONTITLE_Init(void);
47 extern BOOL32 MENU_PatchResidentPopup( HQUEUE16, WND* );
48 extern HCURSOR16 CURSORICON_IconToCursor(HICON16, BOOL32);
49 extern HWND32 CARET_GetHwnd(void);
50 extern BOOL32 WINPOS_CreateInternalPosAtom(void);
51 extern void WINPOS_CheckInternalPos(HWND32);
52 extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
53 extern BOOL32 EVENT_CheckFocus(void);
55 /***********************************************************************
58 * Return a pointer to the WND structure corresponding to a HWND.
60 WND * WIN_FindWndPtr( HWND32 hwnd )
64 if (!hwnd || HIWORD(hwnd)) return NULL;
65 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
66 if (ptr->dwMagic != WND_MAGIC) return NULL;
67 if (ptr->hwndSelf != hwnd)
69 fprintf( stderr, "Can't happen: hwnd %04x self pointer is %04x\n",
70 hwnd, ptr->hwndSelf );
77 /***********************************************************************
80 * Dump the content of a window structure to stderr.
82 void WIN_DumpWindow( HWND32 hwnd )
88 if (!(ptr = WIN_FindWndPtr( hwnd )))
90 fprintf( stderr, "%04x is not a window handle\n", hwnd );
94 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
95 strcpy( className, "#NULL#" );
97 fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
99 "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
100 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%04x\n"
101 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
102 "client=%d,%d-%d,%d window=%d,%d-%d,%d"
103 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
104 ptr->next, ptr->child, ptr->parent, ptr->owner,
105 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
106 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
107 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
108 ptr->text ? ptr->text : "",
109 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
110 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
111 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu,
112 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
114 if (ptr->class->cbWndExtra)
116 fprintf( stderr, "extra bytes:" );
117 for (i = 0; i < ptr->class->cbWndExtra; i++)
118 fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
119 fprintf( stderr, "\n" );
121 fprintf( stderr, "\n" );
125 /***********************************************************************
128 * Walk the windows tree and print each window on stderr.
130 void WIN_WalkWindows( HWND32 hwnd, int indent )
135 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
138 fprintf( stderr, "*** Invalid window handle %04x\n", hwnd );
142 if (!indent) /* first time around */
143 fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
144 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
148 fprintf(stderr, "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
150 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
152 fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %08x\n",
153 (DWORD)ptr, ptr->hmemTaskQ, className,
154 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc );
156 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
162 /***********************************************************************
165 * Return the X window associated to a window.
167 Window WIN_GetXWindow( HWND32 hwnd )
169 WND *wndPtr = WIN_FindWndPtr( hwnd );
170 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
171 return wndPtr ? wndPtr->window : 0;
175 /***********************************************************************
178 * Remove a window from the siblings linked list.
180 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
182 WND *wndPtr, **ppWnd;
184 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
185 ppWnd = &wndPtr->parent->child;
186 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
187 *ppWnd = wndPtr->next;
192 /***********************************************************************
195 * Insert a window into the siblings linked list.
196 * The window is inserted after the specified window, which can also
197 * be specified as HWND_TOP or HWND_BOTTOM.
199 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
201 WND *wndPtr, **ppWnd;
203 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
205 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
207 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
208 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
209 while (*ppWnd) ppWnd = &(*ppWnd)->next;
211 else /* Normal case */
213 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
214 if (!afterPtr) return FALSE;
215 ppWnd = &afterPtr->next;
217 wndPtr->next = *ppWnd;
223 /***********************************************************************
224 * WIN_FindWinToRepaint
226 * Find a window that needs repaint.
228 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
231 WND *pWnd = pWndDesktop;
233 /* Note: the desktop window never gets WM_PAINT messages
234 * The real reason why is because Windows DesktopWndProc
235 * does ValidateRgn inside WM_ERASEBKGND handler.
238 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
240 for ( ; pWnd ; pWnd = pWnd->next )
242 if (!(pWnd->dwStyle & WS_VISIBLE) || (pWnd->flags & WIN_NO_REDRAW))
244 dprintf_win( stddeb, "FindWinToRepaint: skipping window %04x\n",
248 if ((pWnd->hmemTaskQ == hQueue) &&
249 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
252 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
258 hwndRet = pWnd->hwndSelf;
260 /* look among siblings if we got a transparent window */
261 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
262 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
266 if (pWnd) hwndRet = pWnd->hwndSelf;
267 dprintf_win(stddeb,"FindWinToRepaint: found %04x\n",hwndRet);
272 /***********************************************************************
273 * WIN_SendParentNotify
275 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
276 * the window has the WS_EX_NOPARENTNOTIFY style.
278 void WIN_SendParentNotify(HWND32 hwnd, WORD event, WORD idChild, LPARAM lValue)
280 LPPOINT16 lppt = (LPPOINT16)&lValue;
281 WND *wndPtr = WIN_FindWndPtr( hwnd );
282 BOOL32 bMouse = ((event <= WM_MOUSELAST) && (event >= WM_MOUSEFIRST));
284 /* if lValue contains cursor coordinates they have to be
285 * mapped to the client area of parent window */
287 if (bMouse) MapWindowPoints16( 0, hwnd, lppt, 1 );
291 if ((wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) ||
292 !(wndPtr->dwStyle & WS_CHILD)) break;
296 lppt->x += wndPtr->rectClient.left;
297 lppt->y += wndPtr->rectClient.top;
300 wndPtr = wndPtr->parent;
301 SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY,
302 MAKEWPARAM( event, idChild ), lValue );
307 /***********************************************************************
310 * Destroy storage associated to a window. "Internals" p.358
312 static WND* WIN_DestroyWindow( WND* wndPtr )
314 HWND32 hwnd = wndPtr->hwndSelf;
317 dprintf_win( stddeb, "WIN_DestroyWindow: %04x\n", wndPtr->hwndSelf );
321 DDE_DestroyWindow(wndPtr->hwndSelf);
322 #endif /* CONFIG_IPC */
324 /* free child windows */
326 while ((pWnd = wndPtr->child))
327 wndPtr->child = WIN_DestroyWindow( pWnd );
329 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
331 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
333 WINPOS_CheckInternalPos( hwnd );
334 if( hwnd == GetCapture32()) ReleaseCapture();
336 /* free resources associated with the window */
338 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
339 PROPERTY_RemoveWindowProps( wndPtr );
341 wndPtr->dwMagic = 0; /* Mark it as invalid */
342 wndPtr->hwndSelf = 0;
344 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
346 if (wndPtr->hrgnUpdate) DeleteObject32( wndPtr->hrgnUpdate );
347 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
350 /* toss stale messages from the queue */
352 if( wndPtr->hmemTaskQ )
355 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
357 while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
358 QUEUE_RemoveMsg(msgQ, pos);
359 wndPtr->hmemTaskQ = 0;
362 if (!(wndPtr->dwStyle & WS_CHILD))
363 if (wndPtr->wIDmenu) DestroyMenu32( (HMENU32)wndPtr->wIDmenu );
364 if (wndPtr->hSysMenu) DestroyMenu32( wndPtr->hSysMenu );
365 if (wndPtr->window) EVENT_DestroyWindow( wndPtr );
366 if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->dce );
368 WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW );
370 wndPtr->class->cWindows--;
371 wndPtr->class = NULL;
374 USER_HEAP_FREE( hwnd );
378 /***********************************************************************
379 * WIN_ResetQueueWindows
381 void WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew )
388 if (wnd->hmemTaskQ == hQueue)
389 if( hNew ) wnd->hmemTaskQ = hNew;
390 else DestroyWindow32( wnd->hwndSelf );
391 else WIN_ResetQueueWindows( wnd->child, hQueue, hNew );
396 /***********************************************************************
397 * WIN_CreateDesktopWindow
399 * Create the desktop window.
401 BOOL32 WIN_CreateDesktopWindow(void)
406 dprintf_win(stddeb,"Creating desktop window\n");
408 if (!ICONTITLE_Init() ||
409 !WINPOS_CreateInternalPosAtom() ||
410 !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
413 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
414 if (!hwndDesktop) return FALSE;
415 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
417 pWndDesktop->next = NULL;
418 pWndDesktop->child = NULL;
419 pWndDesktop->parent = NULL;
420 pWndDesktop->owner = NULL;
421 pWndDesktop->class = class;
422 pWndDesktop->dwMagic = WND_MAGIC;
423 pWndDesktop->hwndSelf = hwndDesktop;
424 pWndDesktop->hInstance = 0;
425 pWndDesktop->rectWindow.left = 0;
426 pWndDesktop->rectWindow.top = 0;
427 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
428 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
429 pWndDesktop->rectClient = pWndDesktop->rectWindow;
430 pWndDesktop->text = NULL;
431 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
432 pWndDesktop->hrgnUpdate = 0;
433 pWndDesktop->hwndLastActive = hwndDesktop;
434 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
436 pWndDesktop->dwExStyle = 0;
437 pWndDesktop->dce = NULL;
438 pWndDesktop->pVScroll = NULL;
439 pWndDesktop->pHScroll = NULL;
440 pWndDesktop->pProp = NULL;
441 pWndDesktop->wIDmenu = 0;
442 pWndDesktop->flags = 0;
443 pWndDesktop->window = rootWindow;
444 pWndDesktop->hSysMenu = 0;
445 pWndDesktop->userdata = 0;
447 pWndDesktop->winproc = (WNDPROC16)class->winproc;
449 EVENT_RegisterWindow( pWndDesktop );
450 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
451 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
456 /***********************************************************************
459 * Implementation of CreateWindowEx().
461 static HWND32 WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
462 BOOL32 win32, BOOL32 unicode )
466 HWND16 hwnd, hwndLinkAfter;
467 POINT32 maxSize, maxPos, minTrack, maxTrack;
468 LRESULT (*localSend32)(HWND32, UINT32, WPARAM32, LPARAM);
470 dprintf_win( stddeb, "CreateWindowEx: " );
471 if (HIWORD(cs->lpszName)) dprintf_win( stddeb, "'%s' ", cs->lpszName );
472 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszName) );
473 if (HIWORD(cs->lpszClass)) dprintf_win( stddeb, "'%s' ", cs->lpszClass );
474 else dprintf_win( stddeb, "#%04x ", LOWORD(cs->lpszClass) );
476 dprintf_win( stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %p\n",
477 cs->dwExStyle, cs->style, cs->x, cs->y, cs->cx, cs->cy,
478 cs->hwndParent, cs->hMenu, cs->hInstance, cs->lpCreateParams);
480 /* Find the parent window */
484 /* Make sure parent is valid */
485 if (!IsWindow32( cs->hwndParent ))
487 fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
491 else if (cs->style & WS_CHILD)
493 fprintf( stderr, "CreateWindowEx: no parent for child window\n" );
494 return 0; /* WS_CHILD needs a parent */
497 /* Find the window class */
499 if (!(classPtr = CLASS_FindClassByAtom( classAtom,
500 GetExePtr(cs->hInstance) )))
503 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
504 fprintf( stderr, "CreateWindowEx: bad class '%s'\n", buffer );
508 /* Fix the coordinates */
510 if (cs->x == CW_USEDEFAULT32) cs->x = cs->y = 0;
511 if (cs->cx == CW_USEDEFAULT32)
513 /* if (!(cs->style & (WS_CHILD | WS_POPUP))) cs->cx = cs->cy = 0;
521 /* Create the window structure */
523 if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra
524 - sizeof(wndPtr->wExtra) )))
526 dprintf_win( stddeb, "CreateWindowEx: out of memory\n" );
530 /* Fill the window structure */
532 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
534 wndPtr->child = NULL;
536 if (cs->style & WS_CHILD)
538 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
539 wndPtr->owner = NULL;
543 wndPtr->parent = pWndDesktop;
544 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
545 wndPtr->owner = NULL;
547 wndPtr->owner = WIN_FindWndPtr(WIN_GetTopParent(cs->hwndParent));
551 wndPtr->class = classPtr;
552 wndPtr->winproc = classPtr->winproc;
553 wndPtr->dwMagic = WND_MAGIC;
554 wndPtr->hwndSelf = hwnd;
555 wndPtr->hInstance = cs->hInstance;
557 wndPtr->hmemTaskQ = GetTaskQueue(0);
558 wndPtr->hrgnUpdate = 0;
559 wndPtr->hwndLastActive = hwnd;
560 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
561 wndPtr->dwExStyle = cs->dwExStyle;
563 wndPtr->flags = win32 ? WIN_ISWIN32 : 0;
564 wndPtr->pVScroll = NULL;
565 wndPtr->pHScroll = NULL;
566 wndPtr->pProp = NULL;
567 wndPtr->userdata = 0;
568 wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
569 ? MENU_GetSysMenu( hwnd, 0 ) : 0;
571 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
573 /* Call the WH_CBT hook */
575 hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
577 if (HOOK_IsHooked( WH_CBT ))
579 CBT_CREATEWND32A cbtc;
582 cbtc.hwndInsertAfter = hwndLinkAfter;
583 if ( HOOK_CallHooks32A(WH_CBT, HCBT_CREATEWND, hwnd, (LPARAM)&cbtc) )
585 dprintf_win(stddeb, "CreateWindowEx: CBT-hook returned 0\n");
586 USER_HEAP_FREE( hwnd );
591 /* Increment class window counter */
593 classPtr->cWindows++;
595 /* Correct the window style */
597 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
599 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
600 wndPtr->flags |= WIN_NEED_SIZE;
602 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
604 /* Get class or window DC if needed */
606 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
607 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
608 else wndPtr->dce = NULL;
610 /* Insert the window in the linked list */
612 WIN_LinkWindow( hwnd, hwndLinkAfter );
614 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
616 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
618 WINPOS_GetMinMaxInfo( wndPtr, &maxSize, &maxPos, &minTrack, &maxTrack);
619 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
620 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
621 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
622 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
624 if (cs->cx <= 0) cs->cx = 1;
625 if (cs->cy <= 0) cs->cy = 1;
627 wndPtr->rectWindow.left = cs->x;
628 wndPtr->rectWindow.top = cs->y;
629 wndPtr->rectWindow.right = cs->x + cs->cx;
630 wndPtr->rectWindow.bottom = cs->y + cs->cy;
631 wndPtr->rectClient = wndPtr->rectWindow;
633 /* Create the X window (only for top-level windows, and then only */
634 /* when there's no desktop window) */
636 if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
638 XSetWindowAttributes win_attr;
640 if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
641 (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
643 win_attr.event_mask = ExposureMask | KeyPressMask |
644 KeyReleaseMask | PointerMotionMask |
645 ButtonPressMask | ButtonReleaseMask |
646 FocusChangeMask | StructureNotifyMask;
647 win_attr.override_redirect = FALSE;
648 wndPtr->flags |= WIN_MANAGED;
652 win_attr.event_mask = ExposureMask | KeyPressMask |
653 KeyReleaseMask | PointerMotionMask |
654 ButtonPressMask | ButtonReleaseMask |
655 FocusChangeMask | StructureNotifyMask;
656 win_attr.override_redirect = TRUE;
658 win_attr.colormap = COLOR_GetColormap();
659 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
660 win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
661 win_attr.cursor = CURSORICON_XCursor;
662 wndPtr->window = XCreateWindow( display, rootWindow, cs->x, cs->y,
663 cs->cx, cs->cy, 0, CopyFromParent,
664 InputOutput, CopyFromParent,
665 CWEventMask | CWOverrideRedirect |
666 CWColormap | CWCursor | CWSaveUnder |
667 CWBackingStore, &win_attr );
669 if ((wndPtr->flags & WIN_MANAGED) &&
670 (cs->dwExStyle & WS_EX_DLGMODALFRAME))
672 XSizeHints* size_hints = XAllocSizeHints();
676 size_hints->min_width = size_hints->max_width = cs->cx;
677 size_hints->min_height = size_hints->max_height = cs->cy;
678 size_hints->flags = (PSize | PMinSize | PMaxSize);
679 XSetWMSizeHints( display, wndPtr->window, size_hints,
680 XA_WM_NORMAL_HINTS );
685 if (cs->hwndParent) /* Get window owner */
687 Window win = WIN_GetXWindow( cs->hwndParent );
688 if (win) XSetTransientForHint( display, wndPtr->window, win );
690 EVENT_RegisterWindow( wndPtr );
693 /* Set the window menu */
695 if ((cs->style & WS_CAPTION) && !(cs->style & WS_CHILD))
697 if (cs->hMenu) SetMenu32(hwnd, cs->hMenu);
700 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
701 if (classPtr->menuNameA)
702 cs->hMenu = HIWORD(classPtr->menuNameA) ?
703 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
704 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
706 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
707 if (menuName) cs->hMenu = LoadMenu16( cs->hInstance, menuName );
710 if (cs->hMenu) SetMenu32( hwnd, cs->hMenu );
712 else wndPtr->wIDmenu = (UINT32)cs->hMenu;
714 /* Send the WM_CREATE message
715 * Perhaps we shouldn't allow width/height changes as well.
716 * See p327 in "Internals".
719 maxPos.x = wndPtr->rectWindow.left; maxPos.y = wndPtr->rectWindow.top;
721 localSend32 = unicode ? SendMessage32W : SendMessage32A;
722 if( (*localSend32)( hwnd, WM_NCCREATE, 0, (LPARAM)cs) )
724 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
725 NULL, NULL, 0, &wndPtr->rectClient );
726 OffsetRect32(&wndPtr->rectWindow, maxPos.x - wndPtr->rectWindow.left,
727 maxPos.y - wndPtr->rectWindow.top);
728 if( ((*localSend32)( hwnd, WM_CREATE, 0, (LPARAM)cs )) != -1 )
730 /* Send the size messages */
732 if (!(wndPtr->flags & WIN_NEED_SIZE))
735 SendMessage32A( hwnd, WM_SIZE, SIZE_RESTORED,
736 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
737 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
738 SendMessage32A( hwnd, WM_MOVE, 0,
739 MAKELONG( wndPtr->rectClient.left,
740 wndPtr->rectClient.top ) );
743 WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LPARAM)hwnd );
744 if (!IsWindow32(hwnd)) return 0;
746 /* Show the window, maximizing or minimizing if needed */
748 if (wndPtr->dwStyle & WS_MINIMIZE)
751 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
752 WINPOS_MinMaximize( wndPtr, SW_MINIMIZE, &newPos );
753 SetWindowPos32( hwnd, 0, newPos.left, newPos.top, newPos.right, newPos.bottom,
754 SWP_FRAMECHANGED | ((GetActiveWindow32())? SWP_NOACTIVATE : 0));
756 else if (wndPtr->dwStyle & WS_MAXIMIZE)
759 wndPtr->dwStyle &= ~(WS_MAXIMIZE | WS_MINIMIZE);
760 WINPOS_MinMaximize( wndPtr, SW_MAXIMIZE, &newPos );
761 SetWindowPos32( hwnd, 0, newPos.left, newPos.top, newPos.right, newPos.bottom,
762 ((GetActiveWindow32())? SWP_NOACTIVATE : 0) | SWP_FRAMECHANGED );
765 if (cs->style & WS_VISIBLE) ShowWindow32( hwnd, SW_SHOW );
767 /* Call WH_SHELL hook */
769 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
770 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
772 dprintf_win(stddeb, "CreateWindowEx: created window %04x\n", hwnd);
777 /* Abort window creation */
779 dprintf_win(stddeb,"CreateWindowEx: aborted by WM_xxCREATE!\n");
780 WIN_UnlinkWindow( hwnd );
781 WIN_DestroyWindow( wndPtr );
786 /***********************************************************************
787 * CreateWindow16 (USER.41)
789 HWND16 CreateWindow16( LPCSTR className, LPCSTR windowName,
790 DWORD style, INT16 x, INT16 y, INT16 width,
791 INT16 height, HWND16 parent, HMENU16 menu,
792 HINSTANCE16 instance, LPVOID data )
794 return CreateWindowEx16( 0, className, windowName, style,
795 x, y, width, height, parent, menu, instance, data );
799 /***********************************************************************
800 * CreateWindowEx16 (USER.452)
802 HWND16 CreateWindowEx16( DWORD exStyle, LPCSTR className, LPCSTR windowName,
803 DWORD style, INT16 x, INT16 y, INT16 width,
804 INT16 height, HWND16 parent, HMENU16 menu,
805 HINSTANCE16 instance, LPVOID data )
810 /* Find the class atom */
812 if (!(classAtom = GlobalFindAtom32A( className )))
814 fprintf( stderr, "CreateWindowEx16: bad class name " );
815 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
816 else fprintf( stderr, "'%s'\n", className );
820 /* Fix the coordinates */
822 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
823 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
824 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
825 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
827 /* Create the window */
829 cs.lpCreateParams = data;
830 cs.hInstance = (HINSTANCE32)instance;
831 cs.hMenu = (HMENU32)menu;
832 cs.hwndParent = (HWND32)parent;
834 cs.lpszName = windowName;
835 cs.lpszClass = className;
836 cs.dwExStyle = exStyle;
837 return WIN_CreateWindowEx( &cs, classAtom, FALSE, FALSE );
841 /***********************************************************************
842 * CreateWindowEx32A (USER32.82)
844 HWND32 CreateWindowEx32A( DWORD exStyle, LPCSTR className, LPCSTR windowName,
845 DWORD style, INT32 x, INT32 y, INT32 width,
846 INT32 height, HWND32 parent, HMENU32 menu,
847 HINSTANCE32 instance, LPVOID data )
852 /* Find the class atom */
854 if (!(classAtom = GlobalFindAtom32A( className )))
856 fprintf( stderr, "CreateWindowEx32A: bad class name " );
857 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
858 else fprintf( stderr, "'%s'\n", className );
862 /* Create the window */
864 cs.lpCreateParams = data;
865 cs.hInstance = instance;
867 cs.hwndParent = parent;
873 cs.lpszName = windowName;
874 cs.lpszClass = className;
875 cs.dwExStyle = exStyle;
876 return WIN_CreateWindowEx( &cs, classAtom, TRUE, FALSE );
880 /***********************************************************************
881 * CreateWindowEx32W (USER32.83)
883 HWND32 CreateWindowEx32W( DWORD exStyle, LPCWSTR className, LPCWSTR windowName,
884 DWORD style, INT32 x, INT32 y, INT32 width,
885 INT32 height, HWND32 parent, HMENU32 menu,
886 HINSTANCE32 instance, LPVOID data )
891 /* Find the class atom */
893 if (!(classAtom = GlobalFindAtom32W( className )))
895 if (HIWORD(className))
897 LPSTR cn = HEAP_strdupWtoA( GetProcessHeap(), 0, className );
898 fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
899 HeapFree( GetProcessHeap(), 0, cn );
902 fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
906 /* Create the window */
908 cs.lpCreateParams = data;
909 cs.hInstance = instance;
911 cs.hwndParent = parent;
917 cs.lpszName = windowName;
918 cs.lpszClass = className;
919 cs.dwExStyle = exStyle;
920 /* Note: we rely on the fact that CREATESTRUCT32A and */
921 /* CREATESTRUCT32W have the same layout. */
922 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE, TRUE );
926 /***********************************************************************
929 static void WIN_CheckFocus( WND* pWnd )
931 if( GetFocus16() == pWnd->hwndSelf )
932 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
935 /***********************************************************************
938 static void WIN_SendDestroyMsg( WND* pWnd )
942 WIN_CheckFocus(pWnd);
944 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret32();
945 if( !pWnd->window ) CLIPBOARD_DisOwn( pWnd );
947 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
949 if( !IsWindow32(pWnd->hwndSelf) )
951 dprintf_win(stddeb,"\tdestroyed itself while in WM_DESTROY!\n");
955 pChild = pWnd->child;
958 WIN_SendDestroyMsg( pChild );
959 pChild = pChild->next;
961 WIN_CheckFocus(pWnd);
965 /***********************************************************************
966 * DestroyWindow (USER.53)
968 BOOL16 DestroyWindow16( HWND16 hwnd )
970 return DestroyWindow32(hwnd);
972 /***********************************************************************
973 * DestroyWindow (USER32.134)
975 BOOL32 DestroyWindow32( HWND32 hwnd )
979 dprintf_win(stddeb, "DestroyWindow(%04x)\n", hwnd);
983 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
984 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
988 if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
991 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
993 HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
994 /* FIXME: clean up palette - see "Internals" p.352 */
997 if( !QUEUE_IsExitingQueue(wndPtr->hmemTaskQ) )
998 WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
999 if (!IsWindow32(hwnd)) return TRUE;
1001 if( wndPtr->window ) CLIPBOARD_DisOwn( wndPtr ); /* before window is unmapped */
1003 /* Hide the window */
1005 if (wndPtr->dwStyle & WS_VISIBLE)
1007 SetWindowPos32( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
1008 SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|
1009 ((QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
1010 if (!IsWindow32(hwnd)) return TRUE;
1013 /* Recursively destroy owned windows */
1015 if( !(wndPtr->dwStyle & WS_CHILD) )
1017 /* make sure top menu popup doesn't get destroyed */
1018 MENU_PatchResidentPopup( TRUE, wndPtr );
1022 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1025 if (siblingPtr->owner == wndPtr)
1026 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1029 siblingPtr->owner = NULL;
1030 siblingPtr = siblingPtr->next;
1032 if (siblingPtr) DestroyWindow32( siblingPtr->hwndSelf );
1036 if( !Options.managed || EVENT_CheckFocus() )
1037 WINPOS_ActivateOtherWindow(wndPtr);
1039 if( wndPtr->owner &&
1040 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1041 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1044 /* Send destroy messages */
1046 WIN_SendDestroyMsg( wndPtr );
1047 if (!IsWindow32(hwnd)) return TRUE;
1049 /* Unlink now so we won't bother with the children later on */
1051 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1053 /* Destroy the window storage */
1055 WIN_DestroyWindow( wndPtr );
1060 /***********************************************************************
1061 * CloseWindow16 (USER.43)
1063 BOOL16 CloseWindow16( HWND16 hwnd )
1065 return CloseWindow32( hwnd );
1069 /***********************************************************************
1070 * CloseWindow32 (USER32.55)
1072 BOOL32 CloseWindow32( HWND32 hwnd )
1074 WND * wndPtr = WIN_FindWndPtr( hwnd );
1075 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return FALSE;
1076 ShowWindow32( hwnd, SW_MINIMIZE );
1081 /***********************************************************************
1082 * OpenIcon16 (USER.44)
1084 BOOL16 OpenIcon16( HWND16 hwnd )
1086 return OpenIcon32( hwnd );
1090 /***********************************************************************
1091 * OpenIcon32 (USER32.409)
1093 BOOL32 OpenIcon32( HWND32 hwnd )
1095 if (!IsIconic32( hwnd )) return FALSE;
1096 ShowWindow32( hwnd, SW_SHOWNORMAL );
1101 /***********************************************************************
1104 * Implementation of FindWindow() and FindWindowEx().
1106 static HWND32 WIN_FindWindow( HWND32 parent, HWND32 child, ATOM className,
1110 CLASS *pClass = NULL;
1114 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1117 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1119 else if (pWnd->parent != pWndDesktop) return 0;
1124 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1127 if (!pWnd) return 0;
1129 /* For a child window, all siblings will have the same hInstance, */
1130 /* so we can look for the class once and for all. */
1132 if (className && (pWnd->dwStyle & WS_CHILD))
1134 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1138 for ( ; pWnd; pWnd = pWnd->next)
1140 if (className && !(pWnd->dwStyle & WS_CHILD))
1142 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance)))
1143 continue; /* Skip this window */
1145 if (pClass && (pWnd->class != pClass))
1146 continue; /* Not the right class */
1148 /* Now check the title */
1150 if (!title) return pWnd->hwndSelf;
1151 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1158 /***********************************************************************
1159 * FindWindow16 (USER.50)
1161 HWND16 FindWindow16( SEGPTR className, LPCSTR title )
1163 return FindWindowEx16( 0, 0, className, title );
1167 /***********************************************************************
1168 * FindWindowEx16 (USER.427)
1170 HWND16 FindWindowEx16( HWND16 parent, HWND16 child,
1171 SEGPTR className, LPCSTR title )
1177 /* If the atom doesn't exist, then no class */
1178 /* with this name exists either. */
1179 if (!(atom = GlobalFindAtom16( className ))) return 0;
1181 return WIN_FindWindow( parent, child, atom, title );
1185 /***********************************************************************
1186 * FindWindow32A (USER32.197)
1188 HWND32 FindWindow32A( LPCSTR className, LPCSTR title )
1190 return FindWindowEx32A( 0, 0, className, title );
1194 /***********************************************************************
1195 * FindWindowEx32A (USER32.198)
1197 HWND32 FindWindowEx32A( HWND32 parent, HWND32 child,
1198 LPCSTR className, LPCSTR title )
1204 /* If the atom doesn't exist, then no class */
1205 /* with this name exists either. */
1206 if (!(atom = GlobalFindAtom32A( className ))) return 0;
1208 return WIN_FindWindow( 0, 0, atom, title );
1212 /***********************************************************************
1213 * FindWindowEx32W (USER32.199)
1215 HWND32 FindWindowEx32W( HWND32 parent, HWND32 child,
1216 LPCWSTR className, LPCWSTR title )
1224 /* If the atom doesn't exist, then no class */
1225 /* with this name exists either. */
1226 if (!(atom = GlobalFindAtom32W( className ))) return 0;
1228 buffer = HEAP_strdupWtoA( GetProcessHeap(), 0, title );
1229 hwnd = WIN_FindWindow( 0, 0, atom, buffer );
1230 HeapFree( GetProcessHeap(), 0, buffer );
1235 /***********************************************************************
1236 * FindWindow32W (USER32.200)
1238 HWND32 FindWindow32W( LPCWSTR className, LPCWSTR title )
1240 return FindWindowEx32W( 0, 0, className, title );
1244 /**********************************************************************
1247 WND *WIN_GetDesktop(void)
1253 /**********************************************************************
1254 * GetDesktopWindow16 (USER.286)
1256 HWND16 GetDesktopWindow16(void)
1258 return (HWND16)pWndDesktop->hwndSelf;
1262 /**********************************************************************
1263 * GetDesktopWindow32 (USER32.231)
1265 HWND32 GetDesktopWindow32(void)
1267 return pWndDesktop->hwndSelf;
1271 /**********************************************************************
1272 * GetDesktopHwnd (USER.278)
1274 * Exactly the same thing as GetDesktopWindow(), but not documented.
1275 * Don't ask me why...
1277 HWND16 GetDesktopHwnd(void)
1279 return (HWND16)pWndDesktop->hwndSelf;
1283 /*******************************************************************
1284 * EnableWindow16 (USER.34)
1286 BOOL16 EnableWindow16( HWND16 hwnd, BOOL16 enable )
1288 return EnableWindow32( hwnd, enable );
1292 /*******************************************************************
1293 * EnableWindow32 (USER32.171)
1295 BOOL32 EnableWindow32( HWND32 hwnd, BOOL32 enable )
1299 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1300 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1303 wndPtr->dwStyle &= ~WS_DISABLED;
1304 SendMessage32A( hwnd, WM_ENABLE, TRUE, 0 );
1307 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1309 /* Disable window */
1310 wndPtr->dwStyle |= WS_DISABLED;
1311 if ((hwnd == GetFocus32()) || IsChild32( hwnd, GetFocus32() ))
1312 SetFocus32( 0 ); /* A disabled window can't have the focus */
1313 if ((hwnd == GetCapture32()) || IsChild32( hwnd, GetCapture32() ))
1314 ReleaseCapture(); /* A disabled window can't capture the mouse */
1315 SendMessage32A( hwnd, WM_ENABLE, FALSE, 0 );
1318 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1322 /***********************************************************************
1323 * IsWindowEnabled16 (USER.35)
1325 BOOL16 IsWindowEnabled16(HWND16 hWnd)
1327 return IsWindowEnabled32(hWnd);
1331 /***********************************************************************
1332 * IsWindowEnabled32 (USER32.348)
1334 BOOL32 IsWindowEnabled32(HWND32 hWnd)
1338 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1339 return !(wndPtr->dwStyle & WS_DISABLED);
1343 /***********************************************************************
1344 * IsWindowUnicode (USER32.349)
1346 BOOL32 IsWindowUnicode( HWND32 hwnd )
1350 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1351 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1355 /**********************************************************************
1356 * GetWindowWord16 (USER.133)
1358 WORD GetWindowWord16( HWND16 hwnd, INT16 offset )
1360 return GetWindowWord32( hwnd, offset );
1364 /**********************************************************************
1365 * GetWindowWord32 (USER32.313)
1367 WORD GetWindowWord32( HWND32 hwnd, INT32 offset )
1369 WND * wndPtr = WIN_FindWndPtr( hwnd );
1370 if (!wndPtr) return 0;
1373 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1375 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1378 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1382 case GWW_ID: return wndPtr->wIDmenu;
1383 case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
1384 case GWW_HINSTANCE: return (WORD)wndPtr->hInstance;
1386 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1392 /**********************************************************************
1393 * WIN_GetWindowInstance
1395 HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd )
1397 WND * wndPtr = WIN_FindWndPtr( hwnd );
1398 if (!wndPtr) return (HINSTANCE16)0;
1399 return wndPtr->hInstance;
1403 /**********************************************************************
1404 * SetWindowWord16 (USER.134)
1406 WORD SetWindowWord16( HWND16 hwnd, INT16 offset, WORD newval )
1408 return SetWindowWord32( hwnd, offset, newval );
1412 /**********************************************************************
1413 * SetWindowWord32 (USER32.523)
1415 WORD SetWindowWord32( HWND32 hwnd, INT32 offset, WORD newval )
1418 WND * wndPtr = WIN_FindWndPtr( hwnd );
1419 if (!wndPtr) return 0;
1422 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1424 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1427 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1431 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1432 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1433 case GWW_HWNDPARENT: return SetParent32( hwnd, newval );
1435 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1444 /**********************************************************************
1447 * Helper function for GetWindowLong().
1449 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1452 WND * wndPtr = WIN_FindWndPtr( hwnd );
1453 if (!wndPtr) return 0;
1456 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1458 fprintf( stderr, "GetWindowLong: invalid offset %d\n", offset );
1461 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1462 /* Special case for dialog window procedure */
1463 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1464 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1469 case GWL_USERDATA: return wndPtr->userdata;
1470 case GWL_STYLE: return wndPtr->dwStyle;
1471 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1472 case GWL_ID: return wndPtr->wIDmenu;
1473 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1475 case GWL_HWNDPARENT: return wndPtr->parent ?
1476 (HWND32)wndPtr->parent->hwndSelf : 0;
1477 case GWL_HINSTANCE: return (HINSTANCE32)wndPtr->hInstance;
1479 fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
1485 /**********************************************************************
1488 * Helper function for SetWindowLong().
1490 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1491 WINDOWPROCTYPE type )
1494 WND * wndPtr = WIN_FindWndPtr( hwnd );
1495 if (!wndPtr) return 0;
1498 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1500 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1503 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1504 /* Special case for dialog window procedure */
1505 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1507 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1508 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval,
1509 type, WIN_PROC_WINDOW );
1517 return SetWindowWord32( hwnd, offset, (WORD)newval );
1519 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1520 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval,
1521 type, WIN_PROC_WINDOW );
1525 /* FIXME: WM_STYLE... messages for WIN_ISWIN32 windows */
1527 ptr = &wndPtr->dwStyle;
1528 /* Some bits can't be changed this way */
1529 newval &= ~(WS_VISIBLE | WS_CHILD);
1530 newval |= (*ptr & (WS_VISIBLE | WS_CHILD));
1532 case GWL_USERDATA: ptr = &wndPtr->userdata; break;
1533 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
1535 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1544 /**********************************************************************
1545 * GetWindowLong16 (USER.135)
1547 LONG GetWindowLong16( HWND16 hwnd, INT16 offset )
1549 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1553 /**********************************************************************
1554 * GetWindowLong32A (USER32.304)
1556 LONG GetWindowLong32A( HWND32 hwnd, INT32 offset )
1558 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1562 /**********************************************************************
1563 * GetWindowLong32W (USER32.305)
1565 LONG GetWindowLong32W( HWND32 hwnd, INT32 offset )
1567 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1571 /**********************************************************************
1572 * SetWindowLong16 (USER.136)
1574 LONG SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1576 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1580 /**********************************************************************
1581 * SetWindowLong32A (USER32.516)
1583 LONG SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1585 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1589 /**********************************************************************
1590 * SetWindowLong32W (USER32.517)
1592 LONG SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
1594 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1598 /*******************************************************************
1599 * GetWindowText16 (USER.36)
1601 INT16 GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1603 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1607 /*******************************************************************
1608 * GetWindowText32A (USER32.308)
1610 INT32 GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1612 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1617 /*******************************************************************
1618 * GetWindowText32W (USER32.311)
1620 INT32 GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1622 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1627 /*******************************************************************
1628 * SetWindowText16 (USER.37)
1630 void SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1632 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1636 /*******************************************************************
1637 * SetWindowText32A (USER32.)
1639 void SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1641 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1645 /*******************************************************************
1646 * SetWindowText32W (USER32.)
1648 void SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1650 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1654 /*******************************************************************
1655 * GetWindowTextLength16 (USER.38)
1657 INT16 GetWindowTextLength16( HWND16 hwnd )
1659 return (INT16)SendMessage16( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1663 /*******************************************************************
1664 * GetWindowTextLength32A (USER32.309)
1666 INT32 GetWindowTextLength32A( HWND32 hwnd )
1668 return SendMessage32A( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1671 /*******************************************************************
1672 * GetWindowTextLength32W (USER32.309)
1674 INT32 GetWindowTextLength32W( HWND32 hwnd )
1676 return SendMessage32W( hwnd, WM_GETTEXTLENGTH, 0, 0 );
1680 /*******************************************************************
1681 * IsWindow16 (USER.47)
1683 BOOL16 IsWindow16( HWND16 hwnd )
1685 return IsWindow32( hwnd );
1689 /*******************************************************************
1690 * IsWindow32 (USER32.347)
1692 BOOL32 IsWindow32( HWND32 hwnd )
1694 WND * wndPtr = WIN_FindWndPtr( hwnd );
1695 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1699 /*****************************************************************
1700 * GetParent16 (USER.46)
1702 HWND16 GetParent16( HWND16 hwnd )
1704 return (HWND16)GetParent32( hwnd );
1708 /*****************************************************************
1709 * GetParent32 (USER32.277)
1711 HWND32 GetParent32( HWND32 hwnd )
1713 WND *wndPtr = WIN_FindWndPtr(hwnd);
1714 if (!wndPtr) return 0;
1715 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1716 return wndPtr ? wndPtr->hwndSelf : 0;
1720 /*****************************************************************
1723 * Get the top-level parent for a child window.
1725 HWND32 WIN_GetTopParent( HWND32 hwnd )
1727 WND *wndPtr = WIN_FindWndPtr( hwnd );
1728 while (wndPtr && (wndPtr->dwStyle & WS_CHILD)) wndPtr = wndPtr->parent;
1729 return wndPtr ? wndPtr->hwndSelf : 0;
1733 /*****************************************************************
1734 * SetParent16 (USER.233)
1736 HWND16 SetParent16( HWND16 hwndChild, HWND16 hwndNewParent )
1738 return SetParent32( hwndChild, hwndNewParent );
1742 /*****************************************************************
1743 * SetParent32 (USER32.494)
1745 HWND32 SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
1749 WND *wndPtr = WIN_FindWndPtr( hwndChild );
1750 WND *pWndParent = WIN_FindWndPtr( hwndNewParent );
1751 if (!wndPtr || !pWndParent || !(wndPtr->dwStyle & WS_CHILD)) return 0;
1753 oldParent = wndPtr->parent->hwndSelf;
1755 WIN_UnlinkWindow(hwndChild);
1756 if (hwndNewParent) wndPtr->parent = pWndParent;
1757 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
1759 if (IsWindowVisible32(hwndChild)) UpdateWindow32(hwndChild);
1765 /*******************************************************************
1766 * IsChild16 (USER.48)
1768 BOOL16 IsChild16( HWND16 parent, HWND16 child )
1770 return IsChild32(parent,child);
1774 /*******************************************************************
1775 * IsChild32 (USER32.338)
1777 BOOL32 IsChild32( HWND32 parent, HWND32 child )
1779 WND * wndPtr = WIN_FindWndPtr( child );
1780 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1782 wndPtr = wndPtr->parent;
1783 if (wndPtr->hwndSelf == parent) return TRUE;
1789 /***********************************************************************
1790 * IsWindowVisible16 (USER.49)
1792 BOOL16 IsWindowVisible16( HWND16 hwnd )
1794 return IsWindowVisible32(hwnd);
1798 /***********************************************************************
1799 * IsWindowVisible32 (USER32.350)
1801 BOOL32 IsWindowVisible32( HWND32 hwnd )
1803 WND *wndPtr = WIN_FindWndPtr( hwnd );
1804 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1806 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1807 wndPtr = wndPtr->parent;
1809 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1813 /***********************************************************************
1814 * WIN_IsWindowDrawable
1816 * hwnd is drawable when it is visible, all parents are not
1817 * minimized, and it is itself not minimized unless we are
1818 * trying to draw its default class icon.
1820 BOOL32 WIN_IsWindowDrawable( WND* wnd, BOOL32 icon )
1822 if( (wnd->dwStyle & WS_MINIMIZE &&
1823 icon && wnd->class->hIcon) ||
1824 !(wnd->dwStyle & WS_VISIBLE) ) return FALSE;
1825 for(wnd = wnd->parent; wnd; wnd = wnd->parent)
1826 if( wnd->dwStyle & WS_MINIMIZE ||
1827 !(wnd->dwStyle & WS_VISIBLE) ) break;
1828 return (wnd == NULL);
1832 /*******************************************************************
1833 * GetTopWindow16 (USER.229)
1835 HWND16 GetTopWindow16( HWND16 hwnd )
1837 return GetTopWindow32(hwnd);
1841 /*******************************************************************
1842 * GetTopWindow32 (USER.229)
1844 HWND32 GetTopWindow32( HWND32 hwnd )
1846 WND * wndPtr = WIN_FindWndPtr( hwnd );
1847 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1852 /*******************************************************************
1853 * GetWindow16 (USER.262)
1855 HWND16 GetWindow16( HWND16 hwnd, WORD rel )
1857 return GetWindow32( hwnd,rel );
1861 /*******************************************************************
1862 * GetWindow32 (USER32.301)
1864 HWND32 GetWindow32( HWND32 hwnd, WORD rel )
1866 WND * wndPtr = WIN_FindWndPtr( hwnd );
1867 if (!wndPtr) return 0;
1871 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
1875 if (!wndPtr->parent) return 0; /* Desktop window */
1876 while (wndPtr->next) wndPtr = wndPtr->next;
1877 return wndPtr->hwndSelf;
1880 if (!wndPtr->next) return 0;
1881 return wndPtr->next->hwndSelf;
1884 if (!wndPtr->parent) return 0; /* Desktop window */
1885 wndPtr = wndPtr->parent->child; /* First sibling */
1886 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
1887 while (wndPtr->next)
1889 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
1890 wndPtr = wndPtr->next;
1895 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
1898 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
1904 /*******************************************************************
1905 * GetNextWindow16 (USER.230)
1907 HWND16 GetNextWindow16( HWND16 hwnd, WORD flag )
1909 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1910 return GetWindow16( hwnd, flag );
1913 /*******************************************************************
1914 * ShowOwnedPopups16 (USER.265)
1916 void ShowOwnedPopups16( HWND16 owner, BOOL16 fShow )
1918 ShowOwnedPopups32( owner, fShow );
1922 /*******************************************************************
1923 * ShowOwnedPopups32 (USER32.530)
1925 BOOL32 ShowOwnedPopups32( HWND32 owner, BOOL32 fShow )
1927 WND *pWnd = pWndDesktop->child;
1930 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
1931 (pWnd->dwStyle & WS_POPUP))
1932 ShowWindow32( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
1939 /*******************************************************************
1940 * GetLastActivePopup16 (USER.287)
1942 HWND16 GetLastActivePopup16( HWND16 hwnd )
1944 return GetLastActivePopup32( hwnd );
1947 /*******************************************************************
1948 * GetLastActivePopup32 (USER32.255)
1950 HWND32 GetLastActivePopup32( HWND32 hwnd )
1953 wndPtr = WIN_FindWndPtr(hwnd);
1954 if (wndPtr == NULL) return hwnd;
1955 return wndPtr->hwndLastActive;
1959 /*******************************************************************
1962 * Build an array of pointers to the children of a given window.
1963 * The array must be freed with HeapFree(SystemHeap). Return NULL
1964 * when no windows are found.
1966 WND **WIN_BuildWinArray( WND *wndPtr, UINT32 bwaFlags, UINT32* pTotal )
1968 WND **list, **ppWnd;
1970 UINT32 count, skipOwned, skipHidden;
1973 skipHidden = bwaFlags & BWA_SKIPHIDDEN;
1974 skipOwned = bwaFlags & BWA_SKIPOWNED;
1975 skipFlags = (bwaFlags & BWA_SKIPDISABLED) ? WS_DISABLED : 0;
1976 if( bwaFlags & BWA_SKIPICONIC ) skipFlags |= WS_MINIMIZE;
1978 /* First count the windows */
1980 if (!wndPtr) wndPtr = pWndDesktop;
1981 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next)
1983 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
1984 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE ) count++;
1989 /* Now build the list of all windows */
1991 if ((list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * (count + 1))))
1993 for (pWnd = wndPtr->child, ppWnd = list, count = 0; pWnd; pWnd = pWnd->next)
1995 if( (pWnd->dwStyle & skipFlags) || (skipOwned && pWnd->owner) ) continue;
1996 if( !skipHidden || pWnd->dwStyle & WS_VISIBLE )
2007 if( pTotal ) *pTotal = count;
2012 /*******************************************************************
2013 * EnumWindows16 (USER.54)
2015 BOOL16 EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
2017 WND **list, **ppWnd;
2019 /* We have to build a list of all windows first, to avoid */
2020 /* unpleasant side-effects, for instance if the callback */
2021 /* function changes the Z-order of the windows. */
2023 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2025 /* Now call the callback function for every window */
2027 for (ppWnd = list; *ppWnd; ppWnd++)
2029 /* Make sure that the window still exists */
2030 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2031 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
2033 HeapFree( SystemHeap, 0, list );
2038 /*******************************************************************
2039 * EnumWindows32 (USER32.192)
2041 BOOL32 EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
2043 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
2047 /**********************************************************************
2048 * EnumTaskWindows16 (USER.225)
2050 BOOL16 EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func, LPARAM lParam )
2052 WND **list, **ppWnd;
2053 HQUEUE16 hQueue = GetTaskQueue( hTask );
2055 /* This function is the same as EnumWindows(), */
2056 /* except for an added check on the window queue. */
2058 if (!(list = WIN_BuildWinArray( pWndDesktop, 0, NULL ))) return FALSE;
2060 /* Now call the callback function for every window */
2062 for (ppWnd = list; *ppWnd; ppWnd++)
2064 /* Make sure that the window still exists */
2065 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2066 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
2067 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
2069 HeapFree( SystemHeap, 0, list );
2074 /**********************************************************************
2075 * EnumThreadWindows (USER32.189)
2077 BOOL32 EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
2079 THDB *tdb = (THDB*)id;
2081 return (BOOL16)EnumTaskWindows16(tdb->teb.htask16, (WNDENUMPROC16)func, lParam);
2085 /**********************************************************************
2086 * WIN_EnumChildWindows
2088 * Helper function for EnumChildWindows().
2090 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
2096 for ( ; *ppWnd; ppWnd++)
2098 /* Make sure that the window still exists */
2099 if (!IsWindow32((*ppWnd)->hwndSelf)) continue;
2100 /* Build children list first */
2101 if (!(childList = WIN_BuildWinArray( *ppWnd, BWA_SKIPOWNED, NULL )))
2103 if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
2104 ret = WIN_EnumChildWindows( childList, func, lParam );
2105 HeapFree( SystemHeap, 0, childList );
2106 if (!ret) return FALSE;
2112 /**********************************************************************
2113 * EnumChildWindows16 (USER.55)
2115 BOOL16 EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func, LPARAM lParam )
2117 WND **list, *pParent;
2119 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
2120 if (!(list = WIN_BuildWinArray( pParent, BWA_SKIPOWNED, NULL ))) return FALSE;
2121 WIN_EnumChildWindows( list, func, lParam );
2122 HeapFree( SystemHeap, 0, list );
2127 /**********************************************************************
2128 * EnumChildWindows32 (USER32.177)
2130 BOOL32 EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func, LPARAM lParam )
2132 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
2137 /*******************************************************************
2138 * AnyPopup16 (USER.52)
2140 BOOL16 AnyPopup16(void)
2142 return AnyPopup32();
2146 /*******************************************************************
2147 * AnyPopup32 (USER32.3)
2149 BOOL32 AnyPopup32(void)
2152 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
2153 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
2158 /*******************************************************************
2159 * FlashWindow16 (USER.105)
2161 BOOL16 FlashWindow16( HWND16 hWnd, BOOL16 bInvert )
2163 return FlashWindow32( hWnd, bInvert );
2167 /*******************************************************************
2168 * FlashWindow32 (USER32.201)
2170 BOOL32 FlashWindow32( HWND32 hWnd, BOOL32 bInvert )
2172 WND *wndPtr = WIN_FindWndPtr(hWnd);
2174 dprintf_win(stddeb,"FlashWindow: %04x\n", hWnd);
2176 if (!wndPtr) return FALSE;
2178 if (wndPtr->dwStyle & WS_MINIMIZE)
2180 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2182 HDC32 hDC = GetDC32(hWnd);
2184 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM16)hDC, 0 ))
2185 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2187 ReleaseDC32( hWnd, hDC );
2188 wndPtr->flags |= WIN_NCACTIVATED;
2192 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2193 RDW_UPDATENOW | RDW_FRAME, 0 );
2194 wndPtr->flags &= ~WIN_NCACTIVATED;
2201 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2202 else wparam = (hWnd == GetActiveWindow32());
2204 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2210 /*******************************************************************
2211 * SetSysModalWindow16 (USER.188)
2213 HWND16 SetSysModalWindow16( HWND16 hWnd )
2215 HWND32 hWndOldModal = hwndSysModal;
2216 hwndSysModal = hWnd;
2217 dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2218 return hWndOldModal;
2222 /*******************************************************************
2223 * GetSysModalWindow16 (USER.52)
2225 HWND16 GetSysModalWindow16(void)
2227 return hwndSysModal;
2231 /*******************************************************************
2234 * recursively find a child that contains spDragInfo->pt point
2235 * and send WM_QUERYDROPOBJECT
2237 BOOL16 DRAG_QueryUpdate( HWND32 hQueryWnd, SEGPTR spDragInfo, BOOL32 bNoSend )
2239 BOOL16 wParam,bResult = 0;
2241 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2242 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2245 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2247 CONV_POINT16TO32( &ptrDragInfo->pt, &pt );
2249 GetWindowRect32(hQueryWnd,&tempRect);
2251 if( !PtInRect32(&tempRect,pt) ||
2252 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2255 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2257 tempRect = ptrQueryWnd->rectClient;
2258 if(ptrQueryWnd->dwStyle & WS_CHILD)
2259 MapWindowPoints32( ptrQueryWnd->parent->hwndSelf, 0,
2260 (LPPOINT32)&tempRect, 2 );
2262 if (PtInRect32( &tempRect, pt))
2266 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2267 if( ptrWnd->dwStyle & WS_VISIBLE )
2269 GetWindowRect32( ptrWnd->hwndSelf, &tempRect );
2270 if (PtInRect32( &tempRect, pt )) break;
2275 dprintf_msg(stddeb,"DragQueryUpdate: hwnd = %04x, %d %d - %d %d\n",
2276 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2277 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2278 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2279 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo, bNoSend);
2282 if(bResult) return bResult;
2288 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2290 ptrDragInfo->hScope = hQueryWnd;
2292 bResult = ( bNoSend )
2293 ? ptrQueryWnd->dwExStyle & WS_EX_ACCEPTFILES
2294 : SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2295 (WPARAM16)wParam ,(LPARAM) spDragInfo );
2297 CONV_POINT32TO16( &pt, &ptrDragInfo->pt );
2303 /*******************************************************************
2304 * DragDetect (USER.465)
2306 BOOL16 DragDetect16( HWND16 hWnd, POINT16 pt )
2309 CONV_POINT16TO32( &pt, &pt32 );
2310 return DragDetect32( hWnd, pt32 );
2313 /*******************************************************************
2314 * DragDetect32 (USER32.150)
2316 BOOL32 DragDetect32( HWND32 hWnd, POINT32 pt )
2321 rect.left = pt.x - wDragWidth;
2322 rect.right = pt.x + wDragWidth;
2324 rect.top = pt.y - wDragHeight;
2325 rect.bottom = pt.y + wDragHeight;
2331 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2333 if( msg.message == WM_LBUTTONUP )
2338 if( msg.message == WM_MOUSEMOVE )
2340 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2352 /******************************************************************************
2353 * DragObject16 (USER.464)
2355 DWORD DragObject16( HWND16 hwndScope, HWND16 hWnd, UINT16 wObj,
2356 HANDLE16 hOfStruct, WORD szList, HCURSOR16 hCursor )
2359 LPDRAGINFO lpDragInfo;
2361 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2362 HGLOBAL16 hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2363 WND *wndPtr = WIN_FindWndPtr(hWnd);
2364 HCURSOR16 hCurrentCursor = 0;
2365 HWND16 hCurrentWnd = 0;
2367 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2368 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2370 if( !lpDragInfo || !spDragInfo ) return 0L;
2372 hBummer = LoadCursor16(0, IDC_BUMMER);
2374 if( !hBummer || !wndPtr )
2376 GlobalFree16(hDragInfo);
2382 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor, FALSE)) )
2384 GlobalFree16(hDragInfo);
2388 if( hDragCursor == hCursor ) hDragCursor = 0;
2389 else hCursor = hDragCursor;
2391 hOldCursor = SetCursor32(hDragCursor);
2394 lpDragInfo->hWnd = hWnd;
2395 lpDragInfo->hScope = 0;
2396 lpDragInfo->wFlags = wObj;
2397 lpDragInfo->hList = szList; /* near pointer! */
2398 lpDragInfo->hOfStruct = hOfStruct;
2402 ShowCursor32( TRUE );
2406 do{ WaitMessage(); }
2407 while( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) );
2409 *(lpDragInfo+1) = *lpDragInfo;
2411 lpDragInfo->pt = msg.pt;
2413 /* update DRAGINFO struct */
2414 dprintf_msg(stddeb,"drag: lpDI->hScope = %04x\n",lpDragInfo->hScope);
2416 if( DRAG_QueryUpdate(hwndScope, spDragInfo, FALSE) > 0 )
2417 hCurrentCursor = hCursor;
2420 hCurrentCursor = hBummer;
2421 lpDragInfo->hScope = 0;
2423 if( hCurrentCursor )
2424 SetCursor32(hCurrentCursor);
2426 /* send WM_DRAGLOOP */
2427 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM16)(hCurrentCursor != hBummer),
2428 (LPARAM) spDragInfo );
2429 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2430 if( hCurrentWnd != lpDragInfo->hScope )
2433 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2434 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2435 HIWORD(spDragInfo)) );
2436 hCurrentWnd = lpDragInfo->hScope;
2438 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2442 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2444 } while( msg.message != WM_LBUTTONUP && msg.message != WM_NCLBUTTONUP );
2447 ShowCursor32( FALSE );
2451 SetCursor32( hOldCursor );
2452 if (hDragCursor) DestroyCursor32( hDragCursor );
2455 if( hCurrentCursor != hBummer )
2456 msg.lParam = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2457 (WPARAM16)hWnd, (LPARAM)spDragInfo );
2460 GlobalFree16(hDragInfo);
2462 return (DWORD)(msg.lParam);