Release 960928
[wine/multimedia.git] / windows / win.c
blob563c788b769bae6d18b4edf48e031f256eabf705
1 /*
2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <X11/Xatom.h>
12 #include "options.h"
13 #include "class.h"
14 #include "win.h"
15 #include "heap.h"
16 #include "user.h"
17 #include "dce.h"
18 #include "sysmetrics.h"
19 #include "cursoricon.h"
20 #include "heap.h"
21 #include "hook.h"
22 #include "menu.h"
23 #include "message.h"
24 #include "nonclient.h"
25 #include "string32.h"
26 #include "queue.h"
27 #include "winpos.h"
28 #include "color.h"
29 #include "shm_main_blk.h"
30 #include "dde_proc.h"
31 #include "clipboard.h"
32 #include "winproc.h"
33 #include "stddebug.h"
34 /* #define DEBUG_WIN */
35 /* #define DEBUG_MENU */
36 #include "debug.h"
38 /* Desktop window */
39 static WND *pWndDesktop = NULL;
41 static HWND hwndSysModal = 0;
43 static WORD wDragWidth = 4;
44 static WORD wDragHeight= 3;
46 extern HCURSOR16 CURSORICON_IconToCursor(HICON16);
47 extern HWND32 CARET_GetHwnd(void);
48 extern BOOL32 WINPOS_ActivateOtherWindow(WND* pWnd);
49 extern void WINPOS_CheckActive(HWND32);
51 /***********************************************************************
52 * WIN_FindWndPtr
54 * Return a pointer to the WND structure corresponding to a HWND.
56 WND * WIN_FindWndPtr( HWND32 hwnd )
58 WND * ptr;
60 if (!hwnd || HIWORD(hwnd)) return NULL;
61 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
62 if (ptr->dwMagic != WND_MAGIC) return NULL;
63 if (ptr->hwndSelf != hwnd)
65 fprintf( stderr, "Can't happen: hwnd %04x self pointer is %04x\n",
66 hwnd, ptr->hwndSelf );
67 return NULL;
69 return ptr;
73 /***********************************************************************
74 * WIN_DumpWindow
76 * Dump the content of a window structure to stderr.
78 void WIN_DumpWindow( HWND32 hwnd )
80 WND *ptr;
81 char className[80];
82 int i;
84 if (!(ptr = WIN_FindWndPtr( hwnd )))
86 fprintf( stderr, "%04x is not a window handle\n", hwnd );
87 return;
90 if (!GetClassName32A( hwnd, className, sizeof(className ) ))
91 strcpy( className, "#NULL#" );
93 fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
94 fprintf( stderr,
95 "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
96 "inst=%04x taskQ=%04x updRgn=%04x active=%04x dce=%p idmenu=%04x\n"
97 "style=%08lx exstyle=%08lx wndproc=%08x text='%s'\n"
98 "client=%d,%d-%d,%d window=%d,%d-%d,%d iconpos=%d,%d maxpos=%d,%d\n"
99 "sysmenu=%04x flags=%04x props=%p vscroll=%p hscroll=%p\n",
100 ptr->next, ptr->child, ptr->parent, ptr->owner,
101 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
102 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->dce, ptr->wIDmenu,
103 ptr->dwStyle, ptr->dwExStyle, (UINT32)ptr->winproc,
104 ptr->text ? ptr->text : "",
105 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
106 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
107 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x,
108 ptr->ptIconPos.y, ptr->ptMaxPos.x, ptr->ptMaxPos.y, ptr->hSysMenu,
109 ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
111 if (ptr->class->cbWndExtra)
113 fprintf( stderr, "extra bytes:" );
114 for (i = 0; i < ptr->class->cbWndExtra; i++)
115 fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
116 fprintf( stderr, "\n" );
118 fprintf( stderr, "\n" );
122 /***********************************************************************
123 * WIN_WalkWindows
125 * Walk the windows tree and print each window on stderr.
127 void WIN_WalkWindows( HWND32 hwnd, int indent )
129 WND *ptr;
130 char className[80];
132 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
133 if (!ptr)
135 fprintf( stderr, "*** Invalid window handle %04x\n", hwnd );
136 return;
139 if (!indent) /* first time around */
140 fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
141 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
143 while (ptr)
145 fprintf(stderr, "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
147 GlobalGetAtomName16(ptr->class->atomName,className,sizeof(className));
149 fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %08x\n",
150 (DWORD)ptr, ptr->hmemTaskQ, className,
151 (UINT32)ptr->dwStyle, (UINT32)ptr->winproc );
153 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
154 ptr = ptr->next;
159 /***********************************************************************
160 * WIN_GetXWindow
162 * Return the X window associated to a window.
164 Window WIN_GetXWindow( HWND32 hwnd )
166 WND *wndPtr = WIN_FindWndPtr( hwnd );
167 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
168 return wndPtr ? wndPtr->window : 0;
172 /***********************************************************************
173 * WIN_UnlinkWindow
175 * Remove a window from the siblings linked list.
177 BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
179 WND *wndPtr, **ppWnd;
181 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
182 ppWnd = &wndPtr->parent->child;
183 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
184 *ppWnd = wndPtr->next;
185 return TRUE;
189 /***********************************************************************
190 * WIN_LinkWindow
192 * Insert a window into the siblings linked list.
193 * The window is inserted after the specified window, which can also
194 * be specified as HWND_TOP or HWND_BOTTOM.
196 BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
198 WND *wndPtr, **ppWnd;
200 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
202 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
204 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
205 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
206 while (*ppWnd) ppWnd = &(*ppWnd)->next;
208 else /* Normal case */
210 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
211 if (!afterPtr) return FALSE;
212 ppWnd = &afterPtr->next;
214 wndPtr->next = *ppWnd;
215 *ppWnd = wndPtr;
216 return TRUE;
220 /***********************************************************************
221 * WIN_FindWinToRepaint
223 * Find a window that needs repaint.
225 HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
227 HWND hwndRet;
228 WND *pWnd = pWndDesktop;
230 /* Note: the desktop window never gets WM_PAINT messages
231 * The real reason why is because Windows DesktopWndProc
232 * does ValidateRgn inside WM_ERASEBKGND handler.
235 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
237 for ( ; pWnd ; pWnd = pWnd->next )
239 if (!(pWnd->dwStyle & WS_VISIBLE) || (pWnd->flags & WIN_NO_REDRAW))
241 dprintf_win( stddeb, "FindWinToRepaint: skipping window %04x\n",
242 pWnd->hwndSelf );
243 continue;
245 if ((pWnd->hmemTaskQ == hQueue) &&
246 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
248 if (pWnd->child )
249 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
250 return hwndRet;
253 if (!pWnd) return 0;
255 hwndRet = pWnd->hwndSelf;
257 /* look among siblings if we got a transparent window */
258 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
259 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
261 pWnd = pWnd->next;
263 if (pWnd) hwndRet = pWnd->hwndSelf;
264 dprintf_win(stddeb,"FindWinToRepaint: found %04x\n",hwndRet);
265 return hwndRet;
269 /***********************************************************************
270 * WIN_SendParentNotify
272 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
273 * the window has the WS_EX_NOPARENTNOTIFY style.
275 void WIN_SendParentNotify(HWND32 hwnd, WORD event, WORD idChild, LPARAM lValue)
277 LPPOINT16 lppt = (LPPOINT16)&lValue;
278 WND *wndPtr = WIN_FindWndPtr( hwnd );
279 BOOL bMouse = ((event <= WM_MOUSELAST) && (event >= WM_MOUSEFIRST));
281 /* if lValue contains cursor coordinates they have to be
282 * mapped to the client area of parent window */
284 if (bMouse) MapWindowPoints16( 0, hwnd, lppt, 1 );
286 while (wndPtr)
288 if ((wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) ||
289 !(wndPtr->dwStyle & WS_CHILD)) break;
291 if (bMouse)
293 lppt->x += wndPtr->rectClient.left;
294 lppt->y += wndPtr->rectClient.top;
297 wndPtr = wndPtr->parent;
298 SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY,
299 MAKEWPARAM( event, idChild ), lValue );
304 /***********************************************************************
305 * WIN_DestroyWindow
307 * Destroy storage associated to a window. "Internals" p.358
309 static void WIN_DestroyWindow( WND* wndPtr )
311 HWND hwnd = wndPtr->hwndSelf;
312 WND* pWnd,*pNext;
314 #ifdef CONFIG_IPC
315 if (main_block)
316 DDE_DestroyWindow(wndPtr->hwndSelf);
317 #endif /* CONFIG_IPC */
319 /* free child windows */
321 pNext = wndPtr->child;
322 while( (pWnd = pNext) )
324 pNext = pWnd->next;
325 WIN_DestroyWindow( pWnd );
328 SendMessage32A( wndPtr->hwndSelf, WM_NCDESTROY, 0, 0);
330 /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
332 WINPOS_CheckActive( hwnd );
333 if( hwnd == GetCapture32()) ReleaseCapture();
335 /* free resources associated with the window */
337 TIMER_RemoveWindowTimers( wndPtr->hwndSelf );
338 PROPERTY_RemoveWindowProps( wndPtr );
340 wndPtr->dwMagic = 0; /* Mark it as invalid */
341 wndPtr->hwndSelf = 0;
343 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
345 if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
346 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
349 /* toss stale messages from the queue */
351 if( wndPtr->hmemTaskQ )
353 int pos;
354 MESSAGEQUEUE* msgQ = (MESSAGEQUEUE*) GlobalLock16(wndPtr->hmemTaskQ);
356 while( (pos = QUEUE_FindMsg(msgQ, hwnd, 0, 0)) != -1 )
357 QUEUE_RemoveMsg(msgQ, pos);
358 wndPtr->hmemTaskQ = 0;
361 if (!(wndPtr->dwStyle & WS_CHILD))
362 if (wndPtr->wIDmenu) DestroyMenu( (HMENU)wndPtr->wIDmenu );
363 if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
364 if (wndPtr->window) XDestroyWindow( display, wndPtr->window );
365 if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->dce );
367 WINPROC_FreeProc( wndPtr->winproc );
369 wndPtr->class->cWindows--;
370 wndPtr->class = NULL;
372 USER_HEAP_FREE( hwnd );
376 /***********************************************************************
377 * WIN_DestroyQueueWindows
379 void WIN_DestroyQueueWindows( WND* wnd, HQUEUE16 hQueue )
381 WND* next;
383 while (wnd)
385 next = wnd->next;
386 if (wnd->hmemTaskQ == hQueue) DestroyWindow( wnd->hwndSelf );
387 else WIN_DestroyQueueWindows( wnd->child, hQueue );
388 wnd = next;
393 /***********************************************************************
394 * WIN_CreateDesktopWindow
396 * Create the desktop window.
398 BOOL32 WIN_CreateDesktopWindow(void)
400 CLASS *class;
401 HWND hwndDesktop;
403 dprintf_win(stddeb,"Creating desktop window\n");
405 if (!(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
406 return FALSE;
408 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra );
409 if (!hwndDesktop) return FALSE;
410 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
412 pWndDesktop->next = NULL;
413 pWndDesktop->child = NULL;
414 pWndDesktop->parent = NULL;
415 pWndDesktop->owner = NULL;
416 pWndDesktop->class = class;
417 pWndDesktop->winproc = NULL;
418 pWndDesktop->dwMagic = WND_MAGIC;
419 pWndDesktop->hwndSelf = hwndDesktop;
420 pWndDesktop->hInstance = 0;
421 pWndDesktop->rectWindow.left = 0;
422 pWndDesktop->rectWindow.top = 0;
423 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
424 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
425 pWndDesktop->rectClient = pWndDesktop->rectWindow;
426 pWndDesktop->rectNormal = pWndDesktop->rectWindow;
427 pWndDesktop->ptIconPos.x = -1;
428 pWndDesktop->ptIconPos.y = -1;
429 pWndDesktop->ptMaxPos.x = -1;
430 pWndDesktop->ptMaxPos.y = -1;
431 pWndDesktop->text = NULL;
432 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
433 pWndDesktop->hrgnUpdate = 0;
434 pWndDesktop->hwndLastActive = hwndDesktop;
435 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
436 WS_CLIPSIBLINGS;
437 pWndDesktop->dwExStyle = 0;
438 pWndDesktop->dce = NULL;
439 pWndDesktop->pVScroll = NULL;
440 pWndDesktop->pHScroll = NULL;
441 pWndDesktop->pProp = NULL;
442 pWndDesktop->wIDmenu = 0;
443 pWndDesktop->flags = 0;
444 pWndDesktop->window = rootWindow;
445 pWndDesktop->hSysMenu = 0;
446 pWndDesktop->userdata = 0;
448 WINPROC_SetProc( &pWndDesktop->winproc, (WNDPROC16)class->winproc, 0 );
449 EVENT_RegisterWindow( pWndDesktop );
450 SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
451 pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
452 return TRUE;
456 /***********************************************************************
457 * WIN_CreateWindowEx
459 * Implementation of CreateWindowEx().
461 static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
462 BOOL unicode )
464 CLASS *classPtr;
465 WND *wndPtr;
466 HWND16 hwnd, hwndLinkAfter;
467 POINT16 maxSize, maxPos, minTrack, maxTrack;
468 LRESULT wmcreate;
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 */
482 if (cs->hwndParent)
484 /* Make sure parent is valid */
485 if (!IsWindow( cs->hwndParent ))
487 fprintf( stderr, "CreateWindowEx: bad parent %04x\n", cs->hwndParent );
488 return 0;
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) )))
502 char buffer[256];
503 GlobalGetAtomName32A( classAtom, buffer, sizeof(buffer) );
504 fprintf( stderr, "CreateWindowEx: bad class '%s'\n", buffer );
505 return 0;
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;
514 else */
516 cs->cx = 600;
517 cs->cy = 400;
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" );
527 return 0;
530 /* Fill the window structure */
532 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
533 wndPtr->next = NULL;
534 wndPtr->child = NULL;
536 if (cs->style & WS_CHILD)
538 wndPtr->parent = WIN_FindWndPtr( cs->hwndParent );
539 wndPtr->owner = NULL;
541 else
543 wndPtr->parent = pWndDesktop;
544 if (!cs->hwndParent || (cs->hwndParent == pWndDesktop->hwndSelf))
545 wndPtr->owner = NULL;
546 else
547 wndPtr->owner = WIN_FindWndPtr(WIN_GetTopParent(cs->hwndParent));
550 wndPtr->window = 0;
551 wndPtr->class = classPtr;
552 wndPtr->winproc = NULL;
553 wndPtr->dwMagic = WND_MAGIC;
554 wndPtr->hwndSelf = hwnd;
555 wndPtr->hInstance = cs->hInstance;
556 wndPtr->ptIconPos.x = -1;
557 wndPtr->ptIconPos.y = -1;
558 wndPtr->ptMaxPos.x = -1;
559 wndPtr->ptMaxPos.y = -1;
560 wndPtr->text = NULL;
561 wndPtr->hmemTaskQ = GetTaskQueue(0);
562 wndPtr->hrgnUpdate = 0;
563 wndPtr->hwndLastActive = hwnd;
564 wndPtr->dwStyle = cs->style & ~WS_VISIBLE;
565 wndPtr->dwExStyle = cs->dwExStyle;
566 wndPtr->wIDmenu = 0;
567 wndPtr->flags = 0;
568 wndPtr->pVScroll = NULL;
569 wndPtr->pHScroll = NULL;
570 wndPtr->pProp = NULL;
571 wndPtr->hSysMenu = MENU_GetDefSysMenu();
572 wndPtr->userdata = 0;
574 if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
576 /* Call the WH_CBT hook */
578 hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
580 if (HOOK_GetHook( WH_CBT, GetTaskQueue(0) ))
582 CBT_CREATEWND16* cbtc;
584 if ((cbtc = SEGPTR_NEW(CBT_CREATEWND16)))
586 /* Dummy message params to use WINPROC_MapMsg functions */
587 UINT16 msg;
588 WPARAM16 wparam;
589 LPARAM lparam;
591 /* Map the CREATESTRUCT to 16-bit format */
592 lparam = (LPARAM)cs;
593 if (unicode)
594 WINPROC_MapMsg32WTo16( WM_CREATE, 0, &msg, &wparam, &lparam );
595 else
596 WINPROC_MapMsg32ATo16( WM_CREATE, 0, &msg, &wparam, &lparam );
597 cbtc->lpcs = (CREATESTRUCT16 *)lparam;
598 cbtc->hwndInsertAfter = hwndLinkAfter;
599 wmcreate = !HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, hwnd,
600 (LPARAM)SEGPTR_GET(cbtc) );
601 WINPROC_UnmapMsg32ATo16( WM_CREATE, 0, lparam );
602 SEGPTR_FREE(cbtc);
603 if (!wmcreate)
605 dprintf_win(stddeb,"CreateWindowEx: CBT-hook returned 0\n" );
606 USER_HEAP_FREE( hwnd );
607 return 0;
612 /* Set the window procedure */
614 classPtr->cWindows++;
615 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)classPtr->winproc, 0 );
617 /* Correct the window style */
619 if (!(cs->style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
621 wndPtr->dwStyle |= WS_CAPTION | WS_CLIPSIBLINGS;
622 wndPtr->flags |= WIN_NEED_SIZE;
624 if (cs->dwExStyle & WS_EX_DLGMODALFRAME) wndPtr->dwStyle &= ~WS_THICKFRAME;
626 /* Get class or window DC if needed */
628 if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC);
629 else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce;
630 else wndPtr->dce = NULL;
632 /* Insert the window in the linked list */
634 WIN_LinkWindow( hwnd, hwndLinkAfter );
636 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
638 if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
640 NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
641 if (maxSize.x < cs->cx) cs->cx = maxSize.x;
642 if (maxSize.y < cs->cy) cs->cy = maxSize.y;
643 if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
644 if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
646 if (cs->cx <= 0) cs->cx = 1;
647 if (cs->cy <= 0) cs->cy = 1;
649 wndPtr->rectWindow.left = cs->x;
650 wndPtr->rectWindow.top = cs->y;
651 wndPtr->rectWindow.right = cs->x + cs->cx;
652 wndPtr->rectWindow.bottom = cs->y + cs->cy;
653 wndPtr->rectClient = wndPtr->rectWindow;
654 wndPtr->rectNormal = wndPtr->rectWindow;
656 /* Create the X window (only for top-level windows, and then only */
657 /* when there's no desktop window) */
659 if (!(cs->style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
661 XSetWindowAttributes win_attr;
662 Atom XA_WM_DELETE_WINDOW;
664 if (Options.managed && ((cs->style & (WS_DLGFRAME | WS_THICKFRAME)) ||
665 (cs->dwExStyle & WS_EX_DLGMODALFRAME)))
667 win_attr.event_mask = ExposureMask | KeyPressMask |
668 KeyReleaseMask | PointerMotionMask |
669 ButtonPressMask | ButtonReleaseMask |
670 FocusChangeMask | StructureNotifyMask;
671 win_attr.override_redirect = FALSE;
672 wndPtr->flags |= WIN_MANAGED;
674 else
676 win_attr.event_mask = ExposureMask | KeyPressMask |
677 KeyReleaseMask | PointerMotionMask |
678 ButtonPressMask | ButtonReleaseMask |
679 FocusChangeMask | StructureNotifyMask;
680 win_attr.override_redirect = TRUE;
682 win_attr.colormap = COLOR_GetColormap();
683 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
684 win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0);
685 win_attr.cursor = CURSORICON_XCursor;
686 wndPtr->window = XCreateWindow( display, rootWindow, cs->x, cs->y,
687 cs->cx, cs->cy, 0, CopyFromParent,
688 InputOutput, CopyFromParent,
689 CWEventMask | CWOverrideRedirect |
690 CWColormap | CWCursor | CWSaveUnder |
691 CWBackingStore, &win_attr );
692 XA_WM_DELETE_WINDOW = XInternAtom( display, "WM_DELETE_WINDOW",
693 False );
694 XSetWMProtocols( display, wndPtr->window, &XA_WM_DELETE_WINDOW, 1 );
696 if ((wndPtr->flags & WIN_MANAGED) &&
697 (cs->dwExStyle & WS_EX_DLGMODALFRAME))
699 XSizeHints* size_hints = XAllocSizeHints();
701 if (size_hints)
703 size_hints->min_width = size_hints->max_width = cs->cx;
704 size_hints->min_height = size_hints->max_height = cs->cy;
705 size_hints->flags = (PSize | PMinSize | PMaxSize);
706 XSetWMSizeHints( display, wndPtr->window, size_hints,
707 XA_WM_NORMAL_HINTS );
708 XFree(size_hints);
712 if (cs->hwndParent) /* Get window owner */
714 Window win = WIN_GetXWindow( cs->hwndParent );
715 if (win) XSetTransientForHint( display, wndPtr->window, win );
717 EVENT_RegisterWindow( wndPtr );
720 /* Set the window menu */
722 if ((cs->style & WS_CAPTION) && !(cs->style & WS_CHILD))
724 if (cs->hMenu) SetMenu(hwnd, cs->hMenu);
725 else
727 #if 0 /* FIXME: should check if classPtr->menuNameW can be used as is */
728 if (classPtr->menuNameA)
729 cs->hMenu = HIWORD(classPtr->menuNameA) ?
730 LoadMenu(cs->hInstance,SEGPTR_GET(classPtr->menuNameA)):
731 LoadMenu(cs->hInstance,(SEGPTR)classPtr->menuNameA);
732 #else
733 SEGPTR menuName = (SEGPTR)GetClassLong16( hwnd, GCL_MENUNAME );
734 if (menuName) cs->hMenu = LoadMenu16( cs->hInstance, menuName );
735 #endif
737 if (cs->hMenu) SetMenu( hwnd, cs->hMenu );
739 else wndPtr->wIDmenu = (UINT)cs->hMenu;
741 /* Send the WM_CREATE message */
743 if (unicode)
745 if (!SendMessage32W( hwnd, WM_NCCREATE, 0, (LPARAM)cs)) wmcreate = -1;
746 else
748 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
749 NULL, NULL, 0, &wndPtr->rectClient );
750 wmcreate = SendMessage32W( hwnd, WM_CREATE, 0, (LPARAM)cs );
753 else
755 if (!SendMessage32A( hwnd, WM_NCCREATE, 0, (LPARAM)cs)) wmcreate = -1;
756 else
758 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
759 NULL, NULL, 0, &wndPtr->rectClient );
760 wmcreate = SendMessage32A( hwnd, WM_CREATE, 0, (LPARAM)cs );
764 if (wmcreate == -1)
766 /* Abort window creation */
767 dprintf_win(stddeb,"CreateWindowEx: wmcreate==-1, aborting\n");
768 WIN_UnlinkWindow( hwnd );
769 WIN_DestroyWindow( wndPtr );
770 return 0;
773 /* Send the size messages */
775 if (!(wndPtr->flags & WIN_NEED_SIZE))
777 /* send it anyway */
778 SendMessage16( hwnd, WM_SIZE, SIZE_RESTORED,
779 MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
780 wndPtr->rectClient.bottom-wndPtr->rectClient.top));
781 SendMessage16( hwnd, WM_MOVE, 0, MAKELONG( wndPtr->rectClient.left,
782 wndPtr->rectClient.top ));
785 WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LPARAM)hwnd );
786 if (!IsWindow(hwnd)) return 0;
788 /* Show the window, maximizing or minimizing if needed */
790 if (wndPtr->dwStyle & WS_MINIMIZE)
792 /* MinMaximize(hwnd, SW_SHOWMINNOACTIVE, 1) in "Internals" */
794 wndPtr->dwStyle &= ~WS_MAXIMIZE;
795 WINPOS_FindIconPos( hwnd );
796 SetWindowPos( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
797 SYSMETRICS_CXICON, SYSMETRICS_CYICON,
798 SWP_FRAMECHANGED | ((GetActiveWindow())? SWP_NOACTIVATE : 0) );
800 else if (wndPtr->dwStyle & WS_MAXIMIZE)
802 /* MinMaximize(hwnd, SW_SHOWMAXIMIZED, 1) */
804 POINT16 maxSize, maxPos, minTrack, maxTrack;
805 NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
806 SetWindowPos( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
807 ((GetActiveWindow())? SWP_NOACTIVATE : 0) | SWP_FRAMECHANGED );
810 if (cs->style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
812 /* Call WH_SHELL hook */
814 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
815 HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
817 dprintf_win(stddeb, "CreateWindowEx: returning %04x\n", hwnd);
818 return hwnd;
822 /***********************************************************************
823 * CreateWindow16 (USER.41)
825 HWND16 CreateWindow16( LPCSTR className, LPCSTR windowName,
826 DWORD style, INT16 x, INT16 y, INT16 width,
827 INT16 height, HWND16 parent, HMENU16 menu,
828 HINSTANCE16 instance, LPVOID data )
830 return CreateWindowEx16( 0, className, windowName, style,
831 x, y, width, height, parent, menu, instance, data );
835 /***********************************************************************
836 * CreateWindowEx16 (USER.452)
838 HWND16 CreateWindowEx16( DWORD exStyle, LPCSTR className, LPCSTR windowName,
839 DWORD style, INT16 x, INT16 y, INT16 width,
840 INT16 height, HWND16 parent, HMENU16 menu,
841 HINSTANCE16 instance, LPVOID data )
843 ATOM classAtom;
844 CREATESTRUCT32A cs;
846 /* Find the class atom */
848 if (!(classAtom = GlobalFindAtom32A( className )))
850 fprintf( stderr, "CreateWindowEx16: bad class name " );
851 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
852 else fprintf( stderr, "'%s'\n", className );
853 return 0;
856 /* Fix the coordinates */
858 cs.x = (x == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)x;
859 cs.y = (y == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)y;
860 cs.cx = (width == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)width;
861 cs.cy = (height == CW_USEDEFAULT16) ? CW_USEDEFAULT32 : (INT32)height;
863 /* Create the window */
865 cs.lpCreateParams = data;
866 cs.hInstance = (HINSTANCE32)instance;
867 cs.hMenu = (HMENU32)menu;
868 cs.hwndParent = (HWND32)parent;
869 cs.style = style;
870 cs.lpszName = windowName;
871 cs.lpszClass = className;
872 cs.dwExStyle = exStyle;
873 return WIN_CreateWindowEx( &cs, classAtom, FALSE );
877 /***********************************************************************
878 * CreateWindowEx32A (USER32.82)
880 HWND32 CreateWindowEx32A( DWORD exStyle, LPCSTR className, LPCSTR windowName,
881 DWORD style, INT32 x, INT32 y, INT32 width,
882 INT32 height, HWND32 parent, HMENU32 menu,
883 HINSTANCE32 instance, LPVOID data )
885 ATOM classAtom;
886 CREATESTRUCT32A cs;
888 /* Find the class atom */
890 if (!(classAtom = GlobalFindAtom32A( className )))
892 fprintf( stderr, "CreateWindowEx32A: bad class name " );
893 if (!HIWORD(className)) fprintf( stderr, "%04x\n", LOWORD(className) );
894 else fprintf( stderr, "'%s'\n", className );
895 return 0;
898 /* Create the window */
900 cs.lpCreateParams = data;
901 cs.hInstance = instance;
902 cs.hMenu = menu;
903 cs.hwndParent = parent;
904 cs.x = x;
905 cs.y = y;
906 cs.cx = width;
907 cs.cy = height;
908 cs.style = style;
909 cs.lpszName = windowName;
910 cs.lpszClass = className;
911 cs.dwExStyle = exStyle;
912 return WIN_CreateWindowEx( &cs, classAtom, FALSE );
916 /***********************************************************************
917 * CreateWindowEx32W (USER32.83)
919 HWND32 CreateWindowEx32W( DWORD exStyle, LPCWSTR className, LPCWSTR windowName,
920 DWORD style, INT32 x, INT32 y, INT32 width,
921 INT32 height, HWND32 parent, HMENU32 menu,
922 HINSTANCE32 instance, LPVOID data )
924 ATOM classAtom;
925 CREATESTRUCT32W cs;
927 /* Find the class atom */
929 if (!(classAtom = GlobalFindAtom32W( className )))
931 if (HIWORD(className))
933 LPSTR cn = STRING32_DupUniToAnsi(className);
934 fprintf( stderr, "CreateWindowEx32W: bad class name '%s'\n",cn);
935 free(cn);
937 else
938 fprintf( stderr, "CreateWindowEx32W: bad class name %p\n", className );
939 return 0;
942 /* Create the window */
944 cs.lpCreateParams = data;
945 cs.hInstance = instance;
946 cs.hMenu = menu;
947 cs.hwndParent = parent;
948 cs.x = x;
949 cs.y = y;
950 cs.cx = width;
951 cs.cy = height;
952 cs.style = style;
953 cs.lpszName = windowName;
954 cs.lpszClass = className;
955 cs.dwExStyle = exStyle;
956 /* Note: we rely on the fact that CREATESTRUCT32A and */
957 /* CREATESTRUCT32W have the same layout. */
958 return WIN_CreateWindowEx( (CREATESTRUCT32A *)&cs, classAtom, TRUE );
962 /***********************************************************************
963 * WIN_CheckFocus
965 static void WIN_CheckFocus( WND* pWnd )
967 if( GetFocus16() == pWnd->hwndSelf )
968 SetFocus16( (pWnd->dwStyle & WS_CHILD) ? pWnd->parent->hwndSelf : 0 );
971 /***********************************************************************
972 * WIN_SendDestroyMsg
974 static void WIN_SendDestroyMsg( WND* pWnd )
976 WND* pChild;
978 WIN_CheckFocus(pWnd);
980 if( CARET_GetHwnd() == pWnd->hwndSelf ) DestroyCaret();
981 if( !pWnd->window ) CLIPBOARD_DisOwn( pWnd );
983 SendMessage32A( pWnd->hwndSelf, WM_DESTROY, 0, 0);
985 if( !IsWindow(pWnd->hwndSelf) )
987 dprintf_win(stddeb,"\tdestroyed itself while in WM_DESTROY!\n");
988 return;
991 pChild = pWnd->child;
992 while( pChild )
994 WIN_SendDestroyMsg( pChild );
995 pChild = pChild->next;
997 WIN_CheckFocus(pWnd);
1001 /***********************************************************************
1002 * DestroyWindow (USER.53)
1004 BOOL DestroyWindow( HWND hwnd )
1006 WND * wndPtr;
1008 dprintf_win(stddeb, "DestroyWindow(%04x)\n", hwnd);
1010 /* Initialization */
1012 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1013 if (wndPtr == pWndDesktop) return FALSE; /* Can't destroy desktop */
1015 /* Call hooks */
1017 if( HOOK_CallHooks( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
1018 return FALSE;
1020 if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
1022 HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
1023 /* FIXME: clean up palette - see "Internals" p.352 */
1026 if( !QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ) )
1027 WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
1028 if( !IsWindow(hwnd) ) return TRUE;
1030 if( wndPtr->window ) CLIPBOARD_DisOwn( wndPtr ); /* before window is unmapped */
1032 /* Hide the window */
1034 if (wndPtr->dwStyle & WS_VISIBLE)
1036 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW |
1037 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE |
1038 ((QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ))?SWP_DEFERERASE:0) );
1039 if( !IsWindow(hwnd) ) return TRUE;
1042 /* Recursively destroy owned windows */
1044 if( !(wndPtr->dwStyle & WS_CHILD) )
1046 for (;;)
1048 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
1049 while (siblingPtr)
1051 if (siblingPtr->owner == wndPtr)
1052 if (siblingPtr->hmemTaskQ == wndPtr->hmemTaskQ)
1053 break;
1054 else
1055 siblingPtr->owner = NULL;
1056 siblingPtr = siblingPtr->next;
1058 if (siblingPtr) DestroyWindow( siblingPtr->hwndSelf );
1059 else break;
1062 WINPOS_ActivateOtherWindow(wndPtr);
1064 if( wndPtr->owner &&
1065 wndPtr->owner->hwndLastActive == wndPtr->hwndSelf )
1066 wndPtr->owner->hwndLastActive = wndPtr->owner->hwndSelf;
1069 /* Send destroy messages */
1071 WIN_SendDestroyMsg( wndPtr );
1072 if( !IsWindow(hwnd) ) return TRUE;
1074 /* Unlink now so we won't bother with the children later on */
1076 if( wndPtr->parent ) WIN_UnlinkWindow(hwnd);
1078 /* Destroy the window storage */
1080 WIN_DestroyWindow( wndPtr );
1081 return TRUE;
1085 /***********************************************************************
1086 * CloseWindow (USER.43)
1088 BOOL CloseWindow(HWND hWnd)
1090 WND * wndPtr = WIN_FindWndPtr(hWnd);
1091 if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return TRUE;
1092 ShowWindow(hWnd, SW_MINIMIZE);
1093 return TRUE;
1097 /***********************************************************************
1098 * OpenIcon (USER.44)
1100 BOOL OpenIcon(HWND hWnd)
1102 if (!IsIconic(hWnd)) return FALSE;
1103 ShowWindow(hWnd, SW_SHOWNORMAL);
1104 return(TRUE);
1108 /***********************************************************************
1109 * WIN_FindWindow
1111 * Implementation of FindWindow() and FindWindowEx().
1113 static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className,
1114 LPCSTR title )
1116 WND *pWnd;
1117 CLASS *pClass = NULL;
1119 if (child)
1121 if (!(pWnd = WIN_FindWndPtr( child ))) return 0;
1122 if (parent)
1124 if (!pWnd->parent || (pWnd->parent->hwndSelf != parent)) return 0;
1126 else if (pWnd->parent != pWndDesktop) return 0;
1127 pWnd = pWnd->next;
1129 else
1131 if (!(pWnd = parent ? WIN_FindWndPtr(parent) : pWndDesktop)) return 0;
1132 pWnd = pWnd->child;
1134 if (!pWnd) return 0;
1136 /* For a child window, all siblings will have the same hInstance, */
1137 /* so we can look for the class once and for all. */
1139 if (className && (pWnd->dwStyle & WS_CHILD))
1141 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance )))
1142 return 0;
1145 for ( ; pWnd; pWnd = pWnd->next)
1147 if (className && !(pWnd->dwStyle & WS_CHILD))
1149 if (!(pClass = CLASS_FindClassByAtom( className, pWnd->hInstance)))
1150 continue; /* Skip this window */
1152 if (pClass && (pWnd->class != pClass))
1153 continue; /* Not the right class */
1155 /* Now check the title */
1157 if (!title) return pWnd->hwndSelf;
1158 if (pWnd->text && !strcmp( pWnd->text, title )) return pWnd->hwndSelf;
1160 return 0;
1165 /***********************************************************************
1166 * FindWindow16 (USER.50)
1168 HWND16 FindWindow16( SEGPTR className, LPCSTR title )
1170 return FindWindowEx16( 0, 0, className, title );
1174 /***********************************************************************
1175 * FindWindowEx16 (USER.427)
1177 HWND16 FindWindowEx16( HWND16 parent, HWND16 child,
1178 SEGPTR className, LPCSTR title )
1180 ATOM atom = 0;
1182 if (className)
1184 /* If the atom doesn't exist, then no class */
1185 /* with this name exists either. */
1186 if (!(atom = GlobalFindAtom16( className ))) return 0;
1188 return WIN_FindWindow( parent, child, atom, title );
1192 /***********************************************************************
1193 * FindWindow32A (USER32.197)
1195 HWND32 FindWindow32A( LPCSTR className, LPCSTR title )
1197 return FindWindowEx32A( 0, 0, className, title );
1201 /***********************************************************************
1202 * FindWindowEx32A (USER32.198)
1204 HWND32 FindWindowEx32A( HWND32 parent, HWND32 child,
1205 LPCSTR className, LPCSTR title )
1207 ATOM atom = 0;
1209 if (className)
1211 /* If the atom doesn't exist, then no class */
1212 /* with this name exists either. */
1213 if (!(atom = GlobalFindAtom32A( className ))) return 0;
1215 return WIN_FindWindow( 0, 0, atom, title );
1219 /***********************************************************************
1220 * FindWindowEx32W (USER32.199)
1222 HWND32 FindWindowEx32W( HWND32 parent, HWND32 child,
1223 LPCWSTR className, LPCWSTR title )
1225 ATOM atom = 0;
1226 char *buffer;
1227 HWND hwnd;
1229 if (className)
1231 /* If the atom doesn't exist, then no class */
1232 /* with this name exists either. */
1233 if (!(atom = GlobalFindAtom32W( className ))) return 0;
1235 buffer = title ? STRING32_DupUniToAnsi( title ) : NULL;
1236 hwnd = WIN_FindWindow( 0, 0, atom, buffer );
1237 if (buffer) free( buffer );
1238 return hwnd;
1242 /***********************************************************************
1243 * FindWindow32W (USER32.200)
1245 HWND32 FindWindow32W( LPCWSTR className, LPCWSTR title )
1247 return FindWindowEx32W( 0, 0, className, title );
1251 /**********************************************************************
1252 * WIN_GetDesktop
1254 WND *WIN_GetDesktop(void)
1256 return pWndDesktop;
1260 /**********************************************************************
1261 * GetDesktopWindow16 (USER.286)
1263 HWND16 GetDesktopWindow16(void)
1265 return (HWND16)pWndDesktop->hwndSelf;
1269 /**********************************************************************
1270 * GetDesktopWindow32 (USER32.231)
1272 HWND32 GetDesktopWindow32(void)
1274 return pWndDesktop->hwndSelf;
1278 /**********************************************************************
1279 * GetDesktopHwnd (USER.278)
1281 * Exactly the same thing as GetDesktopWindow(), but not documented.
1282 * Don't ask me why...
1284 HWND16 GetDesktopHwnd(void)
1286 return (HWND16)pWndDesktop->hwndSelf;
1290 /*******************************************************************
1291 * EnableWindow (USER.34)
1293 BOOL EnableWindow( HWND hwnd, BOOL enable )
1295 WND *wndPtr;
1297 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1298 if (enable && (wndPtr->dwStyle & WS_DISABLED))
1300 /* Enable window */
1301 wndPtr->dwStyle &= ~WS_DISABLED;
1302 SendMessage16( hwnd, WM_ENABLE, TRUE, 0 );
1303 return TRUE;
1305 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
1307 /* Disable window */
1308 wndPtr->dwStyle |= WS_DISABLED;
1309 if ((hwnd == GetFocus32()) || IsChild( hwnd, GetFocus32() ))
1310 SetFocus32( 0 ); /* A disabled window can't have the focus */
1311 if ((hwnd == GetCapture32()) || IsChild( hwnd, GetCapture32() ))
1312 ReleaseCapture(); /* A disabled window can't capture the mouse */
1313 SendMessage16( hwnd, WM_ENABLE, FALSE, 0 );
1314 return FALSE;
1316 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
1320 /***********************************************************************
1321 * IsWindowEnabled (USER.35) (USER32.348)
1323 BOOL IsWindowEnabled(HWND hWnd)
1325 WND * wndPtr;
1327 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
1328 return !(wndPtr->dwStyle & WS_DISABLED);
1332 /***********************************************************************
1333 * IsWindowUnicode (USER32.349)
1335 BOOL32 IsWindowUnicode( HWND32 hwnd )
1337 WND * wndPtr;
1339 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE;
1340 return (WINPROC_GetProcType( wndPtr->winproc ) == WIN_PROC_32W);
1344 /**********************************************************************
1345 * GetWindowWord (USER.133) (USER32.313)
1347 WORD GetWindowWord( HWND32 hwnd, INT32 offset )
1349 WND * wndPtr = WIN_FindWndPtr( hwnd );
1350 if (!wndPtr) return 0;
1351 if (offset >= 0)
1353 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1355 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1356 return 0;
1358 return *(WORD *)(((char *)wndPtr->wExtra) + offset);
1360 switch(offset)
1362 case GWW_ID: return wndPtr->wIDmenu;
1363 case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
1364 case GWW_HINSTANCE: return (WORD)wndPtr->hInstance;
1365 default:
1366 fprintf( stderr, "GetWindowWord: invalid offset %d\n", offset );
1367 return 0;
1372 /**********************************************************************
1373 * WIN_GetWindowInstance
1375 HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd )
1377 WND * wndPtr = WIN_FindWndPtr( hwnd );
1378 if (!wndPtr) return (HINSTANCE16)0;
1379 return wndPtr->hInstance;
1383 /**********************************************************************
1384 * SetWindowWord (USER.134) (USER32.523)
1386 WORD SetWindowWord( HWND32 hwnd, INT32 offset, WORD newval )
1388 WORD *ptr, retval;
1389 WND * wndPtr = WIN_FindWndPtr( hwnd );
1390 if (!wndPtr) return 0;
1391 if (offset >= 0)
1393 if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra)
1395 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1396 return 0;
1398 ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
1400 else switch(offset)
1402 case GWW_ID: ptr = (WORD *)&wndPtr->wIDmenu; break;
1403 case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
1404 default:
1405 fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
1406 return 0;
1408 retval = *ptr;
1409 *ptr = newval;
1410 return retval;
1414 /**********************************************************************
1415 * WIN_GetWindowLong
1417 * Helper function for GetWindowLong().
1419 static LONG WIN_GetWindowLong( HWND32 hwnd, INT32 offset, WINDOWPROCTYPE type )
1421 LONG retval;
1422 WND * wndPtr = WIN_FindWndPtr( hwnd );
1423 if (!wndPtr) return 0;
1424 if (offset >= 0)
1426 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1428 fprintf( stderr, "GetWindowLong: invalid offset %d\n", offset );
1429 return 0;
1431 retval = *(LONG *)(((char *)wndPtr->wExtra) + offset);
1432 /* Special case for dialog window procedure */
1433 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1434 return (LONG)WINPROC_GetProc( (HWINDOWPROC)retval, type );
1435 return retval;
1437 switch(offset)
1439 case GWL_USERDATA: return wndPtr->userdata;
1440 case GWL_STYLE: return wndPtr->dwStyle;
1441 case GWL_EXSTYLE: return wndPtr->dwExStyle;
1442 case GWL_ID: return wndPtr->wIDmenu;
1443 case GWL_WNDPROC: return (LONG)WINPROC_GetProc( wndPtr->winproc,
1444 type );
1445 case GWL_HWNDPARENT: return wndPtr->parent ?
1446 (HWND32)wndPtr->parent->hwndSelf : 0;
1447 case GWL_HINSTANCE: return (HINSTANCE32)wndPtr->hInstance;
1448 default:
1449 fprintf( stderr, "GetWindowLong: unknown offset %d\n", offset );
1451 return 0;
1455 /**********************************************************************
1456 * WIN_SetWindowLong
1458 * Helper function for SetWindowLong().
1460 static LONG WIN_SetWindowLong( HWND32 hwnd, INT32 offset, LONG newval,
1461 WINDOWPROCTYPE type )
1463 LONG *ptr, retval;
1464 WND * wndPtr = WIN_FindWndPtr( hwnd );
1465 if (!wndPtr) return 0;
1466 if (offset >= 0)
1468 if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra)
1470 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1471 return 0;
1473 ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
1474 /* Special case for dialog window procedure */
1475 if ((offset == DWL_DLGPROC) && (wndPtr->flags & WIN_ISDIALOG))
1477 retval = (LONG)WINPROC_GetProc( (HWINDOWPROC)*ptr, type );
1478 WINPROC_SetProc( (HWINDOWPROC *)ptr, (WNDPROC16)newval, type );
1479 return retval;
1482 else switch(offset)
1484 case GWL_ID:
1485 case GWL_HINSTANCE:
1486 return SetWindowWord( hwnd, offset, (WORD)newval );
1487 case GWL_WNDPROC:
1488 retval = (LONG)WINPROC_GetProc( wndPtr->winproc, type );
1489 WINPROC_SetProc( &wndPtr->winproc, (WNDPROC16)newval, type );
1490 return retval;
1491 case GWL_STYLE:
1492 ptr = &wndPtr->dwStyle;
1493 /* Some bits can't be changed this way */
1494 newval &= ~(WS_VISIBLE | WS_CHILD);
1495 newval |= (*ptr & (WS_VISIBLE | WS_CHILD));
1496 break;
1497 case GWL_USERDATA: ptr = &wndPtr->userdata; break;
1498 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
1499 default:
1500 fprintf( stderr, "SetWindowLong: invalid offset %d\n", offset );
1501 return 0;
1503 retval = *ptr;
1504 *ptr = newval;
1505 return retval;
1509 /**********************************************************************
1510 * GetWindowLong16 (USER.135)
1512 LONG GetWindowLong16( HWND16 hwnd, INT16 offset )
1514 return WIN_GetWindowLong( (HWND32)hwnd, offset, WIN_PROC_16 );
1518 /**********************************************************************
1519 * GetWindowLong32A (USER32.304)
1521 LONG GetWindowLong32A( HWND32 hwnd, INT32 offset )
1523 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32A );
1527 /**********************************************************************
1528 * GetWindowLong32W (USER32.305)
1530 LONG GetWindowLong32W( HWND32 hwnd, INT32 offset )
1532 return WIN_GetWindowLong( hwnd, offset, WIN_PROC_32W );
1536 /**********************************************************************
1537 * SetWindowLong16 (USER.136)
1539 LONG SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval )
1541 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_16 );
1545 /**********************************************************************
1546 * SetWindowLong32A (USER32.516)
1548 LONG SetWindowLong32A( HWND32 hwnd, INT32 offset, LONG newval )
1550 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32A );
1554 /**********************************************************************
1555 * SetWindowLong32W (USER32.517)
1557 LONG SetWindowLong32W( HWND32 hwnd, INT32 offset, LONG newval )
1559 return WIN_SetWindowLong( hwnd, offset, newval, WIN_PROC_32W );
1563 /*******************************************************************
1564 * GetWindowText16 (USER.36)
1566 INT16 GetWindowText16( HWND16 hwnd, SEGPTR lpString, INT16 nMaxCount )
1568 return (INT16)SendMessage16(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
1572 /*******************************************************************
1573 * GetWindowText32A (USER32.308)
1575 INT32 GetWindowText32A( HWND32 hwnd, LPSTR lpString, INT32 nMaxCount )
1577 return (INT32)SendMessage32A( hwnd, WM_GETTEXT, nMaxCount,
1578 (LPARAM)lpString );
1582 /*******************************************************************
1583 * GetWindowText32W (USER32.311)
1585 INT32 GetWindowText32W( HWND32 hwnd, LPWSTR lpString, INT32 nMaxCount )
1587 return (INT32)SendMessage32W( hwnd, WM_GETTEXT, nMaxCount,
1588 (LPARAM)lpString );
1592 /*******************************************************************
1593 * SetWindowText16 (USER.37)
1595 void SetWindowText16( HWND16 hwnd, SEGPTR lpString )
1597 SendMessage16( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1601 /*******************************************************************
1602 * SetWindowText32A (USER32.)
1604 void SetWindowText32A( HWND32 hwnd, LPCSTR lpString )
1606 SendMessage32A( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1610 /*******************************************************************
1611 * SetWindowText32W (USER32.)
1613 void SetWindowText32W( HWND32 hwnd, LPCWSTR lpString )
1615 SendMessage32W( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1619 /*******************************************************************
1620 * GetWindowTextLength (USER.38)
1622 int GetWindowTextLength(HWND hwnd)
1624 return (int)SendMessage16(hwnd, WM_GETTEXTLENGTH, 0, 0 );
1628 /*******************************************************************
1629 * IsWindow (USER.47) (USER32.347)
1631 BOOL16 IsWindow( HWND32 hwnd )
1633 WND * wndPtr = WIN_FindWndPtr( hwnd );
1634 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1638 /*****************************************************************
1639 * GetParent16 (USER.46)
1641 HWND16 GetParent16( HWND16 hwnd )
1643 return (HWND16)GetParent32( hwnd );
1647 /*****************************************************************
1648 * GetParent32 (USER32.277)
1650 HWND32 GetParent32( HWND32 hwnd )
1652 WND *wndPtr = WIN_FindWndPtr(hwnd);
1653 if (!wndPtr) return 0;
1654 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1655 return wndPtr ? wndPtr->hwndSelf : 0;
1659 /*****************************************************************
1660 * WIN_GetTopParent
1662 * Get the top-level parent for a child window.
1664 HWND32 WIN_GetTopParent( HWND32 hwnd )
1666 WND *wndPtr = WIN_FindWndPtr( hwnd );
1667 while (wndPtr && (wndPtr->dwStyle & WS_CHILD)) wndPtr = wndPtr->parent;
1668 return wndPtr ? wndPtr->hwndSelf : 0;
1672 /*****************************************************************
1673 * SetParent (USER.233)
1675 HWND SetParent(HWND hwndChild, HWND hwndNewParent)
1677 HWND oldParent;
1679 WND *wndPtr = WIN_FindWndPtr(hwndChild);
1680 WND *pWndParent = WIN_FindWndPtr( hwndNewParent );
1681 if (!wndPtr || !pWndParent || !(wndPtr->dwStyle & WS_CHILD)) return 0;
1683 oldParent = wndPtr->parent->hwndSelf;
1685 WIN_UnlinkWindow(hwndChild);
1686 if (hwndNewParent) wndPtr->parent = pWndParent;
1687 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
1689 if (IsWindowVisible(hwndChild)) UpdateWindow(hwndChild);
1691 return oldParent;
1696 /*******************************************************************
1697 * IsChild (USER.48)
1699 BOOL IsChild( HWND parent, HWND child )
1701 WND * wndPtr = WIN_FindWndPtr( child );
1702 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1704 wndPtr = wndPtr->parent;
1705 if (wndPtr->hwndSelf == parent) return TRUE;
1707 return FALSE;
1711 /***********************************************************************
1712 * IsWindowVisible (USER.49) (USER32.350)
1714 BOOL IsWindowVisible( HWND hwnd )
1716 WND *wndPtr = WIN_FindWndPtr( hwnd );
1717 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1719 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1720 wndPtr = wndPtr->parent;
1722 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1725 /***********************************************************************
1726 * WIN_IsWindowDrawable
1728 * hwnd is drawable when it is visible, all parents are not
1729 * minimized, and it is itself not minimized unless we are
1730 * trying to draw icon and the default class icon is set.
1732 BOOL32 WIN_IsWindowDrawable( WND* wnd , BOOL32 icon )
1734 HWND hwnd= wnd->hwndSelf;
1735 BOOL32 yes = TRUE;
1737 while(wnd && yes)
1739 if( wnd->dwStyle & WS_MINIMIZE )
1740 if( wnd->hwndSelf != hwnd ) break;
1741 else if( icon && wnd->class->hIcon ) break;
1743 yes = yes && (wnd->dwStyle & WS_VISIBLE);
1744 wnd = wnd->parent; }
1745 return (!wnd && yes);
1748 /*******************************************************************
1749 * GetTopWindow (USER.229)
1751 HWND GetTopWindow( HWND hwnd )
1753 WND * wndPtr = WIN_FindWndPtr( hwnd );
1754 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1755 else return 0;
1759 /*******************************************************************
1760 * GetWindow (USER.262)
1762 HWND GetWindow( HWND hwnd, WORD rel )
1764 WND * wndPtr = WIN_FindWndPtr( hwnd );
1765 if (!wndPtr) return 0;
1766 switch(rel)
1768 case GW_HWNDFIRST:
1769 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
1770 else return 0;
1772 case GW_HWNDLAST:
1773 if (!wndPtr->parent) return 0; /* Desktop window */
1774 while (wndPtr->next) wndPtr = wndPtr->next;
1775 return wndPtr->hwndSelf;
1777 case GW_HWNDNEXT:
1778 if (!wndPtr->next) return 0;
1779 return wndPtr->next->hwndSelf;
1781 case GW_HWNDPREV:
1782 if (!wndPtr->parent) return 0; /* Desktop window */
1783 wndPtr = wndPtr->parent->child; /* First sibling */
1784 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
1785 while (wndPtr->next)
1787 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
1788 wndPtr = wndPtr->next;
1790 return 0;
1792 case GW_OWNER:
1793 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
1795 case GW_CHILD:
1796 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
1798 return 0;
1802 /*******************************************************************
1803 * GetNextWindow (USER.230)
1805 HWND GetNextWindow( HWND hwnd, WORD flag )
1807 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1808 return GetWindow( hwnd, flag );
1811 /*******************************************************************
1812 * ShowOwnedPopups (USER.265)
1814 void ShowOwnedPopups( HWND owner, BOOL fShow )
1816 WND *pWnd = pWndDesktop->child;
1817 while (pWnd)
1819 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
1820 (pWnd->dwStyle & WS_POPUP))
1821 ShowWindow( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
1822 pWnd = pWnd->next;
1827 /*******************************************************************
1828 * GetLastActivePopup (USER.287)
1830 HWND GetLastActivePopup(HWND hwnd)
1832 WND *wndPtr;
1833 wndPtr = WIN_FindWndPtr(hwnd);
1834 if (wndPtr == NULL) return hwnd;
1835 return wndPtr->hwndLastActive;
1839 /*******************************************************************
1840 * WIN_BuildWinArray
1842 * Build an array of pointers to all children of a given window.
1843 * The array must be freed with HeapFree(SystemHeap).
1845 WND **WIN_BuildWinArray( WND *wndPtr )
1847 WND **list, **ppWnd;
1848 WND *pWnd;
1849 INT32 count;
1851 /* First count the windows */
1853 if (!wndPtr) wndPtr = pWndDesktop;
1854 for (pWnd = wndPtr->child, count = 0; pWnd; pWnd = pWnd->next) count++;
1855 count++; /* For the terminating NULL */
1857 /* Now build the list of all windows */
1859 if (!(list = (WND **)HeapAlloc( SystemHeap, 0, sizeof(WND *) * count )))
1860 return NULL;
1861 for (pWnd = wndPtr->child, ppWnd = list; pWnd; pWnd = pWnd->next)
1862 *ppWnd++ = pWnd;
1863 *ppWnd = NULL;
1864 return list;
1868 /*******************************************************************
1869 * EnumWindows16 (USER.54)
1871 BOOL16 EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
1873 WND **list, **ppWnd;
1875 /* We have to build a list of all windows first, to avoid */
1876 /* unpleasant side-effects, for instance if the callback */
1877 /* function changes the Z-order of the windows. */
1879 if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
1881 /* Now call the callback function for every window */
1883 for (ppWnd = list; *ppWnd; ppWnd++)
1885 /* Make sure that the window still exists */
1886 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
1887 if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
1889 HeapFree( SystemHeap, 0, list );
1890 return TRUE;
1894 /*******************************************************************
1895 * EnumWindows32 (USER32.192)
1897 BOOL32 EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
1899 return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
1903 /**********************************************************************
1904 * EnumTaskWindows16 (USER.225)
1906 BOOL16 EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func, LPARAM lParam )
1908 WND **list, **ppWnd;
1909 HANDLE hQueue = GetTaskQueue( hTask );
1911 /* This function is the same as EnumWindows(), */
1912 /* except for an added check on the window queue. */
1914 if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
1916 /* Now call the callback function for every window */
1918 for (ppWnd = list; *ppWnd; ppWnd++)
1920 /* Make sure that the window still exists */
1921 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
1922 if ((*ppWnd)->hmemTaskQ != hQueue) continue; /* Check the queue */
1923 if (!func( (*ppWnd)->hwndSelf, lParam )) break;
1925 HeapFree( SystemHeap, 0, list );
1926 return TRUE;
1930 /**********************************************************************
1931 * EnumThreadWindows (USER32.189)
1933 BOOL32 EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
1935 return (BOOL16)EnumTaskWindows16((HTASK16)id, (WNDENUMPROC16)func, lParam);
1939 /**********************************************************************
1940 * WIN_EnumChildWindows
1942 * Helper function for EnumChildWindows().
1944 static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
1945 LPARAM lParam )
1947 WND **childList;
1948 BOOL16 ret = FALSE;
1950 while (*ppWnd)
1952 /* Make sure that the window still exists */
1953 if (!IsWindow((*ppWnd)->hwndSelf)) continue;
1954 /* Build children list first */
1955 if (!(childList = WIN_BuildWinArray( *ppWnd ))) return FALSE;
1956 if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
1957 ret = WIN_EnumChildWindows( childList, func, lParam );
1958 HeapFree( SystemHeap, 0, childList );
1959 if (!ret) return FALSE;
1960 ppWnd++;
1962 return TRUE;
1966 /**********************************************************************
1967 * EnumChildWindows16 (USER.55)
1969 BOOL16 EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func, LPARAM lParam )
1971 WND **list, *pParent;
1973 if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
1974 if (!(list = WIN_BuildWinArray( pParent ))) return FALSE;
1975 WIN_EnumChildWindows( list, func, lParam );
1976 HeapFree( SystemHeap, 0, list );
1977 return TRUE;
1981 /**********************************************************************
1982 * EnumChildWindows32 (USER32.177)
1984 BOOL32 EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func, LPARAM lParam )
1986 return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
1987 lParam );
1991 /*******************************************************************
1992 * AnyPopup (USER.52)
1994 BOOL AnyPopup(void)
1996 WND *wndPtr;
1997 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
1998 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
1999 return FALSE;
2002 /*******************************************************************
2003 * FlashWindow [USER.105]
2005 BOOL FlashWindow(HWND hWnd, BOOL bInvert)
2007 WND *wndPtr = WIN_FindWndPtr(hWnd);
2009 dprintf_win(stddeb,"FlashWindow: %04x\n", hWnd);
2011 if (!wndPtr) return FALSE;
2013 if (wndPtr->dwStyle & WS_MINIMIZE)
2015 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
2017 HDC32 hDC = GetDC32(hWnd);
2019 if (!SendMessage16( hWnd, WM_ERASEBKGND, (WPARAM)hDC, (LPARAM)0 ))
2020 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
2022 ReleaseDC32( hWnd, hDC );
2023 wndPtr->flags |= WIN_NCACTIVATED;
2025 else
2027 PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
2028 RDW_UPDATENOW | RDW_FRAME, 0 );
2029 wndPtr->flags &= ~WIN_NCACTIVATED;
2031 return TRUE;
2033 else
2035 WPARAM wparam;
2036 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
2037 else wparam = (hWnd == GetActiveWindow());
2039 SendMessage16( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
2040 return wparam;
2045 /*******************************************************************
2046 * SetSysModalWindow16 (USER.188)
2048 HWND16 SetSysModalWindow16( HWND16 hWnd )
2050 HWND hWndOldModal = hwndSysModal;
2051 hwndSysModal = hWnd;
2052 dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
2053 return hWndOldModal;
2057 /*******************************************************************
2058 * GetSysModalWindow16 (USER.52)
2060 HWND16 GetSysModalWindow16(void)
2062 return hwndSysModal;
2066 /*******************************************************************
2067 * DRAG_QueryUpdate
2069 * recursively find a child that contains spDragInfo->pt point
2070 * and send WM_QUERYDROPOBJECT
2072 BOOL DRAG_QueryUpdate( HWND hQueryWnd, SEGPTR spDragInfo )
2074 BOOL wParam,bResult = 0;
2075 POINT16 pt;
2076 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
2077 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
2078 RECT16 tempRect; /* this sucks */
2080 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
2082 pt = ptrDragInfo->pt;
2084 GetWindowRect16(hQueryWnd,&tempRect);
2086 if( !PtInRect16(&tempRect,pt) ||
2087 (ptrQueryWnd->dwStyle & WS_DISABLED) )
2088 return 0;
2090 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
2092 tempRect = ptrQueryWnd->rectClient;
2093 if(ptrQueryWnd->dwStyle & WS_CHILD)
2094 MapWindowPoints16(ptrQueryWnd->parent->hwndSelf,0,(LPPOINT16)&tempRect,2);
2096 if( PtInRect16(&tempRect,pt) )
2098 wParam = 0;
2100 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
2101 if( ptrWnd->dwStyle & WS_VISIBLE )
2103 GetWindowRect16(ptrWnd->hwndSelf,&tempRect);
2105 if( PtInRect16(&tempRect,pt) )
2106 break;
2109 if(ptrWnd)
2111 dprintf_msg(stddeb,"DragQueryUpdate: hwnd = %04x, %d %d - %d %d\n",
2112 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
2113 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
2114 if( !(ptrWnd->dwStyle & WS_DISABLED) )
2115 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo);
2118 if(bResult) return bResult;
2120 else wParam = 1;
2122 else wParam = 1;
2124 ScreenToClient16(hQueryWnd,&ptrDragInfo->pt);
2126 ptrDragInfo->hScope = hQueryWnd;
2128 bResult = SendMessage16( hQueryWnd ,WM_QUERYDROPOBJECT ,
2129 (WPARAM)wParam ,(LPARAM) spDragInfo );
2130 if( !bResult )
2131 ptrDragInfo->pt = pt;
2133 return bResult;
2136 /*******************************************************************
2137 * DragDetect ( USER.465 )
2140 BOOL16 DragDetect(HWND16 hWnd, POINT16 pt)
2142 MSG16 msg;
2143 RECT16 rect;
2145 rect.left = pt.x - wDragWidth;
2146 rect.right = pt.x + wDragWidth;
2148 rect.top = pt.y - wDragHeight;
2149 rect.bottom = pt.y + wDragHeight;
2151 SetCapture32(hWnd);
2153 while(1)
2155 while(PeekMessage16(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
2157 if( msg.message == WM_LBUTTONUP )
2159 ReleaseCapture();
2160 return 0;
2162 if( msg.message == WM_MOUSEMOVE )
2164 if( !PtInRect16( &rect, MAKEPOINT16(msg.lParam) ) )
2166 ReleaseCapture();
2167 return 1;
2171 WaitMessage();
2174 return 0;
2177 /******************************************************************************
2178 * DragObject ( USER.464 )
2181 DWORD DragObject(HWND hwndScope, HWND hWnd, WORD wObj, HANDLE hOfStruct,
2182 WORD szList , HCURSOR16 hCursor)
2184 MSG16 msg;
2185 LPDRAGINFO lpDragInfo;
2186 SEGPTR spDragInfo;
2187 HCURSOR16 hDragCursor=0, hOldCursor=0, hBummer=0;
2188 HANDLE hDragInfo = GlobalAlloc16( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
2189 WND *wndPtr = WIN_FindWndPtr(hWnd);
2190 DWORD dwRet = 0;
2191 short dragDone = 0;
2192 HCURSOR16 hCurrentCursor = 0;
2193 HWND hCurrentWnd = 0;
2194 WORD btemp;
2196 lpDragInfo = (LPDRAGINFO) GlobalLock16(hDragInfo);
2197 spDragInfo = (SEGPTR) WIN16_GlobalLock16(hDragInfo);
2199 if( !lpDragInfo || !spDragInfo ) return 0L;
2201 hBummer = LoadCursor16(0,IDC_BUMMER);
2203 if( !hBummer || !wndPtr )
2205 GlobalFree16(hDragInfo);
2206 return 0L;
2209 if(hCursor)
2211 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor)) )
2213 GlobalFree16(hDragInfo);
2214 return 0L;
2217 if( hDragCursor == hCursor ) hDragCursor = 0;
2218 else hCursor = hDragCursor;
2220 hOldCursor = SetCursor(hDragCursor);
2223 lpDragInfo->hWnd = hWnd;
2224 lpDragInfo->hScope = 0;
2225 lpDragInfo->wFlags = wObj;
2226 lpDragInfo->hList = szList; /* near pointer! */
2227 lpDragInfo->hOfStruct = hOfStruct;
2228 lpDragInfo->l = 0L;
2230 SetCapture32(hWnd);
2231 ShowCursor(1);
2233 while( !dragDone )
2235 WaitMessage();
2237 if( !PeekMessage16(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) )
2238 continue;
2240 *(lpDragInfo+1) = *lpDragInfo;
2242 lpDragInfo->pt = msg.pt;
2244 /* update DRAGINFO struct */
2245 dprintf_msg(stddeb,"drag: lpDI->hScope = %04x\n",lpDragInfo->hScope);
2247 if( (btemp = (WORD)DRAG_QueryUpdate(hwndScope, spDragInfo)) > 0 )
2248 hCurrentCursor = hCursor;
2249 else
2251 hCurrentCursor = hBummer;
2252 lpDragInfo->hScope = 0;
2254 if( hCurrentCursor )
2255 SetCursor(hCurrentCursor);
2257 dprintf_msg(stddeb,"drag: got %04x\n",btemp);
2259 /* send WM_DRAGLOOP */
2260 SendMessage16( hWnd, WM_DRAGLOOP, (WPARAM)(hCurrentCursor != hBummer) ,
2261 (LPARAM) spDragInfo );
2262 /* send WM_DRAGSELECT or WM_DRAGMOVE */
2263 if( hCurrentWnd != lpDragInfo->hScope )
2265 if( hCurrentWnd )
2266 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 0,
2267 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
2268 HIWORD(spDragInfo)) );
2269 hCurrentWnd = lpDragInfo->hScope;
2270 if( hCurrentWnd )
2271 SendMessage16( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
2273 else
2274 if( hCurrentWnd )
2275 SendMessage16( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
2278 /* check if we're done */
2279 if( msg.message == WM_LBUTTONUP || msg.message == WM_NCLBUTTONUP )
2280 dragDone = TRUE;
2283 ReleaseCapture();
2284 ShowCursor(0);
2286 if( hCursor )
2288 SetCursor(hOldCursor);
2289 if( hDragCursor )
2290 DestroyCursor(hDragCursor);
2293 if( hCurrentCursor != hBummer )
2294 dwRet = SendMessage16( lpDragInfo->hScope, WM_DROPOBJECT,
2295 (WPARAM)hWnd, (LPARAM)spDragInfo );
2296 GlobalFree16(hDragInfo);
2298 return dwRet;