Release 960428
[wine/multimedia.git] / windows / win.c
blobce2b70afbb8cce124702b9073c014db49ccb9827
1 /*
2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
10 #include "options.h"
11 #include "class.h"
12 #include "win.h"
13 #include "user.h"
14 #include "dce.h"
15 #include "sysmetrics.h"
16 #include "cursoricon.h"
17 #include "event.h"
18 #include "nonclient.h"
19 #include "queue.h"
20 #include "winpos.h"
21 #include "color.h"
22 #include "shm_main_blk.h"
23 #include "dde_proc.h"
24 #include "callback.h"
25 #include "stddebug.h"
26 /* #define DEBUG_WIN */
27 /* #define DEBUG_MENU */
28 #include "debug.h"
30 /* Desktop window */
31 static WND *pWndDesktop = NULL;
33 static HWND hwndSysModal = 0;
35 static WORD wDragWidth = 4;
36 static WORD wDragHeight= 3;
38 extern HCURSOR CURSORICON_IconToCursor(HICON);
40 /***********************************************************************
41 * WIN_FindWndPtr
43 * Return a pointer to the WND structure corresponding to a HWND.
45 WND * WIN_FindWndPtr( HWND hwnd )
47 WND * ptr;
49 if (!hwnd) return NULL;
50 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
51 if (ptr->dwMagic != WND_MAGIC) return NULL;
52 if (ptr->hwndSelf != hwnd)
54 fprintf( stderr, "Can't happen: hwnd %04x self pointer is %04x\n",
55 hwnd, ptr->hwndSelf );
56 return NULL;
58 return ptr;
62 /***********************************************************************
63 * WIN_DumpWindow
65 * Dump the content of a window structure to stderr.
67 void WIN_DumpWindow( HWND hwnd )
69 WND *ptr;
70 char className[80];
71 int i;
73 if (!(ptr = WIN_FindWndPtr( hwnd )))
75 fprintf( stderr, "%04x is not a window handle\n", hwnd );
76 return;
79 if (!GetClassName( hwnd, className, sizeof(className ) ))
80 strcpy( className, "#NULL#" );
82 fprintf( stderr, "Window %04x (%p):\n", hwnd, ptr );
83 fprintf( stderr,
84 "next=%p child=%p parent=%p owner=%p class=%p '%s'\n"
85 "inst=%04x taskQ=%04x updRgn=%04x active=%04x hdce=%04x idmenu=%04x\n"
86 "style=%08lx exstyle=%08lx wndproc=%08lx text=%04x '%s'\n"
87 "client=%d,%d-%d,%d window=%d,%d-%d,%d iconpos=%d,%d maxpos=%d,%d\n"
88 "sysmenu=%04x flags=%04x props=%04x vscroll=%04x hscroll=%04x\n",
89 ptr->next, ptr->child, ptr->parent, ptr->owner,
90 ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
91 ptr->hrgnUpdate, ptr->hwndLastActive, ptr->hdce, ptr->wIDmenu,
92 ptr->dwStyle, ptr->dwExStyle, (DWORD)ptr->lpfnWndProc, ptr->hText,
93 ptr->hText ? (char*)USER_HEAP_LIN_ADDR(ptr->hText) : "",
94 ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
95 ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
96 ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x,
97 ptr->ptIconPos.y, ptr->ptMaxPos.x, ptr->ptMaxPos.y, ptr->hSysMenu,
98 ptr->flags, ptr->hProp, ptr->hVScroll, ptr->hHScroll );
100 if (ptr->class->wc.cbWndExtra)
102 fprintf( stderr, "extra bytes:" );
103 for (i = 0; i < ptr->class->wc.cbWndExtra; i++)
104 fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
105 fprintf( stderr, "\n" );
107 fprintf( stderr, "\n" );
111 /***********************************************************************
112 * WIN_WalkWindows
114 * Walk the windows tree and print each window on stderr.
116 void WIN_WalkWindows( HWND hwnd, int indent )
118 WND *ptr;
119 char className[80];
121 ptr = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop;
122 if (!ptr)
124 fprintf( stderr, "*** Invalid window handle\n" );
125 return;
128 if (!indent) /* first time around */
129 fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
130 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
132 while (ptr)
134 fprintf(stderr, "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,"");
136 GlobalGetAtomName( ptr->class->atomName, className, sizeof(className));
138 fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %04x:%04x\n",
139 (DWORD)ptr, ptr->hmemTaskQ, className,
140 (unsigned) ptr->dwStyle,
141 HIWORD(ptr->lpfnWndProc),
142 LOWORD(ptr->lpfnWndProc));
144 if (ptr->child) WIN_WalkWindows( ptr->child->hwndSelf, indent+1 );
145 ptr = ptr->next;
150 /***********************************************************************
151 * WIN_GetXWindow
153 * Return the X window associated to a window.
155 Window WIN_GetXWindow( HWND hwnd )
157 WND *wndPtr = WIN_FindWndPtr( hwnd );
158 while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
159 return wndPtr ? wndPtr->window : 0;
163 /***********************************************************************
164 * WIN_UnlinkWindow
166 * Remove a window from the siblings linked list.
168 BOOL WIN_UnlinkWindow( HWND hwnd )
170 WND *wndPtr, **ppWnd;
172 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
173 ppWnd = &wndPtr->parent->child;
174 while (*ppWnd != wndPtr) ppWnd = &(*ppWnd)->next;
175 *ppWnd = wndPtr->next;
176 return TRUE;
180 /***********************************************************************
181 * WIN_LinkWindow
183 * Insert a window into the siblings linked list.
184 * The window is inserted after the specified window, which can also
185 * be specified as HWND_TOP or HWND_BOTTOM.
187 BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
189 WND *wndPtr, **ppWnd;
191 if (!(wndPtr = WIN_FindWndPtr( hwnd )) || !wndPtr->parent) return FALSE;
193 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
195 ppWnd = &wndPtr->parent->child; /* Point to first sibling hwnd */
196 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
197 while (*ppWnd) ppWnd = &(*ppWnd)->next;
199 else /* Normal case */
201 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
202 if (!afterPtr) return FALSE;
203 ppWnd = &afterPtr->next;
205 wndPtr->next = *ppWnd;
206 *ppWnd = wndPtr;
207 return TRUE;
211 /***********************************************************************
212 * WIN_FindWinToRepaint
214 * Find a window that needs repaint.
216 HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE hQueue )
218 HWND hwndRet;
219 WND *pWnd = pWndDesktop;
221 /* Note: the desktop window never gets WM_PAINT messages */
222 pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
224 for ( ; pWnd ; pWnd = pWnd->next )
226 if (!(pWnd->dwStyle & WS_VISIBLE) || (pWnd->flags & WIN_NO_REDRAW))
228 dprintf_win( stddeb, "FindWinToRepaint: skipping window %04x\n",
229 pWnd->hwndSelf );
230 continue;
232 if ((pWnd->hmemTaskQ == hQueue) &&
233 (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
235 if (pWnd->child )
236 if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
237 return hwndRet;
240 if (!pWnd) return 0;
242 hwndRet = pWnd->hwndSelf;
244 /* look among siblings if we got a transparent window */
245 while (pWnd && ((pWnd->dwExStyle & WS_EX_TRANSPARENT) ||
246 !(pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))))
248 pWnd = pWnd->next;
250 if (pWnd) hwndRet = pWnd->hwndSelf;
251 dprintf_win(stddeb,"FindWinToRepaint: found %04x\n",hwndRet);
252 return hwndRet;
256 /***********************************************************************
257 * WIN_SendParentNotify
259 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
260 * the window has the WS_EX_NOPARENTNOTIFY style.
262 void WIN_SendParentNotify( HWND hwnd, WORD event, WORD idChild, LONG lValue )
264 LPPOINT lppt = (LPPOINT)(void*)(&lValue);
265 WND *wndPtr = WIN_FindWndPtr( hwnd );
266 BOOL bMouse = ((event <= WM_MOUSELAST) && (event >= WM_MOUSEFIRST));
268 /* if lValue contains cursor coordinates they have to be
269 * mapped to the client area of parent window */
271 if (bMouse) MapWindowPoints(0, hwnd, lppt, 1);
272 #ifndef WINELIB32
273 else lValue = MAKELONG( LOWORD(lValue), idChild );
274 #endif
276 while (wndPtr)
278 if ((wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) ||
279 !(wndPtr->dwStyle & WS_CHILD)) break;
281 if (bMouse)
283 lppt->x += wndPtr->rectClient.left;
284 lppt->y += wndPtr->rectClient.top;
287 wndPtr = wndPtr->parent;
288 #ifdef WINELIB32
289 SendMessage( wndPtr->hwndSelf, WM_PARENTNOTIFY,
290 MAKEWPARAM( event, idChild ), lValue );
291 #else
292 SendMessage( wndPtr->hwndSelf, WM_PARENTNOTIFY, event, (LPARAM)lValue);
293 #endif
298 /***********************************************************************
299 * WIN_DestroyWindow
301 * Destroy storage associated to a window
303 static void WIN_DestroyWindow( HWND hwnd )
305 WND *wndPtr = WIN_FindWndPtr( hwnd );
307 #ifdef CONFIG_IPC
308 if (main_block)
309 DDE_DestroyWindow(hwnd);
310 #endif /* CONFIG_IPC */
312 if (!wndPtr) return;
313 WIN_UnlinkWindow( hwnd ); /* Remove the window from the linked list */
314 wndPtr->dwMagic = 0; /* Mark it as invalid */
315 wndPtr->hwndSelf = 0;
316 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
318 if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
319 QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
321 if (!(wndPtr->dwStyle & WS_CHILD))
323 if (wndPtr->wIDmenu) DestroyMenu( (HMENU)wndPtr->wIDmenu );
325 if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
326 if (wndPtr->window) XDestroyWindow( display, wndPtr->window );
327 if (wndPtr->class->wc.style & CS_OWNDC) DCE_FreeDCE( wndPtr->hdce );
328 wndPtr->class->cWindows--;
329 USER_HEAP_FREE( hwnd );
333 /***********************************************************************
334 * WIN_DestroyQueueWindows
336 void WIN_DestroyQueueWindows( WND* wnd, HQUEUE hQueue )
338 WND* next;
340 while (wnd)
342 next = wnd->next;
343 if (wnd->hmemTaskQ == hQueue) DestroyWindow( wnd->hwndSelf );
344 else WIN_DestroyQueueWindows( wnd->child, hQueue );
345 wnd = next;
350 /***********************************************************************
351 * WIN_CreateDesktopWindow
353 * Create the desktop window.
355 BOOL WIN_CreateDesktopWindow(void)
357 CLASS *class;
358 HDC hdc;
359 HWND hwndDesktop;
361 if (!(class = CLASS_FindClassByName( DESKTOP_CLASS_ATOM, 0 )))
362 return FALSE;
364 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->wc.cbWndExtra );
365 if (!hwndDesktop) return FALSE;
366 pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
368 pWndDesktop->next = NULL;
369 pWndDesktop->child = NULL;
370 pWndDesktop->parent = NULL;
371 pWndDesktop->owner = NULL;
372 pWndDesktop->class = class;
373 pWndDesktop->dwMagic = WND_MAGIC;
374 pWndDesktop->hwndSelf = hwndDesktop;
375 pWndDesktop->hInstance = 0;
376 pWndDesktop->rectWindow.left = 0;
377 pWndDesktop->rectWindow.top = 0;
378 pWndDesktop->rectWindow.right = SYSMETRICS_CXSCREEN;
379 pWndDesktop->rectWindow.bottom = SYSMETRICS_CYSCREEN;
380 pWndDesktop->rectClient = pWndDesktop->rectWindow;
381 pWndDesktop->rectNormal = pWndDesktop->rectWindow;
382 pWndDesktop->ptIconPos.x = -1;
383 pWndDesktop->ptIconPos.y = -1;
384 pWndDesktop->ptMaxPos.x = -1;
385 pWndDesktop->ptMaxPos.y = -1;
386 pWndDesktop->hmemTaskQ = 0; /* Desktop does not belong to a task */
387 pWndDesktop->hrgnUpdate = 0;
388 pWndDesktop->hwndLastActive = hwndDesktop;
389 pWndDesktop->lpfnWndProc = class->wc.lpfnWndProc;
390 pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN |
391 WS_CLIPSIBLINGS;
392 pWndDesktop->dwExStyle = 0;
393 pWndDesktop->hdce = 0;
394 pWndDesktop->hVScroll = 0;
395 pWndDesktop->hHScroll = 0;
396 pWndDesktop->wIDmenu = 0;
397 pWndDesktop->hText = 0;
398 pWndDesktop->flags = 0;
399 pWndDesktop->window = rootWindow;
400 pWndDesktop->hSysMenu = 0;
401 pWndDesktop->hProp = 0;
402 EVENT_RegisterWindow( pWndDesktop->window, hwndDesktop );
403 SendMessage( hwndDesktop, WM_NCCREATE, 0, 0 );
404 if ((hdc = GetDC( hwndDesktop )) != 0)
406 SendMessage( hwndDesktop, WM_ERASEBKGND, hdc, 0 );
407 ReleaseDC( hwndDesktop, hdc );
409 return TRUE;
413 /***********************************************************************
414 * CreateWindow (USER.41)
416 HWND CreateWindow( SEGPTR className, SEGPTR windowName,
417 DWORD style, INT x, INT y, INT width, INT height,
418 HWND parent, HMENU menu, HANDLE instance, SEGPTR data )
420 return CreateWindowEx( 0, className, windowName, style,
421 x, y, width, height, parent, menu, instance, data );
425 /***********************************************************************
426 * CreateWindowEx (USER.452)
428 HWND CreateWindowEx( DWORD exStyle, SEGPTR className, SEGPTR windowName,
429 DWORD style, INT x, INT y, INT width, INT height,
430 HWND parent, HMENU menu, HANDLE instance, SEGPTR data )
432 HANDLE hwnd;
433 CLASS *classPtr;
434 WND *wndPtr;
435 POINT maxSize, maxPos, minTrack, maxTrack;
436 CREATESTRUCT createStruct;
437 int wmcreate;
438 XSetWindowAttributes win_attr;
439 Atom XA_WM_DELETE_WINDOW;
441 dprintf_win( stddeb, "CreateWindowEx: " );
442 if (HIWORD(windowName))
443 dprintf_win( stddeb, "'%s' ", (char *)PTR_SEG_TO_LIN(windowName) );
444 else
445 dprintf_win( stddeb, "%04x ", LOWORD(windowName) );
446 if (HIWORD(className))
447 dprintf_win( stddeb, "'%s' ", (char *)PTR_SEG_TO_LIN(className) );
448 else
449 dprintf_win( stddeb, "%04x ", LOWORD(className) );
451 dprintf_win(stddeb, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %08lx\n",
452 exStyle, style, x, y, width, height,
453 parent, menu, instance, (DWORD)data);
455 if (x == CW_USEDEFAULT) x = y = 0;
456 if (width == CW_USEDEFAULT)
458 width = 600;
459 height = 400;
462 /* Find the parent and class */
464 if (parent)
466 /* Make sure parent is valid */
467 if (!IsWindow( parent )) {
468 dprintf_win(stddeb,"CreateWindowEx: Parent %04x is not a window\n", parent);
469 return 0;
472 else
474 if (style & WS_CHILD) {
475 dprintf_win(stddeb,"CreateWindowEx: no parent\n");
476 return 0; /* WS_CHILD needs a parent */
480 if (!(classPtr = CLASS_FindClassByName( className, GetExePtr(instance) )))
482 fprintf(stderr,"CreateWindow BAD CLASSNAME " );
483 if (HIWORD(className)) fprintf( stderr, "'%s'\n",
484 (char *)PTR_SEG_TO_LIN(className) );
485 else fprintf( stderr, "%04x\n", LOWORD(className) );
486 return 0;
489 /* Correct the window style */
491 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
492 style |= WS_CAPTION | WS_CLIPSIBLINGS;
493 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
495 /* Create the window structure */
497 hwnd = USER_HEAP_ALLOC( sizeof(WND)+classPtr->wc.cbWndExtra );
498 if (!hwnd) {
499 dprintf_win(stddeb,"CreateWindowEx: Out of memory\n");
500 return 0;
503 /* Fill the structure */
505 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
506 wndPtr->next = NULL;
507 wndPtr->child = NULL;
508 wndPtr->parent = (style & WS_CHILD) ? WIN_FindWndPtr( parent ) : pWndDesktop;
509 wndPtr->owner = (style & WS_CHILD) ? NULL : WIN_FindWndPtr(WIN_GetTopParent(parent));
510 wndPtr->window = 0;
511 wndPtr->class = classPtr;
512 wndPtr->dwMagic = WND_MAGIC;
513 wndPtr->hwndSelf = hwnd;
514 wndPtr->hInstance = instance;
515 wndPtr->ptIconPos.x = -1;
516 wndPtr->ptIconPos.y = -1;
517 wndPtr->ptMaxPos.x = -1;
518 wndPtr->ptMaxPos.y = -1;
519 wndPtr->hmemTaskQ = GetTaskQueue(0);
520 wndPtr->hrgnUpdate = 0;
521 wndPtr->hwndLastActive = hwnd;
522 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
523 wndPtr->dwStyle = style & ~WS_VISIBLE;
524 wndPtr->dwExStyle = exStyle;
525 wndPtr->wIDmenu = 0;
526 wndPtr->hText = 0;
527 wndPtr->flags = 0;
528 wndPtr->hVScroll = 0;
529 wndPtr->hHScroll = 0;
530 wndPtr->hSysMenu = 0;
531 wndPtr->hProp = 0;
533 if (classPtr->wc.cbWndExtra)
534 memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
535 classPtr->cWindows++;
537 /* Get class or window DC if needed */
539 if (classPtr->wc.style & CS_OWNDC)
540 wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC );
541 else if (classPtr->wc.style & CS_CLASSDC)
542 wndPtr->hdce = classPtr->hdce;
543 else
544 wndPtr->hdce = 0;
546 /* Insert the window in the linked list */
548 WIN_LinkWindow( hwnd, HWND_TOP );
550 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
552 NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
554 if (maxSize.x < width) width = maxSize.x;
555 if (maxSize.y < height) height = maxSize.y;
556 if (width <= 0) width = 1;
557 if (height <= 0) height = 1;
559 wndPtr->rectWindow.left = x;
560 wndPtr->rectWindow.top = y;
561 wndPtr->rectWindow.right = x + width;
562 wndPtr->rectWindow.bottom = y + height;
563 wndPtr->rectClient = wndPtr->rectWindow;
564 wndPtr->rectNormal = wndPtr->rectWindow;
566 /* Create the X window (only for top-level windows, and then only */
567 /* when there's no desktop window) */
569 if (!(style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
571 if (Options.managed && ((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
572 (exStyle & WS_EX_DLGMODALFRAME)))
574 win_attr.event_mask = ExposureMask | KeyPressMask |
575 KeyReleaseMask | PointerMotionMask |
576 ButtonPressMask | ButtonReleaseMask |
577 FocusChangeMask | StructureNotifyMask;
578 win_attr.override_redirect = FALSE;
579 wndPtr->flags |= WIN_MANAGED;
581 else
583 win_attr.event_mask = ExposureMask | KeyPressMask |
584 KeyReleaseMask | PointerMotionMask |
585 ButtonPressMask | ButtonReleaseMask |
586 FocusChangeMask;
587 win_attr.override_redirect = TRUE;
589 win_attr.colormap = COLOR_WinColormap;
590 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
591 win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0);
592 win_attr.cursor = CURSORICON_XCursor;
593 wndPtr->window = XCreateWindow( display, rootWindow, x, y,
594 width, height, 0, CopyFromParent,
595 InputOutput, CopyFromParent,
596 CWEventMask | CWOverrideRedirect |
597 CWColormap | CWCursor | CWSaveUnder |
598 CWBackingStore, &win_attr );
599 XStoreName( display, wndPtr->window, PTR_SEG_TO_LIN(windowName) );
600 XA_WM_DELETE_WINDOW = XInternAtom( display, "WM_DELETE_WINDOW",
601 False );
602 XSetWMProtocols( display, wndPtr->window, &XA_WM_DELETE_WINDOW, 1 );
603 if (parent) /* Get window owner */
605 Window win = WIN_GetXWindow( parent );
606 if (win) XSetTransientForHint( display, wndPtr->window, win );
609 EVENT_RegisterWindow( wndPtr->window, hwnd );
612 if ((style & WS_CAPTION) && !(style & WS_CHILD))
614 if (menu) SetMenu(hwnd, menu);
615 else if (classPtr->wc.lpszMenuName)
616 SetMenu( hwnd, LoadMenu( instance, classPtr->wc.lpszMenuName ) );
618 else wndPtr->wIDmenu = (UINT)menu;
620 GetSystemMenu( hwnd, TRUE ); /* Create a copy of the system menu */
622 /* Send the WM_CREATE message */
624 createStruct.lpCreateParams = (LPSTR)data;
625 createStruct.hInstance = instance;
626 createStruct.hMenu = menu;
627 createStruct.hwndParent = parent;
628 createStruct.cx = width;
629 createStruct.cy = height;
630 createStruct.x = x;
631 createStruct.y = y;
632 createStruct.style = style;
633 createStruct.lpszName = windowName;
634 createStruct.lpszClass = className;
635 createStruct.dwExStyle = 0;
637 wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LPARAM)MAKE_SEGPTR(&createStruct) );
638 if (!wmcreate)
640 dprintf_win(stddeb,"CreateWindowEx: WM_NCCREATE return 0\n");
641 wmcreate = -1;
643 else
645 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
646 NULL, NULL, NULL, &wndPtr->rectClient );
647 wmcreate = SendMessage(hwnd, WM_CREATE, 0, (LPARAM)MAKE_SEGPTR(&createStruct));
650 if (wmcreate == -1)
652 /* Abort window creation */
653 dprintf_win(stddeb,"CreateWindowEx: wmcreate==-1, aborting\n");
654 WIN_DestroyWindow( hwnd );
655 return 0;
658 WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LONG)hwnd );
660 /* Show the window, maximizing or minimizing if needed */
662 if (wndPtr->dwStyle & WS_MINIMIZE)
664 wndPtr->dwStyle &= ~WS_MAXIMIZE;
665 WINPOS_FindIconPos( hwnd );
666 SetWindowPos( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
667 SYSMETRICS_CXICON, SYSMETRICS_CYICON,
668 SWP_FRAMECHANGED |
669 (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
671 else if (wndPtr->dwStyle & WS_MAXIMIZE)
673 SetWindowPos( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
674 SWP_FRAMECHANGED |
675 (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
677 else if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
679 dprintf_win(stddeb, "CreateWindowEx: return %04x\n", hwnd);
680 return hwnd;
684 /***********************************************************************
685 * DestroyWindow (USER.53)
687 BOOL DestroyWindow( HWND hwnd )
689 WND * wndPtr;
691 dprintf_win(stddeb, "DestroyWindow(%04x)\n", hwnd);
693 /* Initialisation */
695 if (hwnd == pWndDesktop->hwndSelf) return FALSE; /* Can't destroy desktop*/
696 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
698 /* Hide the window */
700 if (wndPtr->dwStyle & WS_VISIBLE)
701 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE |
702 SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
703 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
704 ReleaseCapture();
705 WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LONG)hwnd );
707 /* Recursively destroy owned windows */
709 for (;;)
711 WND *siblingPtr = wndPtr->parent->child; /* First sibling */
712 while (siblingPtr)
714 if (siblingPtr->owner == wndPtr) break;
715 siblingPtr = siblingPtr->next;
717 if (siblingPtr) DestroyWindow( siblingPtr->hwndSelf );
718 else break;
721 /* Send destroy messages and destroy children */
723 SendMessage( hwnd, WM_DESTROY, 0, 0 );
724 while (wndPtr->child) /* The child removes itself from the list */
725 DestroyWindow( wndPtr->child->hwndSelf );
726 SendMessage( hwnd, WM_NCDESTROY, 0, 0 );
728 /* Destroy the window */
730 WIN_DestroyWindow( hwnd );
731 return TRUE;
735 /***********************************************************************
736 * CloseWindow (USER.43)
738 BOOL CloseWindow(HWND hWnd)
740 WND * wndPtr = WIN_FindWndPtr(hWnd);
741 if (wndPtr->dwStyle & WS_CHILD) return TRUE;
742 ShowWindow(hWnd, SW_MINIMIZE);
743 return TRUE;
747 /***********************************************************************
748 * OpenIcon (USER.44)
750 BOOL OpenIcon(HWND hWnd)
752 if (!IsIconic(hWnd)) return FALSE;
753 ShowWindow(hWnd, SW_SHOWNORMAL);
754 return(TRUE);
758 /***********************************************************************
759 * FindWindow (USER.50)
761 HWND FindWindow( SEGPTR ClassMatch, LPSTR TitleMatch )
763 WND *wndPtr;
764 CLASS *class = NULL;
766 if (ClassMatch)
768 if (!(class = CLASS_FindClassByName( ClassMatch, (HINSTANCE)0xffff )))
769 return 0;
772 wndPtr = pWndDesktop->child;
773 while (wndPtr)
775 if (!class || (wndPtr->class == class))
777 /* Found matching class */
778 if (!TitleMatch) return wndPtr->hwndSelf;
779 if (wndPtr->hText)
781 char *textPtr = (char *) USER_HEAP_LIN_ADDR( wndPtr->hText );
782 if (!strcmp( textPtr, TitleMatch )) return wndPtr->hwndSelf;
785 wndPtr = wndPtr->next;
787 return 0;
791 /**********************************************************************
792 * WIN_GetDesktop
794 WND *WIN_GetDesktop(void)
796 return pWndDesktop;
800 /**********************************************************************
801 * GetDesktopWindow (USER.286)
803 HWND GetDesktopWindow(void)
805 return pWndDesktop->hwndSelf;
809 /**********************************************************************
810 * GetDesktopHwnd (USER.278)
812 * Exactly the same thing as GetDesktopWindow(), but not documented.
813 * Don't ask me why...
815 HWND GetDesktopHwnd(void)
817 return pWndDesktop->hwndSelf;
821 /*******************************************************************
822 * EnableWindow (USER.34)
824 BOOL EnableWindow( HWND hwnd, BOOL enable )
826 WND *wndPtr;
828 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
829 if (enable && (wndPtr->dwStyle & WS_DISABLED))
831 /* Enable window */
832 wndPtr->dwStyle &= ~WS_DISABLED;
833 SendMessage( hwnd, WM_ENABLE, TRUE, 0 );
834 return TRUE;
836 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
838 /* Disable window */
839 wndPtr->dwStyle |= WS_DISABLED;
840 if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
841 SetFocus( 0 ); /* A disabled window can't have the focus */
842 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
843 ReleaseCapture(); /* A disabled window can't capture the mouse */
844 SendMessage( hwnd, WM_ENABLE, FALSE, 0 );
845 return FALSE;
847 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
851 /***********************************************************************
852 * IsWindowEnabled (USER.35)
854 BOOL IsWindowEnabled(HWND hWnd)
856 WND * wndPtr;
858 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
859 return !(wndPtr->dwStyle & WS_DISABLED);
863 /**********************************************************************
864 * GetWindowWord (USER.133)
866 WORD GetWindowWord( HWND hwnd, short offset )
868 WND * wndPtr = WIN_FindWndPtr( hwnd );
869 if (!wndPtr) return 0;
870 if (offset >= 0) return *(WORD *)(((char *)wndPtr->wExtra) + offset);
871 switch(offset)
873 case GWW_ID: return wndPtr->wIDmenu;
874 #ifdef WINELIB32
875 case GWW_HWNDPARENT:
876 case GWW_HINSTANCE:
877 fprintf(stderr,"GetWindowWord called with offset %d.\n",offset);
878 return 0;
879 #else
880 case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
881 case GWW_HINSTANCE: return (WORD)wndPtr->hInstance;
882 #endif
884 return 0;
888 /**********************************************************************
889 * WIN_GetWindowInstance
891 HINSTANCE WIN_GetWindowInstance(HWND hwnd)
893 WND * wndPtr = WIN_FindWndPtr( hwnd );
894 if (!wndPtr) return (HINSTANCE)0;
895 return wndPtr->hInstance;
899 /**********************************************************************
900 * SetWindowWord (USER.134)
902 WORD SetWindowWord( HWND hwnd, short offset, WORD newval )
904 WORD *ptr, retval;
905 WND * wndPtr = WIN_FindWndPtr( hwnd );
906 if (!wndPtr) return 0;
907 if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
908 else switch(offset)
910 #ifdef WINELIB32
911 case GWW_ID:
912 case GWW_HINSTANCE:
913 fprintf(stderr,"SetWindowWord called with offset %d.\n",offset);
914 return 0;
915 #else
916 case GWW_ID: ptr = &wndPtr->wIDmenu; break;
917 case GWW_HINSTANCE: ptr = (WORD*)&wndPtr->hInstance; break;
918 #endif
919 default: return 0;
921 retval = *ptr;
922 *ptr = newval;
923 return retval;
927 /**********************************************************************
928 * GetWindowLong (USER.135)
930 LONG GetWindowLong( HWND hwnd, short offset )
932 WND * wndPtr = WIN_FindWndPtr( hwnd );
933 if (!wndPtr) return 0;
934 if (offset >= 0) return *(LONG *)(((char *)wndPtr->wExtra) + offset);
935 switch(offset)
937 case GWL_STYLE: return wndPtr->dwStyle;
938 case GWL_EXSTYLE: return wndPtr->dwExStyle;
939 case GWL_WNDPROC: return (LONG)wndPtr->lpfnWndProc;
940 #ifdef WINELIB32
941 case GWW_HWNDPARENT: return wndPtr->parent ? wndPtr->parent->hwndSelf : 0;
942 case GWW_HINSTANCE: return wndPtr->hInstance;
943 #endif
945 return 0;
949 /**********************************************************************
950 * SetWindowLong (USER.136)
952 LONG SetWindowLong( HWND hwnd, short offset, LONG newval )
954 LONG *ptr, retval;
955 WND * wndPtr = WIN_FindWndPtr( hwnd );
956 if (!wndPtr) return 0;
957 if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
958 else switch(offset)
960 case GWL_STYLE: ptr = &wndPtr->dwStyle; break;
961 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
962 case GWL_WNDPROC: ptr = (LONG *)&wndPtr->lpfnWndProc; break;
963 default: return 0;
965 retval = *ptr;
966 *ptr = newval;
967 return retval;
971 /*******************************************************************
972 * GetWindowText (USER.36)
974 int WIN16_GetWindowText( HWND hwnd, SEGPTR lpString, INT nMaxCount )
976 return (int)SendMessage(hwnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString);
979 int GetWindowText( HWND hwnd, LPSTR lpString, int nMaxCount )
981 int len;
982 HANDLE handle;
984 /* We have to allocate a buffer on the USER heap */
985 /* to be able to pass its address to 16-bit code */
986 if (!(handle = USER_HEAP_ALLOC( nMaxCount ))) return 0;
987 len = (int)SendMessage( hwnd, WM_GETTEXT, (WPARAM)nMaxCount,
988 (LPARAM)USER_HEAP_SEG_ADDR(handle) );
989 strncpy( lpString, USER_HEAP_LIN_ADDR(handle), nMaxCount );
990 USER_HEAP_FREE( handle );
991 return len;
995 /*******************************************************************
996 * SetWindowText (USER.37)
998 void WIN16_SetWindowText( HWND hwnd, SEGPTR lpString )
1000 SendMessage( hwnd, WM_SETTEXT, 0, (LPARAM)lpString );
1003 void SetWindowText( HWND hwnd, LPCSTR lpString )
1005 HANDLE handle;
1007 /* We have to allocate a buffer on the USER heap */
1008 /* to be able to pass its address to 16-bit code */
1009 if (!(handle = USER_HEAP_ALLOC( strlen(lpString)+1 ))) return;
1010 strcpy( USER_HEAP_LIN_ADDR(handle), lpString );
1011 SendMessage( hwnd, WM_SETTEXT, 0, (LPARAM)USER_HEAP_SEG_ADDR(handle) );
1012 USER_HEAP_FREE( handle );
1016 /*******************************************************************
1017 * GetWindowTextLength (USER.38)
1019 int GetWindowTextLength(HWND hwnd)
1021 return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0 );
1025 /*******************************************************************
1026 * IsWindow (USER.47)
1028 BOOL IsWindow( HWND hwnd )
1030 WND * wndPtr = WIN_FindWndPtr( hwnd );
1031 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
1035 /*****************************************************************
1036 * GetParent (USER.46)
1038 HWND GetParent(HWND hwnd)
1040 WND *wndPtr = WIN_FindWndPtr(hwnd);
1041 if (!wndPtr) return 0;
1042 wndPtr = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->parent : wndPtr->owner;
1043 return wndPtr ? wndPtr->hwndSelf : 0;
1047 /*****************************************************************
1048 * WIN_GetTopParent
1050 * Get the top-level parent for a child window.
1052 HWND WIN_GetTopParent( HWND hwnd )
1054 WND *wndPtr = WIN_FindWndPtr( hwnd );
1055 while (wndPtr && (wndPtr->dwStyle & WS_CHILD)) wndPtr = wndPtr->parent;
1056 return wndPtr ? wndPtr->hwndSelf : 0;
1060 /*****************************************************************
1061 * SetParent (USER.233)
1063 HWND SetParent(HWND hwndChild, HWND hwndNewParent)
1065 HWND oldParent;
1067 WND *wndPtr = WIN_FindWndPtr(hwndChild);
1068 WND *pWndParent = WIN_FindWndPtr( hwndNewParent );
1069 if (!wndPtr || !pWndParent || !(wndPtr->dwStyle & WS_CHILD)) return 0;
1071 oldParent = wndPtr->parent->hwndSelf;
1073 WIN_UnlinkWindow(hwndChild);
1074 if (hwndNewParent) wndPtr->parent = pWndParent;
1075 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
1077 if (IsWindowVisible(hwndChild)) UpdateWindow(hwndChild);
1079 return oldParent;
1084 /*******************************************************************
1085 * IsChild (USER.48)
1087 BOOL IsChild( HWND parent, HWND child )
1089 WND * wndPtr = WIN_FindWndPtr( child );
1090 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1092 wndPtr = wndPtr->parent;
1093 if (wndPtr->hwndSelf == parent) return TRUE;
1095 return FALSE;
1099 /***********************************************************************
1100 * IsWindowVisible (USER.49)
1102 BOOL IsWindowVisible( HWND hwnd )
1104 WND *wndPtr = WIN_FindWndPtr( hwnd );
1105 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
1107 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
1108 wndPtr = wndPtr->parent;
1110 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
1115 /*******************************************************************
1116 * GetTopWindow (USER.229)
1118 HWND GetTopWindow( HWND hwnd )
1120 WND * wndPtr = WIN_FindWndPtr( hwnd );
1121 if (wndPtr && wndPtr->child) return wndPtr->child->hwndSelf;
1122 else return 0;
1126 /*******************************************************************
1127 * GetWindow (USER.262)
1129 HWND GetWindow( HWND hwnd, WORD rel )
1131 WND * wndPtr = WIN_FindWndPtr( hwnd );
1132 if (!wndPtr) return 0;
1133 switch(rel)
1135 case GW_HWNDFIRST:
1136 if (wndPtr->parent) return wndPtr->parent->child->hwndSelf;
1137 else return 0;
1139 case GW_HWNDLAST:
1140 if (!wndPtr->parent) return 0; /* Desktop window */
1141 while (wndPtr->next) wndPtr = wndPtr->next;
1142 return wndPtr->hwndSelf;
1144 case GW_HWNDNEXT:
1145 if (!wndPtr->next) return 0;
1146 return wndPtr->next->hwndSelf;
1148 case GW_HWNDPREV:
1149 if (!wndPtr->parent) return 0; /* Desktop window */
1150 wndPtr = wndPtr->parent->child; /* First sibling */
1151 if (wndPtr->hwndSelf == hwnd) return 0; /* First in list */
1152 while (wndPtr->next)
1154 if (wndPtr->next->hwndSelf == hwnd) return wndPtr->hwndSelf;
1155 wndPtr = wndPtr->next;
1157 return 0;
1159 case GW_OWNER:
1160 return wndPtr->owner ? wndPtr->owner->hwndSelf : 0;
1162 case GW_CHILD:
1163 return wndPtr->child ? wndPtr->child->hwndSelf : 0;
1165 return 0;
1169 /*******************************************************************
1170 * GetNextWindow (USER.230)
1172 HWND GetNextWindow( HWND hwnd, WORD flag )
1174 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1175 return GetWindow( hwnd, flag );
1178 /*******************************************************************
1179 * ShowOwnedPopups (USER.265)
1181 void ShowOwnedPopups( HWND owner, BOOL fShow )
1183 WND *pWnd = pWndDesktop->child;
1184 while (pWnd)
1186 if (pWnd->owner && (pWnd->owner->hwndSelf == owner) &&
1187 (pWnd->dwStyle & WS_POPUP))
1188 ShowWindow( pWnd->hwndSelf, fShow ? SW_SHOW : SW_HIDE );
1189 pWnd = pWnd->next;
1194 /*******************************************************************
1195 * GetLastActivePopup (USER.287)
1197 HWND GetLastActivePopup(HWND hwnd)
1199 WND *wndPtr;
1200 wndPtr = WIN_FindWndPtr(hwnd);
1201 if (wndPtr == NULL) return hwnd;
1202 return wndPtr->hwndLastActive;
1206 /*******************************************************************
1207 * EnumWindows (USER.54)
1209 BOOL EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam )
1211 WND *wndPtr;
1212 HWND *list, *pWnd;
1213 int count;
1215 /* We have to build a list of all windows first, to avoid */
1216 /* unpleasant side-effects, for instance if the callback */
1217 /* function changes the Z-order of the windows. */
1219 /* First count the windows */
1221 count = 0;
1222 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next) count++;
1223 if (!count) return TRUE;
1225 /* Now build the list of all windows */
1227 if (!(pWnd = list = (HWND *)malloc( sizeof(HWND) * count ))) return FALSE;
1228 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
1229 *pWnd++ = wndPtr->hwndSelf;
1231 /* Now call the callback function for every window */
1233 for (pWnd = list; count > 0; count--, pWnd++)
1235 /* Make sure that window still exists */
1236 if (!IsWindow(*pWnd)) continue;
1237 if (!CallEnumWindowsProc( lpEnumFunc, *pWnd, lParam )) break;
1239 free( list );
1240 return TRUE;
1244 /**********************************************************************
1245 * EnumTaskWindows (USER.225)
1247 BOOL EnumTaskWindows( HTASK hTask, WNDENUMPROC lpEnumFunc, LPARAM lParam )
1249 WND *wndPtr;
1250 HWND *list, *pWnd;
1251 HANDLE hQueue = GetTaskQueue( hTask );
1252 int count;
1254 /* This function is the same as EnumWindows(), */
1255 /* except for an added check on the window queue. */
1257 /* First count the windows */
1259 count = 0;
1260 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
1261 if (wndPtr->hmemTaskQ == hQueue) count++;
1262 if (!count) return TRUE;
1264 /* Now build the list of all windows */
1266 if (!(pWnd = list = (HWND *)malloc( sizeof(HWND) * count ))) return FALSE;
1267 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
1268 if (wndPtr->hmemTaskQ == hQueue) *pWnd++ = wndPtr->hwndSelf;
1270 /* Now call the callback function for every window */
1272 for (pWnd = list; count > 0; count--, pWnd++)
1274 /* Make sure that window still exists */
1275 if (!IsWindow(*pWnd)) continue;
1276 if (!CallEnumTaskWndProc( lpEnumFunc, *pWnd, lParam )) break;
1278 free( list );
1279 return TRUE;
1283 /*******************************************************************
1284 * WIN_EnumChildWin
1286 * o hwnd is the first child to use, loop until all next windows
1287 * are processed
1289 * o call wdnenumprc
1291 * o call ourselves with the next child window
1294 static BOOL WIN_EnumChildWin( WND *wndPtr, FARPROC wndenumprc, LPARAM lParam )
1296 WND *pWndNext, *pWndChild;
1297 while (wndPtr)
1299 pWndNext = wndPtr->next; /* storing hwnd is a way to avoid.. */
1300 pWndChild = wndPtr->child; /* ..side effects after wndenumprc */
1301 if (!CallEnumWindowsProc( wndenumprc, wndPtr->hwndSelf, lParam ))
1302 return 0;
1303 if (pWndChild && IsWindow(pWndChild->hwndSelf))
1304 if (!WIN_EnumChildWin(pWndChild, wndenumprc, lParam)) return 0;
1305 wndPtr = pWndNext;
1307 return 1;
1311 /*******************************************************************
1312 * EnumChildWindows (USER.55)
1314 * o gets the first child of hwnd
1316 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1318 BOOL EnumChildWindows(HWND hwnd, WNDENUMPROC wndenumprc, LPARAM lParam)
1320 WND *wndPtr;
1322 dprintf_enum(stddeb,"EnumChildWindows\n");
1324 if (hwnd == 0) return 0;
1325 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1326 return WIN_EnumChildWin(wndPtr->child, wndenumprc, lParam);
1330 /*******************************************************************
1331 * AnyPopup (USER.52)
1333 BOOL AnyPopup(void)
1335 WND *wndPtr;
1336 for (wndPtr = pWndDesktop->child; wndPtr; wndPtr = wndPtr->next)
1337 if (wndPtr->owner && (wndPtr->dwStyle & WS_VISIBLE)) return TRUE;
1338 return FALSE;
1341 /*******************************************************************
1342 * FlashWindow [USER.105]
1344 BOOL FlashWindow(HWND hWnd, BOOL bInvert)
1346 WND *wndPtr = WIN_FindWndPtr(hWnd);
1348 dprintf_win(stddeb,"FlashWindow: %04x\n", hWnd);
1350 if (!wndPtr) return FALSE;
1352 if (wndPtr->dwStyle & WS_MINIMIZE)
1354 if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
1356 HDC hDC = GetDC(hWnd);
1358 if (!SendMessage( hWnd, WM_ERASEBKGND, (WPARAM)hDC, (LPARAM)0 ))
1359 wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
1361 ReleaseDC( hWnd, hDC );
1362 wndPtr->flags |= WIN_NCACTIVATED;
1364 else
1366 RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
1367 RDW_UPDATENOW | RDW_FRAME );
1368 wndPtr->flags &= ~WIN_NCACTIVATED;
1370 return TRUE;
1372 else
1374 WPARAM wparam;
1375 if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
1376 else wparam = (hWnd == GetActiveWindow());
1378 SendMessage( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
1379 return wparam;
1384 /*******************************************************************
1385 * SetSysModalWindow [USER.188]
1387 HWND SetSysModalWindow(HWND hWnd)
1389 HWND hWndOldModal = hwndSysModal;
1390 hwndSysModal = hWnd;
1391 dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow(%04x) !\n", hWnd);
1392 return hWndOldModal;
1396 /*******************************************************************
1397 * GetSysModalWindow [USER.189]
1399 HWND GetSysModalWindow(void)
1401 return hwndSysModal;
1404 /*******************************************************************
1405 * DRAG_QueryUpdate
1407 * recursively find a child that contains spDragInfo->pt point
1408 * and send WM_QUERYDROPOBJECT
1410 BOOL DRAG_QueryUpdate( HWND hQueryWnd, SEGPTR spDragInfo )
1412 BOOL wParam,bResult = 0;
1413 POINT pt;
1414 LPDRAGINFO ptrDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN(spDragInfo);
1415 WND *ptrQueryWnd = WIN_FindWndPtr(hQueryWnd),*ptrWnd;
1416 RECT tempRect; /* this sucks */
1418 if( !ptrQueryWnd || !ptrDragInfo ) return 0;
1420 pt = ptrDragInfo->pt;
1422 GetWindowRect(hQueryWnd,&tempRect);
1424 if( !PtInRect(&tempRect,pt) ||
1425 (ptrQueryWnd->dwStyle & WS_DISABLED) )
1426 return 0;
1428 if( !(ptrQueryWnd->dwStyle & WS_MINIMIZE) )
1430 tempRect = ptrQueryWnd->rectClient;
1431 if(ptrQueryWnd->dwStyle & WS_CHILD)
1432 MapWindowPoints(ptrQueryWnd->parent->hwndSelf,0,(LPPOINT)&tempRect,2);
1434 if( PtInRect(&tempRect,pt) )
1436 wParam = 0;
1438 for (ptrWnd = ptrQueryWnd->child; ptrWnd ;ptrWnd = ptrWnd->next)
1439 if( ptrWnd->dwStyle & WS_VISIBLE )
1441 GetWindowRect(ptrWnd->hwndSelf,&tempRect);
1443 if( PtInRect(&tempRect,pt) )
1444 break;
1447 if(ptrWnd)
1449 dprintf_msg(stddeb,"DragQueryUpdate: hwnd = %04x, %d %d - %d %d\n",
1450 ptrWnd->hwndSelf, ptrWnd->rectWindow.left, ptrWnd->rectWindow.top,
1451 ptrWnd->rectWindow.right, ptrWnd->rectWindow.bottom );
1452 if( !(ptrWnd->dwStyle & WS_DISABLED) )
1453 bResult = DRAG_QueryUpdate(ptrWnd->hwndSelf, spDragInfo);
1456 if(bResult) return bResult;
1458 else wParam = 1;
1460 else wParam = 1;
1462 ScreenToClient(hQueryWnd,&ptrDragInfo->pt);
1464 ptrDragInfo->hScope = hQueryWnd;
1466 bResult = SendMessage( hQueryWnd ,WM_QUERYDROPOBJECT ,
1467 (WPARAM)wParam ,(LPARAM) spDragInfo );
1468 if( !bResult )
1469 ptrDragInfo->pt = pt;
1471 return bResult;
1474 /*******************************************************************
1475 * DragDetect ( USER.465 )
1478 BOOL DragDetect(HWND hWnd, POINT pt)
1480 MSG msg;
1481 RECT rect;
1483 rect.left = pt.x - wDragWidth;
1484 rect.right = pt.x + wDragWidth;
1486 rect.top = pt.y - wDragHeight;
1487 rect.bottom = pt.y + wDragHeight;
1489 SetCapture(hWnd);
1491 while(1)
1493 while(PeekMessage(&msg ,0 ,WM_MOUSEFIRST ,WM_MOUSELAST ,PM_REMOVE))
1495 if( msg.message == WM_LBUTTONUP )
1497 ReleaseCapture();
1498 return 0;
1500 if( msg.message == WM_MOUSEMOVE )
1502 POINT pt = { LOWORD(msg.lParam), HIWORD(msg.lParam) };
1503 if( !PtInRect( &rect, pt ) )
1505 ReleaseCapture();
1506 return 1;
1510 WaitMessage();
1513 return 0;
1516 /******************************************************************************
1517 * DragObject ( USER.464 )
1520 DWORD DragObject(HWND hwndScope, HWND hWnd, WORD wObj, HANDLE hOfStruct,
1521 WORD szList , HCURSOR hCursor)
1523 MSG msg;
1524 LPDRAGINFO lpDragInfo;
1525 SEGPTR spDragInfo;
1526 HCURSOR hDragCursor=0, hOldCursor=0, hBummer=0;
1527 HANDLE hDragInfo = GlobalAlloc( GMEM_SHARE | GMEM_ZEROINIT, 2*sizeof(DRAGINFO));
1528 WND *wndPtr = WIN_FindWndPtr(hWnd);
1529 DWORD dwRet = 0;
1530 short dragDone = 0;
1531 HCURSOR hCurrentCursor = 0;
1532 HWND hCurrentWnd = 0;
1533 WORD btemp;
1535 lpDragInfo = (LPDRAGINFO) GlobalLock(hDragInfo);
1536 spDragInfo = (SEGPTR) WIN16_GlobalLock(hDragInfo);
1538 if( !lpDragInfo || !spDragInfo ) return 0L;
1540 hBummer = LoadCursor(0,IDC_BUMMER);
1542 if( !hBummer || !wndPtr )
1544 GlobalFree(hDragInfo);
1545 return 0L;
1548 if(hCursor)
1550 if( !(hDragCursor = CURSORICON_IconToCursor(hCursor)) )
1552 GlobalFree(hDragInfo);
1553 return 0L;
1556 if( hDragCursor == hCursor ) hDragCursor = 0;
1557 else hCursor = hDragCursor;
1559 hOldCursor = SetCursor(hDragCursor);
1562 lpDragInfo->hWnd = hWnd;
1563 lpDragInfo->hScope = 0;
1564 lpDragInfo->wFlags = wObj;
1565 lpDragInfo->hList = szList; /* near pointer! */
1566 lpDragInfo->hOfStruct = hOfStruct;
1567 lpDragInfo->l = 0L;
1569 SetCapture(hWnd);
1570 ShowCursor(1);
1572 while( !dragDone )
1574 WaitMessage();
1576 if( !PeekMessage(&msg,0,WM_MOUSEFIRST,WM_MOUSELAST,PM_REMOVE) )
1577 continue;
1579 *(lpDragInfo+1) = *lpDragInfo;
1581 lpDragInfo->pt = msg.pt;
1583 /* update DRAGINFO struct */
1584 dprintf_msg(stddeb,"drag: lpDI->hScope = %04x\n",lpDragInfo->hScope);
1586 if( (btemp = (WORD)DRAG_QueryUpdate(hwndScope, spDragInfo)) > 0 )
1587 hCurrentCursor = hCursor;
1588 else
1590 hCurrentCursor = hBummer;
1591 lpDragInfo->hScope = 0;
1593 if( hCurrentCursor )
1594 SetCursor(hCurrentCursor);
1596 dprintf_msg(stddeb,"drag: got %04x\n",btemp);
1598 /* send WM_DRAGLOOP */
1599 SendMessage( hWnd, WM_DRAGLOOP, (WPARAM)(hCurrentCursor != hBummer) ,
1600 (LPARAM) spDragInfo );
1601 /* send WM_DRAGSELECT or WM_DRAGMOVE */
1602 if( hCurrentWnd != lpDragInfo->hScope )
1604 if( hCurrentWnd )
1605 SendMessage( hCurrentWnd, WM_DRAGSELECT, 0,
1606 (LPARAM)MAKELONG(LOWORD(spDragInfo)+sizeof(DRAGINFO),
1607 HIWORD(spDragInfo)) );
1608 hCurrentWnd = lpDragInfo->hScope;
1609 if( hCurrentWnd )
1610 SendMessage( hCurrentWnd, WM_DRAGSELECT, 1, (LPARAM)spDragInfo);
1612 else
1613 if( hCurrentWnd )
1614 SendMessage( hCurrentWnd, WM_DRAGMOVE, 0, (LPARAM)spDragInfo);
1617 /* check if we're done */
1618 if( msg.message == WM_LBUTTONUP || msg.message == WM_NCLBUTTONUP )
1619 dragDone = TRUE;
1622 ReleaseCapture();
1623 ShowCursor(0);
1625 if( hCursor )
1627 SetCursor(hOldCursor);
1628 if( hDragCursor )
1629 DestroyCursor(hDragCursor);
1632 if( hCurrentCursor != hBummer )
1633 dwRet = SendMessage( lpDragInfo->hScope, WM_DROPOBJECT,
1634 (WPARAM)hWnd, (LPARAM)spDragInfo );
1635 GlobalFree(hDragInfo);
1637 return dwRet;