2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
15 #include "sysmetrics.h"
17 #include "cursoricon.h"
20 #include "nonclient.h"
23 #include "shm_main_blk.h"
27 /* #define DEBUG_WIN */
28 /* #define DEBUG_MENU */
31 static HWND hwndDesktop = 0;
32 static HWND hWndSysModal = 0;
34 /***********************************************************************
37 * Return a pointer to the WND structure corresponding to a HWND.
39 WND * WIN_FindWndPtr( HWND hwnd )
43 if (!hwnd) return NULL;
44 ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
45 if (ptr->dwMagic != WND_MAGIC) return NULL;
50 /***********************************************************************
53 * Return the X window associated to a window.
55 Window WIN_GetXWindow( HWND hwnd )
57 WND *wndPtr = WIN_FindWndPtr( hwnd );
58 while (wndPtr && !wndPtr->window)
60 wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
62 return wndPtr ? wndPtr->window : 0;
66 /***********************************************************************
69 * Remove a window from the siblings linked list.
71 BOOL WIN_UnlinkWindow( HWND hwnd )
74 WND *parentPtr, *wndPtr;
76 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
77 if (!(parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ))) return FALSE;
79 curWndPtr = &parentPtr->hwndChild;
81 while (*curWndPtr != hwnd)
83 WND * curPtr = WIN_FindWndPtr( *curWndPtr );
84 curWndPtr = &curPtr->hwndNext;
86 *curWndPtr = wndPtr->hwndNext;
91 /***********************************************************************
94 * Insert a window into the siblings linked list.
95 * The window is inserted after the specified window, which can also
96 * be specified as HWND_TOP or HWND_BOTTOM.
98 BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
100 HWND * hwndPtr = NULL; /* pointer to hwnd to change */
101 WND *wndPtr, *parentPtr;
103 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
104 if (!(parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ))) return FALSE;
106 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
108 hwndPtr = &parentPtr->hwndChild; /* Point to first sibling hwnd */
109 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
112 WND * nextPtr = WIN_FindWndPtr( *hwndPtr );
113 hwndPtr = &nextPtr->hwndNext;
116 else /* Normal case */
118 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
119 if (afterPtr) hwndPtr = &afterPtr->hwndNext;
121 if (!hwndPtr) return FALSE;
122 wndPtr->hwndNext = *hwndPtr;
128 /***********************************************************************
129 * WIN_FindWinToRepaint
131 * Find a window that needs repaint.
133 HWND WIN_FindWinToRepaint( HWND hwnd )
137 /* Note: the desktop window never gets WM_PAINT messages */
138 if (!hwnd) hwnd = GetTopWindow( hwndDesktop );
139 for ( ; hwnd != 0; hwnd = wndPtr->hwndNext )
141 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
142 dprintf_win( stddeb, "WIN_FindWinToRepaint: "NPFMT", style %08lx\n",
143 hwnd, wndPtr->dwStyle );
144 if (!(wndPtr->dwStyle & WS_VISIBLE) || (wndPtr->flags & WIN_NO_REDRAW))
146 if ((wndPtr->dwStyle & WS_MINIMIZE) && (WIN_CLASS_INFO(wndPtr).hIcon))
148 if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT))
150 if (wndPtr->hwndChild)
153 if ((child = WIN_FindWinToRepaint( wndPtr->hwndChild )))
161 /***********************************************************************
162 * WIN_SendParentNotify
164 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
165 * the window has the WS_EX_NOPARENTNOTIFY style.
167 void WIN_SendParentNotify( HWND hwnd, WORD event, WORD idChild, LONG lValue )
169 WND *wndPtr = WIN_FindWndPtr( hwnd );
171 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
173 if (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) break;
175 SendMessage( wndPtr->hwndParent, WM_PARENTNOTIFY,
176 MAKEWPARAM(event,idChild),
179 SendMessage( wndPtr->hwndParent, WM_PARENTNOTIFY, event,
180 MAKELPARAM(LOWORD(lValue), idChild) );
182 wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
187 /***********************************************************************
190 * Destroy storage associated to a window
192 static void WIN_DestroyWindow( HWND hwnd )
194 WND *wndPtr = WIN_FindWndPtr( hwnd );
195 CLASS *classPtr = CLASS_FindClassPtr( wndPtr->hClass );
199 DDE_DestroyWindow(hwnd);
200 #endif /* CONFIG_IPC */
202 if (!wndPtr || !classPtr) return;
203 WIN_UnlinkWindow( hwnd ); /* Remove the window from the linked list */
204 wndPtr->dwMagic = 0; /* Mark it as invalid */
205 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
207 if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
208 MSG_DecPaintCount( wndPtr->hmemTaskQ );
210 if (!(wndPtr->dwStyle & WS_CHILD))
212 if (wndPtr->wIDmenu) DestroyMenu( wndPtr->wIDmenu );
214 if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
215 if (wndPtr->window) XDestroyWindow( display, wndPtr->window );
216 if (classPtr->wc.style & CS_OWNDC) DCE_FreeDCE( wndPtr->hdce );
217 classPtr->cWindows--;
218 USER_HEAP_FREE( hwnd );
222 /***********************************************************************
223 * WIN_CreateDesktopWindow
225 * Create the desktop window.
227 BOOL WIN_CreateDesktopWindow(void)
234 if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_ATOM, 0, &classPtr )))
237 hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+classPtr->wc.cbWndExtra );
238 if (!hwndDesktop) return FALSE;
239 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
241 wndPtr->hwndNext = 0;
242 wndPtr->hwndChild = 0;
243 wndPtr->dwMagic = WND_MAGIC;
244 wndPtr->hwndParent = 0;
245 wndPtr->hwndOwner = 0;
246 wndPtr->hClass = hclass;
247 wndPtr->hInstance = 0;
248 wndPtr->rectWindow.left = 0;
249 wndPtr->rectWindow.top = 0;
250 wndPtr->rectWindow.right = SYSMETRICS_CXSCREEN;
251 wndPtr->rectWindow.bottom = SYSMETRICS_CYSCREEN;
252 wndPtr->rectClient = wndPtr->rectWindow;
253 wndPtr->rectNormal = wndPtr->rectWindow;
254 wndPtr->ptIconPos.x = -1;
255 wndPtr->ptIconPos.y = -1;
256 wndPtr->ptMaxPos.x = -1;
257 wndPtr->ptMaxPos.y = -1;
258 wndPtr->hmemTaskQ = 0; /* Desktop does not belong to a task */
259 wndPtr->hrgnUpdate = 0;
260 wndPtr->hwndLastActive = hwndDesktop;
261 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
262 wndPtr->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
263 wndPtr->dwExStyle = 0;
265 wndPtr->hVScroll = 0;
266 wndPtr->hHScroll = 0;
270 wndPtr->window = rootWindow;
271 wndPtr->hSysMenu = 0;
273 EVENT_RegisterWindow( wndPtr->window, hwndDesktop );
274 SendMessage( hwndDesktop, WM_NCCREATE, 0, 0 );
275 if ((hdc = GetDC( hwndDesktop )) != 0)
277 SendMessage( hwndDesktop, WM_ERASEBKGND, (WPARAM)hdc, 0 );
278 ReleaseDC( hwndDesktop, hdc );
284 /***********************************************************************
285 * CreateWindow (USER.41)
287 HWND CreateWindow( SEGPTR className, SEGPTR windowName,
288 DWORD style, short x, short y, short width, short height,
289 HWND parent, HMENU menu, HANDLE instance, SEGPTR data )
291 return CreateWindowEx( 0, className, windowName, style,
292 x, y, width, height, parent, menu, instance, data );
296 /***********************************************************************
297 * CreateWindowEx (USER.452)
299 HWND CreateWindowEx( DWORD exStyle, SEGPTR className, SEGPTR windowName,
300 DWORD style, short x, short y, short width, short height,
301 HWND parent, HMENU menu, HANDLE instance, SEGPTR data )
306 POINT maxSize, maxPos, minTrack, maxTrack;
307 CREATESTRUCT createStruct;
309 XSetWindowAttributes win_attr;
311 /* FIXME: windowName and className should be SEGPTRs */
313 dprintf_win( stddeb, "CreateWindowEx: " );
314 if (HIWORD(windowName))
315 dprintf_win( stddeb, "'%s' ", (char *)PTR_SEG_TO_LIN(windowName) );
317 dprintf_win( stddeb, "%04x ", LOWORD(windowName) );
318 if (HIWORD(className))
319 dprintf_win( stddeb, "'%s' ", (char *)PTR_SEG_TO_LIN(className) );
321 dprintf_win( stddeb, "%04x ", LOWORD(className) );
323 dprintf_win(stddeb, "%08lx %08lx %d,%d %dx%d "NPFMT" "NPFMT" "NPFMT" %08lx\n",
324 exStyle, style, x, y, width, height,
325 parent, menu, instance, (DWORD)data);
327 if (x == CW_USEDEFAULT) x = y = 0;
328 if (width == CW_USEDEFAULT)
334 /* Find the parent and class */
338 /* Make sure parent is valid */
339 if (!IsWindow( parent )) {
340 dprintf_win(stddeb,"CreateWindowEx: Parent "NPFMT" is not a window\n", parent);
346 if (style & WS_CHILD) {
347 dprintf_win(stddeb,"CreateWindowEx: no parent\n");
348 return 0; /* WS_CHILD needs a parent */
352 if (!(class = CLASS_FindClassByName( className, GetExePtr(instance),
355 fprintf(stderr,"CreateWindow BAD CLASSNAME " );
356 if (HIWORD(className)) fprintf( stderr, "'%s'\n",
357 (char *)PTR_SEG_TO_LIN(className) );
358 else fprintf( stderr, "%04x\n", LOWORD(className) );
362 /* Correct the window style */
364 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
365 style |= WS_CAPTION | WS_CLIPSIBLINGS;
366 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
368 /* Create the window structure */
370 hwnd = USER_HEAP_ALLOC( sizeof(WND)+classPtr->wc.cbWndExtra );
372 dprintf_win(stddeb,"CreateWindowEx: Out of memory\n");
376 /* Fill the structure */
378 wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
379 wndPtr->hwndNext = 0;
380 wndPtr->hwndChild = 0;
382 wndPtr->dwMagic = WND_MAGIC;
383 wndPtr->hwndParent = (style & WS_CHILD) ? parent : hwndDesktop;
384 wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : WIN_GetTopParent(parent);
385 wndPtr->hClass = class;
386 wndPtr->hInstance = instance;
387 wndPtr->ptIconPos.x = -1;
388 wndPtr->ptIconPos.y = -1;
389 wndPtr->ptMaxPos.x = -1;
390 wndPtr->ptMaxPos.y = -1;
391 wndPtr->hmemTaskQ = GetTaskQueue(0);
392 wndPtr->hrgnUpdate = 0;
393 wndPtr->hwndPrevActive = 0;
394 wndPtr->hwndLastActive = hwnd;
395 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
396 wndPtr->dwStyle = style & ~WS_VISIBLE;
397 wndPtr->dwExStyle = exStyle;
401 wndPtr->hVScroll = 0;
402 wndPtr->hHScroll = 0;
403 wndPtr->hSysMenu = 0;
406 if (classPtr->wc.cbWndExtra)
407 memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
408 classPtr->cWindows++;
410 /* Get class or window DC if needed */
412 if (classPtr->wc.style & CS_OWNDC)
413 wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC );
414 else if (classPtr->wc.style & CS_CLASSDC)
415 wndPtr->hdce = classPtr->hdce;
419 /* Insert the window in the linked list */
421 WIN_LinkWindow( hwnd, HWND_TOP );
423 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
425 NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
427 if (maxSize.x < width) width = maxSize.x;
428 if (maxSize.y < height) height = maxSize.y;
429 if (width <= 0) width = 1;
430 if (height <= 0) height = 1;
432 wndPtr->rectWindow.left = x;
433 wndPtr->rectWindow.top = y;
434 wndPtr->rectWindow.right = x + width;
435 wndPtr->rectWindow.bottom = y + height;
436 wndPtr->rectClient = wndPtr->rectWindow;
437 wndPtr->rectNormal = wndPtr->rectWindow;
439 /* Create the X window (only for top-level windows, and then only */
440 /* when there's no desktop window) */
442 if (!(style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
444 win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
445 PointerMotionMask | ButtonPressMask |
446 ButtonReleaseMask | FocusChangeMask;
447 win_attr.override_redirect = TRUE;
448 win_attr.colormap = COLOR_WinColormap;
449 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
450 win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0);
451 win_attr.cursor = CURSORICON_XCursor;
452 wndPtr->window = XCreateWindow( display, rootWindow, x, y,
453 width, height, 0, CopyFromParent,
454 InputOutput, CopyFromParent,
455 CWEventMask | CWOverrideRedirect |
456 CWColormap | CWCursor | CWSaveUnder |
457 CWBackingStore, &win_attr );
458 XStoreName( display, wndPtr->window, PTR_SEG_TO_LIN(windowName) );
459 EVENT_RegisterWindow( wndPtr->window, hwnd );
462 if ((style & WS_CAPTION) && !(style & WS_CHILD))
464 if (menu) SetMenu(hwnd, menu);
465 else if (classPtr->wc.lpszMenuName)
466 SetMenu( hwnd, LoadMenu( instance, classPtr->wc.lpszMenuName ) );
468 else wndPtr->wIDmenu = menu;
470 /* Send the WM_CREATE message */
472 createStruct.lpCreateParams = (LPSTR)data;
473 createStruct.hInstance = instance;
474 createStruct.hMenu = menu;
475 createStruct.hwndParent = parent;
476 createStruct.cx = width;
477 createStruct.cy = height;
480 createStruct.style = style;
481 createStruct.lpszName = windowName;
482 createStruct.lpszClass = className;
483 createStruct.dwExStyle = 0;
485 wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, MAKE_SEGPTR(&createStruct) );
488 dprintf_win(stddeb,"CreateWindowEx: WM_NCCREATE return 0\n");
493 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
494 NULL, NULL, NULL, &wndPtr->rectClient );
495 wmcreate = SendMessage(hwnd, WM_CREATE, 0, MAKE_SEGPTR(&createStruct));
500 /* Abort window creation */
501 dprintf_win(stddeb,"CreateWindowEx: wmcreate==-1, aborting\n");
502 WIN_DestroyWindow( hwnd );
506 /* Create a copy of SysMenu */
507 if (style & WS_SYSMENU) wndPtr->hSysMenu = CopySysMenu();
509 WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LONG)hwnd );
511 /* Show the window, maximizing or minimizing if needed */
513 if (wndPtr->dwStyle & WS_MINIMIZE)
515 wndPtr->dwStyle &= ~WS_MAXIMIZE;
516 WINPOS_FindIconPos( hwnd );
517 SetWindowPos( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
518 SYSMETRICS_CXICON, SYSMETRICS_CYICON,
520 (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
522 else if (wndPtr->dwStyle & WS_MAXIMIZE)
524 SetWindowPos( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
526 (style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 );
528 else if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
530 dprintf_win(stddeb, "CreateWindowEx: return "NPFMT" \n", hwnd);
535 /***********************************************************************
536 * DestroyWindow (USER.53)
538 BOOL DestroyWindow( HWND hwnd )
543 dprintf_win(stddeb, "DestroyWindow ("NPFMT")\n", hwnd);
547 if (hwnd == hwndDesktop) return FALSE; /* Can't destroy desktop */
548 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
549 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return FALSE;
551 /* Hide the window */
553 if (wndPtr->dwStyle & WS_VISIBLE)
554 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE |
555 SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
556 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
558 WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LONG)hwnd );
560 /* Recursively destroy owned windows */
564 HWND hwndSibling = GetWindow( hwnd, GW_HWNDFIRST );
567 WND *siblingPtr = WIN_FindWndPtr( hwndSibling );
568 if (siblingPtr->hwndOwner == hwnd) break;
569 hwndSibling = siblingPtr->hwndNext;
571 if (hwndSibling) DestroyWindow( hwndSibling );
575 /* Send destroy messages and destroy children */
577 SendMessage( hwnd, WM_DESTROY, 0, 0 );
578 while (wndPtr->hwndChild) /* The child removes itself from the list */
579 DestroyWindow( wndPtr->hwndChild );
580 SendMessage( hwnd, WM_NCDESTROY, 0, 0 );
582 /* Destroy the window */
584 WIN_DestroyWindow( hwnd );
589 /***********************************************************************
590 * CloseWindow (USER.43)
592 void CloseWindow(HWND hWnd)
594 WND * wndPtr = WIN_FindWndPtr(hWnd);
595 if (wndPtr->dwStyle & WS_CHILD) return;
596 ShowWindow(hWnd, SW_MINIMIZE);
600 /***********************************************************************
603 BOOL OpenIcon(HWND hWnd)
605 if (!IsIconic(hWnd)) return FALSE;
606 ShowWindow(hWnd, SW_SHOWNORMAL);
611 /***********************************************************************
612 * FindWindow (USER.50)
614 HWND FindWindow( SEGPTR ClassMatch, LPSTR TitleMatch )
622 hclass = CLASS_FindClassByName( ClassMatch, (HINSTANCE)0xffff,
624 if (!hclass) return 0;
628 hwnd = GetTopWindow( hwndDesktop );
631 WND *wndPtr = WIN_FindWndPtr( hwnd );
632 if (!hclass || (wndPtr->hClass == hclass))
634 /* Found matching class */
635 if (!TitleMatch) return hwnd;
638 char *textPtr = (char *) USER_HEAP_LIN_ADDR( wndPtr->hText );
639 if (!strcmp( textPtr, TitleMatch )) return hwnd;
642 hwnd = wndPtr->hwndNext;
648 /**********************************************************************
649 * GetDesktopWindow (USER.286)
650 * GetDeskTopHwnd (USER.278)
652 HWND GetDesktopWindow(void)
658 /*******************************************************************
659 * EnableWindow (USER.34)
661 BOOL EnableWindow( HWND hwnd, BOOL enable )
665 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
666 if (enable && (wndPtr->dwStyle & WS_DISABLED))
669 wndPtr->dwStyle &= ~WS_DISABLED;
670 SendMessage( hwnd, WM_ENABLE, TRUE, 0 );
673 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
676 wndPtr->dwStyle |= WS_DISABLED;
677 if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
678 SetFocus( 0 ); /* A disabled window can't have the focus */
679 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
680 ReleaseCapture(); /* A disabled window can't capture the mouse */
681 SendMessage( hwnd, WM_ENABLE, FALSE, 0 );
684 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
688 /***********************************************************************
689 * IsWindowEnabled (USER.35)
691 BOOL IsWindowEnabled(HWND hWnd)
695 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
696 return !(wndPtr->dwStyle & WS_DISABLED);
700 /**********************************************************************
701 * GetWindowWord (USER.133)
703 WORD GetWindowWord( HWND hwnd, short offset )
705 WND * wndPtr = WIN_FindWndPtr( hwnd );
706 if (!wndPtr) return 0;
707 if (offset >= 0) return *(WORD *)(((char *)wndPtr->wExtra) + offset);
710 case GWW_ID: return wndPtr->wIDmenu;
714 fprintf(stderr,"GetWindowWord called with offset %d.\n",offset);
717 case GWW_HWNDPARENT: return (WORD)wndPtr->hwndParent;
718 case GWW_HINSTANCE: return (WORD)wndPtr->hInstance;
725 /**********************************************************************
726 * WIN_GetWindowInstance
728 HINSTANCE WIN_GetWindowInstance(HWND hwnd)
730 WND * wndPtr = WIN_FindWndPtr( hwnd );
731 if (!wndPtr) return (HINSTANCE)0;
732 return wndPtr->hInstance;
736 /**********************************************************************
737 * SetWindowWord (USER.134)
739 WORD SetWindowWord( HWND hwnd, short offset, WORD newval )
742 WND * wndPtr = WIN_FindWndPtr( hwnd );
743 if (!wndPtr) return 0;
744 if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
747 case GWW_ID: ptr = &wndPtr->wIDmenu; break;
750 fprintf(stderr,"SetWindowWord called with offset %d.\n",offset);
753 case GWW_HINSTANCE: ptr = (WORD*)&wndPtr->hInstance; break;
763 /**********************************************************************
764 * GetWindowLong (USER.135)
766 LONG GetWindowLong( HWND hwnd, short offset )
768 WND * wndPtr = WIN_FindWndPtr( hwnd );
769 if (!wndPtr) return 0;
770 if (offset >= 0) return *(LONG *)(((char *)wndPtr->wExtra) + offset);
773 case GWL_STYLE: return wndPtr->dwStyle;
774 case GWL_EXSTYLE: return wndPtr->dwExStyle;
775 case GWL_WNDPROC: return (LONG)wndPtr->lpfnWndProc;
777 case GWW_HWNDPARENT: return (LONG)wndPtr->hwndParent;
778 case GWW_HINSTANCE: return (LONG)wndPtr->hInstance;
785 /**********************************************************************
786 * SetWindowLong (USER.136)
788 LONG SetWindowLong( HWND hwnd, short offset, LONG newval )
791 WND * wndPtr = WIN_FindWndPtr( hwnd );
792 if (!wndPtr) return 0;
793 if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
796 case GWL_STYLE: ptr = &wndPtr->dwStyle; break;
797 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle; break;
798 case GWL_WNDPROC: ptr = (LONG *)&wndPtr->lpfnWndProc; break;
807 /*******************************************************************
808 * GetWindowText (USER.36)
810 int WIN16_GetWindowText( HWND hwnd, SEGPTR lpString, int nMaxCount )
812 return (int)SendMessage(hwnd, WM_GETTEXT, (WORD)nMaxCount,
816 int GetWindowText( HWND hwnd, LPSTR lpString, int nMaxCount )
821 /* We have to allocate a buffer on the USER heap */
822 /* to be able to pass its address to 16-bit code */
823 if (!(handle = USER_HEAP_ALLOC( nMaxCount ))) return 0;
824 len = (int)SendMessage( hwnd, WM_GETTEXT, (WPARAM)nMaxCount,
825 (LPARAM)USER_HEAP_SEG_ADDR(handle) );
826 strncpy( lpString, USER_HEAP_LIN_ADDR(handle), nMaxCount );
827 USER_HEAP_FREE( handle );
832 /*******************************************************************
833 * SetWindowText (USER.37)
835 void WIN16_SetWindowText( HWND hwnd, SEGPTR lpString )
837 SendMessage( hwnd, WM_SETTEXT, 0, (DWORD)lpString );
840 void SetWindowText( HWND hwnd, LPSTR lpString )
844 /* We have to allocate a buffer on the USER heap */
845 /* to be able to pass its address to 16-bit code */
846 if (!(handle = USER_HEAP_ALLOC( strlen(lpString)+1 ))) return;
847 strcpy( USER_HEAP_LIN_ADDR(handle), lpString );
848 SendMessage( hwnd, WM_SETTEXT, 0, (LPARAM)USER_HEAP_SEG_ADDR(handle) );
849 USER_HEAP_FREE( handle );
853 /*******************************************************************
854 * GetWindowTextLength (USER.38)
856 int GetWindowTextLength(HWND hwnd)
858 return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0 );
862 /*******************************************************************
865 BOOL IsWindow( HWND hwnd )
867 WND * wndPtr = WIN_FindWndPtr( hwnd );
868 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
872 /*****************************************************************
873 * GetParent (USER.46)
875 HWND GetParent(HWND hwnd)
877 WND *wndPtr = WIN_FindWndPtr(hwnd);
878 if (!wndPtr) return 0;
879 return (wndPtr->dwStyle & WS_CHILD) ?
880 wndPtr->hwndParent : wndPtr->hwndOwner;
884 /*****************************************************************
887 * Get the top-level parent for a child window.
889 HWND WIN_GetTopParent( HWND hwnd )
893 WND *wndPtr = WIN_FindWndPtr( hwnd );
894 if (wndPtr->dwStyle & WS_CHILD) hwnd = wndPtr->hwndParent;
901 /*****************************************************************
902 * SetParent (USER.233)
904 HWND SetParent(HWND hwndChild, HWND hwndNewParent)
908 WND *wndPtr = WIN_FindWndPtr(hwndChild);
909 if (!wndPtr || !(wndPtr->dwStyle & WS_CHILD)) return 0;
911 temp = wndPtr->hwndParent;
913 WIN_UnlinkWindow(hwndChild);
915 wndPtr->hwndParent = hwndNewParent;
917 wndPtr->hwndParent = GetDesktopWindow();
918 WIN_LinkWindow(hwndChild, HWND_BOTTOM);
920 if (IsWindowVisible(hwndChild)) UpdateWindow(hwndChild);
927 /*******************************************************************
930 BOOL IsChild( HWND parent, HWND child )
932 WND * wndPtr = WIN_FindWndPtr( child );
933 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
935 if (wndPtr->hwndParent == parent) return TRUE;
936 wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
942 /***********************************************************************
943 * IsWindowVisible (USER.49)
945 BOOL IsWindowVisible( HWND hwnd )
947 WND *wndPtr = WIN_FindWndPtr( hwnd );
948 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
950 if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
951 wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
953 return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
958 /*******************************************************************
959 * GetTopWindow (USER.229)
961 HWND GetTopWindow( HWND hwnd )
963 WND * wndPtr = WIN_FindWndPtr( hwnd );
964 if (wndPtr) return wndPtr->hwndChild;
969 /*******************************************************************
970 * GetWindow (USER.262)
972 HWND GetWindow( HWND hwnd, WORD rel )
974 WND * wndPtr = WIN_FindWndPtr( hwnd );
975 if (!wndPtr) return 0;
979 if (wndPtr->hwndParent)
981 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
982 return parentPtr->hwndChild;
987 if (!wndPtr->hwndParent) return 0; /* Desktop window */
988 while (wndPtr->hwndNext)
990 hwnd = wndPtr->hwndNext;
991 wndPtr = WIN_FindWndPtr( hwnd );
996 return wndPtr->hwndNext;
1002 if (wndPtr->hwndParent)
1004 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
1005 hwndPrev = parentPtr->hwndChild;
1007 else return 0; /* Desktop window */
1008 if (hwndPrev == hwnd) return 0;
1011 wndPtr = WIN_FindWndPtr( hwndPrev );
1012 if (wndPtr->hwndNext == hwnd) break;
1013 hwndPrev = wndPtr->hwndNext;
1019 return wndPtr->hwndOwner;
1022 return wndPtr->hwndChild;
1028 /*******************************************************************
1029 * GetNextWindow (USER.230)
1031 HWND GetNextWindow( HWND hwnd, WORD flag )
1033 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
1034 return GetWindow( hwnd, flag );
1037 /*******************************************************************
1038 * ShowOwnedPopups (USER.265)
1040 void ShowOwnedPopups( HWND owner, BOOL fShow )
1042 HWND hwnd = GetWindow( hwndDesktop, GW_CHILD );
1045 WND *wnd = WIN_FindWndPtr(hwnd);
1046 if (wnd->hwndOwner == owner && (wnd->dwStyle & WS_POPUP))
1047 ShowWindow( hwnd, fShow ? SW_SHOW : SW_HIDE );
1048 hwnd = wnd->hwndNext;
1053 /*******************************************************************
1054 * GetLastActivePopup (USER.287)
1056 HWND GetLastActivePopup(HWND hwnd)
1059 wndPtr = WIN_FindWndPtr(hwnd);
1060 if (wndPtr == NULL) return hwnd;
1061 return wndPtr->hwndLastActive;
1065 /*******************************************************************
1066 * EnumWindows (USER.54)
1068 BOOL EnumWindows( FARPROC lpEnumFunc, LPARAM lParam )
1075 /* We have to build a list of all windows first, to avoid */
1076 /* unpleasant side-effects, for instance if the callback */
1077 /* function changes the Z-order of the windows. */
1079 /* First count the windows */
1082 for (hwnd = GetTopWindow(hwndDesktop); hwnd != 0; hwnd = wndPtr->hwndNext)
1084 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1087 if (!count) return TRUE;
1089 /* Now build the list of all windows */
1091 if (!(list = (HWND *)malloc( sizeof(HWND) * count ))) return FALSE;
1092 for (hwnd = GetTopWindow(hwndDesktop), pWnd = list; hwnd != 0; hwnd = wndPtr->hwndNext)
1094 wndPtr = WIN_FindWndPtr( hwnd );
1098 /* Now call the callback function for every window */
1100 for (pWnd = list; count > 0; count--, pWnd++)
1102 /* Make sure that window still exists */
1103 if (!IsWindow(*pWnd)) continue;
1104 if (!CallEnumWindowsProc( lpEnumFunc, *pWnd, lParam )) break;
1111 /**********************************************************************
1112 * EnumTaskWindows (USER.225)
1114 BOOL EnumTaskWindows( HTASK hTask, FARPROC lpEnumFunc, LONG lParam )
1119 HANDLE hQueue = GetTaskQueue( hTask );
1122 /* This function is the same as EnumWindows(), */
1123 /* except for an added check on the window queue. */
1125 /* First count the windows */
1128 for (hwnd = GetTopWindow(hwndDesktop); hwnd != 0; hwnd = wndPtr->hwndNext)
1130 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
1131 if (wndPtr->hmemTaskQ == hQueue) count++;
1133 if (!count) return TRUE;
1135 /* Now build the list of all windows */
1137 if (!(list = (HWND *)malloc( sizeof(HWND) * count ))) return FALSE;
1138 for (hwnd = GetTopWindow(hwndDesktop), pWnd = list; hwnd != 0; hwnd = wndPtr->hwndNext)
1140 wndPtr = WIN_FindWndPtr( hwnd );
1141 if (wndPtr->hmemTaskQ == hQueue) *pWnd++ = hwnd;
1144 /* Now call the callback function for every window */
1146 for (pWnd = list; count > 0; count--, pWnd++)
1148 /* Make sure that window still exists */
1149 if (!IsWindow(*pWnd)) continue;
1150 if (!CallEnumTaskWndProc( lpEnumFunc, *pWnd, lParam )) break;
1157 /*******************************************************************
1160 * o hwnd is the first child to use, loop until all next windows
1165 * o call ourselves with the next child window
1168 static BOOL WIN_EnumChildWin(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
1174 if (!(wndPtr=WIN_FindWndPtr(hwnd))) return 0;
1175 if (!CallEnumWindowsProc( wndenumprc, hwnd, lParam )) return 0;
1176 if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) return 0;
1177 hwnd=wndPtr->hwndNext;
1182 /*******************************************************************
1183 * EnumChildWindows (USER.55)
1185 * o gets the first child of hwnd
1187 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1189 BOOL EnumChildWindows(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
1193 dprintf_enum(stddeb,"EnumChildWindows\n");
1195 if (hwnd == 0) return 0;
1196 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1197 hwnd = wndPtr->hwndChild;
1198 return WIN_EnumChildWin(hwnd, wndenumprc, lParam);
1202 /*******************************************************************
1203 * AnyPopup [USER.52]
1207 dprintf_win(stdnimp,"EMPTY STUB !! AnyPopup !\n");
1211 /*******************************************************************
1212 * FlashWindow [USER.105]
1214 BOOL FlashWindow(HWND hWnd, BOOL bInvert)
1216 dprintf_win(stdnimp,"EMPTY STUB !! FlashWindow !\n");
1221 /*******************************************************************
1222 * SetSysModalWindow [USER.188]
1224 HWND SetSysModalWindow(HWND hWnd)
1226 HWND hWndOldModal = hWndSysModal;
1227 hWndSysModal = hWnd;
1228 dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow("NPFMT") !\n", hWnd);
1229 return hWndOldModal;
1233 /*******************************************************************
1234 * GetSysModalWindow [USER.189]
1236 HWND GetSysModalWindow(void)
1238 return hWndSysModal;