2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
15 #include "sysmetrics.h"
21 #include "nonclient.h"
26 /* #define DEBUG_WIN */
27 /* #define DEBUG_MENU */
30 static HWND hwndDesktop
= 0;
31 static HWND hWndSysModal
= 0;
33 /***********************************************************************
36 * Return a pointer to the WND structure corresponding to a HWND.
38 WND
* WIN_FindWndPtr( HWND hwnd
)
42 if (!hwnd
) return NULL
;
43 ptr
= (WND
*) USER_HEAP_LIN_ADDR( hwnd
);
44 if (ptr
->dwMagic
!= WND_MAGIC
) return NULL
;
49 /***********************************************************************
52 * Return the X window associated to a window.
54 Window
WIN_GetXWindow( HWND hwnd
)
56 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
57 while (wndPtr
&& !wndPtr
->window
)
59 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
61 return wndPtr
? wndPtr
->window
: 0;
65 /***********************************************************************
68 * Remove a window from the siblings linked list.
70 BOOL
WIN_UnlinkWindow( HWND hwnd
)
73 WND
*parentPtr
, *wndPtr
;
75 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
76 if (!(parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
))) return FALSE
;
78 curWndPtr
= &parentPtr
->hwndChild
;
80 while (*curWndPtr
!= hwnd
)
82 WND
* curPtr
= WIN_FindWndPtr( *curWndPtr
);
83 curWndPtr
= &curPtr
->hwndNext
;
85 *curWndPtr
= wndPtr
->hwndNext
;
90 /***********************************************************************
93 * Insert a window into the siblings linked list.
94 * The window is inserted after the specified window, which can also
95 * be specified as HWND_TOP or HWND_BOTTOM.
97 BOOL
WIN_LinkWindow( HWND hwnd
, HWND hwndInsertAfter
)
99 HWND
* hwndPtr
= NULL
; /* pointer to hwnd to change */
100 WND
*wndPtr
, *parentPtr
;
102 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
103 if (!(parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
))) return FALSE
;
105 if ((hwndInsertAfter
== HWND_TOP
) || (hwndInsertAfter
== HWND_BOTTOM
))
107 hwndPtr
= &parentPtr
->hwndChild
; /* Point to first sibling hwnd */
108 if (hwndInsertAfter
== HWND_BOTTOM
) /* Find last sibling hwnd */
111 WND
* nextPtr
= WIN_FindWndPtr( *hwndPtr
);
112 hwndPtr
= &nextPtr
->hwndNext
;
115 else /* Normal case */
117 WND
* afterPtr
= WIN_FindWndPtr( hwndInsertAfter
);
118 if (afterPtr
) hwndPtr
= &afterPtr
->hwndNext
;
120 if (!hwndPtr
) return FALSE
;
121 wndPtr
->hwndNext
= *hwndPtr
;
127 /***********************************************************************
128 * WIN_FindWinToRepaint
130 * Find a window that needs repaint.
132 HWND
WIN_FindWinToRepaint( HWND hwnd
)
136 /* Note: the desktop window never gets WM_PAINT messages */
137 if (!hwnd
) hwnd
= GetTopWindow( hwndDesktop
);
138 for ( ; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
140 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
141 if (!(wndPtr
->dwStyle
& WS_VISIBLE
) || (wndPtr
->flags
& WIN_NO_REDRAW
))
143 if ((wndPtr
->dwStyle
& WS_MINIMIZE
) && (WIN_CLASS_INFO(wndPtr
).hIcon
))
145 if (wndPtr
->hrgnUpdate
|| (wndPtr
->flags
& WIN_INTERNAL_PAINT
))
147 if (wndPtr
->hwndChild
)
150 if ((child
= WIN_FindWinToRepaint( wndPtr
->hwndChild
)))
158 /***********************************************************************
159 * WIN_SendParentNotify
161 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
162 * the window has the WS_EX_NOPARENTNOTIFY style.
164 void WIN_SendParentNotify( HWND hwnd
, WORD event
, LONG lParam
)
166 HWND current
= GetParent( hwnd
);
167 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
169 if (!wndPtr
|| (wndPtr
->dwExStyle
& WS_EX_NOPARENTNOTIFY
)) return;
172 SendMessage( current
, WM_PARENTNOTIFY
, event
, lParam
);
173 current
= GetParent( current
);
178 /***********************************************************************
181 * Destroy storage associated to a window
183 static void WIN_DestroyWindow( HWND hwnd
)
185 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
186 CLASS
*classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
);
188 if (!wndPtr
|| !classPtr
) return;
189 WIN_UnlinkWindow( hwnd
); /* Remove the window from the linked list */
190 wndPtr
->dwMagic
= 0; /* Mark it as invalid */
191 if ((wndPtr
->hrgnUpdate
) || (wndPtr
->flags
& WIN_INTERNAL_PAINT
))
193 if (wndPtr
->hrgnUpdate
) DeleteObject( wndPtr
->hrgnUpdate
);
194 MSG_DecPaintCount( wndPtr
->hmemTaskQ
);
196 if (!(wndPtr
->dwStyle
& WS_CHILD
))
198 if (wndPtr
->wIDmenu
) DestroyMenu( wndPtr
->wIDmenu
);
200 if (wndPtr
->hSysMenu
) DestroyMenu( wndPtr
->hSysMenu
);
201 if (wndPtr
->window
) XDestroyWindow( display
, wndPtr
->window
);
202 if (classPtr
->wc
.style
& CS_OWNDC
) DCE_FreeDCE( wndPtr
->hdce
);
203 classPtr
->cWindows
--;
204 USER_HEAP_FREE( hwnd
);
208 /***********************************************************************
209 * WIN_CreateDesktopWindow
211 * Create the desktop window.
213 BOOL
WIN_CreateDesktopWindow(void)
220 if (!(hclass
= CLASS_FindClassByName( DESKTOP_CLASS_NAME
, 0, &classPtr
)))
223 hwndDesktop
= USER_HEAP_ALLOC( sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
224 if (!hwndDesktop
) return FALSE
;
225 wndPtr
= (WND
*) USER_HEAP_LIN_ADDR( hwndDesktop
);
227 wndPtr
->hwndNext
= 0;
228 wndPtr
->hwndChild
= 0;
229 wndPtr
->dwMagic
= WND_MAGIC
;
230 wndPtr
->hwndParent
= 0;
231 wndPtr
->hwndOwner
= 0;
232 wndPtr
->hClass
= hclass
;
233 wndPtr
->hInstance
= 0;
234 wndPtr
->rectWindow
.left
= 0;
235 wndPtr
->rectWindow
.top
= 0;
236 wndPtr
->rectWindow
.right
= SYSMETRICS_CXSCREEN
;
237 wndPtr
->rectWindow
.bottom
= SYSMETRICS_CYSCREEN
;
238 wndPtr
->rectClient
= wndPtr
->rectWindow
;
239 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
240 wndPtr
->ptIconPos
.x
= -1;
241 wndPtr
->ptIconPos
.y
= -1;
242 wndPtr
->ptMaxPos
.x
= -1;
243 wndPtr
->ptMaxPos
.y
= -1;
244 wndPtr
->hmemTaskQ
= 0; /* Desktop does not belong to a task */
245 wndPtr
->hrgnUpdate
= 0;
246 wndPtr
->hwndLastActive
= hwndDesktop
;
247 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
248 wndPtr
->dwStyle
= WS_VISIBLE
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
;
249 wndPtr
->dwExStyle
= 0;
251 wndPtr
->hVScroll
= 0;
252 wndPtr
->hHScroll
= 0;
256 wndPtr
->window
= rootWindow
;
257 wndPtr
->hSysMenu
= 0;
259 EVENT_RegisterWindow( wndPtr
->window
, hwndDesktop
);
260 SendMessage( hwndDesktop
, WM_NCCREATE
, 0, 0 );
261 if ((hdc
= GetDC( hwndDesktop
)) != 0)
263 SendMessage( hwndDesktop
, WM_ERASEBKGND
, hdc
, 0 );
264 ReleaseDC( hwndDesktop
, hdc
);
270 /***********************************************************************
271 * CreateWindow (USER.41)
273 HWND
CreateWindow( LPSTR className
, LPSTR windowName
,
274 DWORD style
, short x
, short y
, short width
, short height
,
275 HWND parent
, HMENU menu
, HANDLE instance
, SEGPTR data
)
277 return CreateWindowEx( 0, className
, windowName
, style
,
278 x
, y
, width
, height
, parent
, menu
, instance
, data
);
282 /***********************************************************************
283 * CreateWindowEx (USER.452)
285 HWND
CreateWindowEx( DWORD exStyle
, LPSTR className
, LPSTR windowName
,
286 DWORD style
, short x
, short y
, short width
, short height
,
287 HWND parent
, HMENU menu
, HANDLE instance
, SEGPTR data
)
292 POINT maxSize
, maxPos
, minTrack
, maxTrack
;
293 CREATESTRUCT createStruct
;
294 HANDLE hwinName
, hclassName
;
296 XSetWindowAttributes win_attr
;
298 dprintf_win(stddeb
, "CreateWindowEx: %08lX '%s' '%s' %08lX %d,%d %dx%d %04X %04X %04X %08lx\n",
299 exStyle
, className
, windowName
, style
, x
, y
, width
, height
,
300 parent
, menu
, instance
, data
);
301 /* 'soundrec.exe' has negative position !
302 Why ? For now, here a patch : */
303 if (!strcmp(className
, "SoundRec"))
308 if (x
== CW_USEDEFAULT
) x
= y
= 0;
309 if (width
== CW_USEDEFAULT
)
314 if (width
== 0) width
= 1;
315 if (height
== 0) height
= 1;
317 /* Find the parent and class */
321 /* Make sure parent is valid */
322 if (!IsWindow( parent
)) {
323 dprintf_win(stddeb
,"CreateWindowEx: Parent %x is not a windows\n", parent
);
327 else if (style
& WS_CHILD
) {
328 dprintf_win(stddeb
,"CreateWindowEx: no parent\n");
329 return 0; /* WS_CHILD needs a parent */
332 if (!(class = CLASS_FindClassByName( className
, instance
, &classPtr
))) {
333 fprintf(stderr
,"CreateWindow BAD CLASSNAME '%s' !\n", className
);
337 /* Correct the window style */
339 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
340 style
|= WS_CAPTION
| WS_CLIPSIBLINGS
;
341 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
343 /* Create the window structure */
345 hwnd
= USER_HEAP_ALLOC( sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
347 dprintf_win(stddeb
,"CreateWindowEx: Out of memory\n");
351 /* Fill the structure */
353 wndPtr
= (WND
*) USER_HEAP_LIN_ADDR( hwnd
);
354 wndPtr
->hwndNext
= 0;
355 wndPtr
->hwndChild
= 0;
357 wndPtr
->dwMagic
= WND_MAGIC
;
358 wndPtr
->hwndParent
= (style
& WS_CHILD
) ? parent
: hwndDesktop
;
359 wndPtr
->hwndOwner
= (style
& WS_CHILD
) ? 0 : parent
;
360 wndPtr
->hClass
= class;
361 wndPtr
->hInstance
= instance
;
362 wndPtr
->rectWindow
.left
= x
;
363 wndPtr
->rectWindow
.top
= y
;
364 wndPtr
->rectWindow
.right
= x
+ width
;
365 wndPtr
->rectWindow
.bottom
= y
+ height
;
366 wndPtr
->rectClient
= wndPtr
->rectWindow
;
367 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
368 wndPtr
->ptIconPos
.x
= -1;
369 wndPtr
->ptIconPos
.y
= -1;
370 wndPtr
->ptMaxPos
.x
= -1;
371 wndPtr
->ptMaxPos
.y
= -1;
372 wndPtr
->hmemTaskQ
= GetTaskQueue(0);
373 wndPtr
->hrgnUpdate
= 0;
374 wndPtr
->hwndPrevActive
= 0;
375 wndPtr
->hwndLastActive
= hwnd
;
376 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
377 wndPtr
->dwStyle
= style
;
378 wndPtr
->dwExStyle
= exStyle
;
382 wndPtr
->hVScroll
= 0;
383 wndPtr
->hHScroll
= 0;
384 wndPtr
->hSysMenu
= 0;
387 if (classPtr
->wc
.cbWndExtra
)
388 memset( wndPtr
->wExtra
, 0, classPtr
->wc
.cbWndExtra
);
389 classPtr
->cWindows
++;
391 /* Make sure owner is a top-level window */
393 while (wndPtr
->hwndOwner
&& GetParent(wndPtr
->hwndOwner
))
394 wndPtr
->hwndOwner
= GetParent(wndPtr
->hwndOwner
);
396 /* Get class or window DC if needed */
398 if (classPtr
->wc
.style
& CS_OWNDC
)
399 wndPtr
->hdce
= DCE_AllocDCE( DCE_WINDOW_DC
);
400 else if (classPtr
->wc
.style
& CS_CLASSDC
)
401 wndPtr
->hdce
= classPtr
->hdce
;
405 /* Insert the window in the linked list */
407 WIN_LinkWindow( hwnd
, HWND_TOP
);
409 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
411 NC_GetMinMaxInfo( hwnd
, &maxSize
, &maxPos
, &minTrack
, &maxTrack
);
413 if ( maxSize
.x
< width
)
416 wndPtr
->rectWindow
.right
= x
+ width
;
418 if ( maxSize
.y
< height
)
421 wndPtr
->rectWindow
.bottom
= y
+ height
;
424 /* Create the X window (only for top-level windows, and then only */
425 /* when there's no desktop window) */
427 if (!(style
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
430 HCURSOR hCursor
= classPtr
->wc
.hCursor
;
431 if (!hCursor
) hCursor
= LoadCursor( 0, IDC_ARROW
);
432 cursor
= (CURSORALLOC
*) GlobalLock(hCursor
);
434 win_attr
.event_mask
= ExposureMask
| KeyPressMask
| KeyReleaseMask
|
435 PointerMotionMask
| ButtonPressMask
|
436 ButtonReleaseMask
| FocusChangeMask
;
437 win_attr
.override_redirect
= TRUE
;
438 win_attr
.colormap
= COLOR_WinColormap
;
439 win_attr
.backing_store
= Options
.backingstore
? WhenMapped
: NotUseful
;
440 win_attr
.save_under
= ((classPtr
->wc
.style
& CS_SAVEBITS
) != 0);
441 win_attr
.cursor
= cursor
? cursor
->xcursor
: None
;
442 wndPtr
->window
= XCreateWindow( display
, rootWindow
, x
, y
,
443 width
, height
, 0, CopyFromParent
,
444 InputOutput
, CopyFromParent
,
445 CWEventMask
| CWOverrideRedirect
|
446 CWColormap
| CWCursor
| CWSaveUnder
|
447 CWBackingStore
, &win_attr
);
448 XStoreName( display
, wndPtr
->window
, windowName
);
449 EVENT_RegisterWindow( wndPtr
->window
, hwnd
);
450 GlobalUnlock( hCursor
);
453 if ((style
& WS_CAPTION
) && !(style
& WS_CHILD
))
455 if (menu
) SetMenu(hwnd
, menu
);
456 else if (classPtr
->wc
.lpszMenuName
)
457 SetMenu(hwnd
,LoadMenu(instance
,(SEGPTR
)classPtr
->wc
.lpszMenuName
));
459 else wndPtr
->wIDmenu
= menu
;
461 /* Send the WM_CREATE message */
463 hclassName
= USER_HEAP_ALLOC( strlen(className
)+1 );
464 strcpy( USER_HEAP_LIN_ADDR(hclassName
), className
);
465 createStruct
.lpCreateParams
= (LPSTR
)data
;
466 createStruct
.hInstance
= instance
;
467 createStruct
.hMenu
= menu
;
468 createStruct
.hwndParent
= parent
;
469 createStruct
.cx
= width
;
470 createStruct
.cy
= height
;
473 createStruct
.style
= style
;
474 createStruct
.lpszClass
= (LPSTR
)USER_HEAP_SEG_ADDR(hclassName
);
475 createStruct
.dwExStyle
= 0;
478 hwinName
= USER_HEAP_ALLOC( strlen(windowName
)+1 );
479 strcpy( USER_HEAP_LIN_ADDR(hwinName
), windowName
);
480 createStruct
.lpszName
= (LPSTR
)USER_HEAP_SEG_ADDR(hwinName
);
485 createStruct
.lpszName
= NULL
;
488 wmcreate
= SendMessage( hwnd
, WM_NCCREATE
, 0, MAKE_SEGPTR(&createStruct
) );
490 dprintf_win(stddeb
,"CreateWindowEx: WM_NCCREATE return 0\n");
495 WINPOS_SendNCCalcSize( hwnd
, FALSE
, &wndPtr
->rectWindow
,
496 NULL
, NULL
, NULL
, &wndPtr
->rectClient
);
497 wmcreate
= SendMessage(hwnd
, WM_CREATE
, 0, MAKE_SEGPTR(&createStruct
));
500 USER_HEAP_FREE( hclassName
);
501 if (hwinName
) USER_HEAP_FREE( hwinName
);
505 /* Abort window creation */
506 dprintf_win(stddeb
,"CreateWindowEx: wmcreate==-1, aborting\n");
507 WIN_DestroyWindow( hwnd
);
511 /* Create a copy of SysMenu */
512 if (style
& WS_SYSMENU
) wndPtr
->hSysMenu
= CopySysMenu();
514 WIN_SendParentNotify( hwnd
, WM_CREATE
, MAKELONG( hwnd
, wndPtr
->wIDmenu
) );
516 if (style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
517 /* if (style & WS_MINIMIZE) ShowWindow( hwnd, SW_MINIMIZE ); */
519 dprintf_win(stddeb
, "CreateWindowEx: return %04X \n", hwnd
);
524 /***********************************************************************
525 * DestroyWindow (USER.53)
527 BOOL
DestroyWindow( HWND hwnd
)
532 dprintf_win(stddeb
, "DestroyWindow (%04x)\n", hwnd
);
536 if (hwnd
== hwndDesktop
) return FALSE
; /* Can't destroy desktop */
537 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
538 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return FALSE
;
540 /* Hide the window */
542 if (wndPtr
->dwStyle
& WS_VISIBLE
)
543 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, SWP_HIDEWINDOW
| SWP_NOACTIVATE
|
544 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOSIZE
);
545 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
547 WIN_SendParentNotify( hwnd
, WM_DESTROY
, MAKELONG(hwnd
, wndPtr
->wIDmenu
) );
549 /* Recursively destroy owned windows */
553 HWND hwndSibling
= GetWindow( hwnd
, GW_HWNDFIRST
);
556 WND
*siblingPtr
= WIN_FindWndPtr( hwndSibling
);
557 if (siblingPtr
->hwndOwner
== hwnd
) break;
558 hwndSibling
= siblingPtr
->hwndNext
;
560 if (hwndSibling
) DestroyWindow( hwndSibling
);
564 /* Send destroy messages and destroy children */
566 SendMessage( hwnd
, WM_DESTROY
, 0, 0 );
567 while (wndPtr
->hwndChild
) /* The child removes itself from the list */
568 DestroyWindow( wndPtr
->hwndChild
);
569 SendMessage( hwnd
, WM_NCDESTROY
, 0, 0 );
571 /* Destroy the window */
573 WIN_DestroyWindow( hwnd
);
578 /***********************************************************************
579 * CloseWindow (USER.43)
581 void CloseWindow(HWND hWnd
)
583 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
584 if (wndPtr
->dwStyle
& WS_CHILD
) return;
585 ShowWindow(hWnd
, SW_MINIMIZE
);
589 /***********************************************************************
592 BOOL
OpenIcon(HWND hWnd
)
594 if (!IsIconic(hWnd
)) return FALSE
;
595 ShowWindow(hWnd
, SW_SHOWNORMAL
);
600 /***********************************************************************
601 * FindWindow (USER.50)
603 HWND
FindWindow(LPSTR ClassMatch
, LPSTR TitleMatch
)
611 hclass
= CLASS_FindClassByName( ClassMatch
, 0xffff, &classPtr
);
612 if (!hclass
) return 0;
616 hwnd
= GetTopWindow( hwndDesktop
);
619 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
620 if (!hclass
|| (wndPtr
->hClass
== hclass
))
622 /* Found matching class */
623 if (!TitleMatch
) return hwnd
;
626 char *textPtr
= (char *) USER_HEAP_LIN_ADDR( wndPtr
->hText
);
627 if (!strcmp( textPtr
, TitleMatch
)) return hwnd
;
630 hwnd
= wndPtr
->hwndNext
;
636 /**********************************************************************
637 * GetDesktopWindow (USER.286)
638 * GetDeskTopHwnd (USER.278)
640 HWND
GetDesktopWindow(void)
646 /*******************************************************************
647 * EnableWindow (USER.34)
649 BOOL
EnableWindow( HWND hwnd
, BOOL enable
)
653 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
654 if (enable
&& (wndPtr
->dwStyle
& WS_DISABLED
))
657 wndPtr
->dwStyle
&= ~WS_DISABLED
;
658 SendMessage( hwnd
, WM_ENABLE
, TRUE
, 0 );
661 else if (!enable
&& !(wndPtr
->dwStyle
& WS_DISABLED
))
664 wndPtr
->dwStyle
|= WS_DISABLED
;
665 if ((hwnd
== GetFocus()) || IsChild( hwnd
, GetFocus() ))
666 SetFocus( 0 ); /* A disabled window can't have the focus */
667 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
668 ReleaseCapture(); /* A disabled window can't capture the mouse */
669 SendMessage( hwnd
, WM_ENABLE
, FALSE
, 0 );
672 return ((wndPtr
->dwStyle
& WS_DISABLED
) != 0);
676 /***********************************************************************
677 * IsWindowEnabled (USER.35)
679 BOOL
IsWindowEnabled(HWND hWnd
)
683 if (!(wndPtr
= WIN_FindWndPtr(hWnd
))) return FALSE
;
684 return !(wndPtr
->dwStyle
& WS_DISABLED
);
688 /**********************************************************************
689 * GetWindowWord (USER.133)
691 WORD
GetWindowWord( HWND hwnd
, short offset
)
693 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
694 if (!wndPtr
) return 0;
695 if (offset
>= 0) return *(WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
698 case GWW_ID
: return wndPtr
->wIDmenu
;
699 case GWW_HWNDPARENT
: return wndPtr
->hwndParent
;
700 case GWW_HINSTANCE
: return wndPtr
->hInstance
;
706 /**********************************************************************
707 * SetWindowWord (USER.134)
709 WORD
SetWindowWord( HWND hwnd
, short offset
, WORD newval
)
712 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
713 if (!wndPtr
) return 0;
714 if (offset
>= 0) ptr
= (WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
717 case GWW_ID
: ptr
= &wndPtr
->wIDmenu
; break;
718 case GWW_HINSTANCE
: ptr
= &wndPtr
->hInstance
; break;
727 /**********************************************************************
728 * GetWindowLong (USER.135)
730 LONG
GetWindowLong( HWND hwnd
, short offset
)
732 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
733 if (!wndPtr
) return 0;
734 if (offset
>= 0) return *(LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
737 case GWL_STYLE
: return wndPtr
->dwStyle
;
738 case GWL_EXSTYLE
: return wndPtr
->dwExStyle
;
739 case GWL_WNDPROC
: return (LONG
)wndPtr
->lpfnWndProc
;
745 /**********************************************************************
746 * SetWindowLong (USER.136)
748 LONG
SetWindowLong( HWND hwnd
, short offset
, LONG newval
)
751 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
752 if (!wndPtr
) return 0;
753 if (offset
>= 0) ptr
= (LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
756 case GWL_STYLE
: ptr
= &wndPtr
->dwStyle
; break;
757 case GWL_EXSTYLE
: ptr
= &wndPtr
->dwExStyle
; break;
758 case GWL_WNDPROC
: ptr
= (LONG
*)&wndPtr
->lpfnWndProc
; break;
767 /*******************************************************************
768 * GetWindowText (USER.36)
770 int WIN16_GetWindowText( HWND hwnd
, SEGPTR lpString
, int nMaxCount
)
772 return (int)SendMessage(hwnd
, WM_GETTEXT
, (WORD
)nMaxCount
,
776 int GetWindowText( HWND hwnd
, LPSTR lpString
, int nMaxCount
)
781 /* We have to allocate a buffer on the USER heap */
782 /* to be able to pass its address to 16-bit code */
783 if (!(handle
= USER_HEAP_ALLOC( nMaxCount
))) return 0;
784 len
= (int)SendMessage( hwnd
, WM_GETTEXT
, (WORD
)nMaxCount
,
785 USER_HEAP_SEG_ADDR(handle
) );
786 strncpy( lpString
, USER_HEAP_LIN_ADDR(handle
), nMaxCount
);
787 USER_HEAP_FREE( handle
);
792 /*******************************************************************
793 * SetWindowText (USER.37)
795 void WIN16_SetWindowText( HWND hwnd
, SEGPTR lpString
)
797 SendMessage( hwnd
, WM_SETTEXT
, 0, (DWORD
)lpString
);
800 void SetWindowText( HWND hwnd
, LPSTR lpString
)
804 /* We have to allocate a buffer on the USER heap */
805 /* to be able to pass its address to 16-bit code */
806 if (!(handle
= USER_HEAP_ALLOC( strlen(lpString
)+1 ))) return;
807 strcpy( USER_HEAP_LIN_ADDR(handle
), lpString
);
808 SendMessage( hwnd
, WM_SETTEXT
, 0, USER_HEAP_SEG_ADDR(handle
) );
809 USER_HEAP_FREE( handle
);
813 /*******************************************************************
814 * GetWindowTextLength (USER.38)
816 int GetWindowTextLength(HWND hwnd
)
818 return (int)SendMessage(hwnd
, WM_GETTEXTLENGTH
, 0, 0 );
822 /*******************************************************************
825 BOOL
IsWindow( HWND hwnd
)
827 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
828 return ((wndPtr
!= NULL
) && (wndPtr
->dwMagic
== WND_MAGIC
));
832 /*****************************************************************
833 * GetParent (USER.46)
835 HWND
GetParent(HWND hwnd
)
837 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
838 if (!wndPtr
|| !(wndPtr
->dwStyle
& WS_CHILD
)) return 0;
839 return wndPtr
->hwndParent
;
842 /*****************************************************************
843 * SetParent (USER.233)
845 HWND
SetParent(HWND hwndChild
, HWND hwndNewParent
)
849 WND
*wndPtr
= WIN_FindWndPtr(hwndChild
);
850 if (!wndPtr
|| !(wndPtr
->dwStyle
& WS_CHILD
)) return 0;
852 temp
= wndPtr
->hwndParent
;
855 wndPtr
->hwndParent
= hwndNewParent
;
857 wndPtr
->hwndParent
= GetDesktopWindow();
864 /*******************************************************************
867 BOOL
IsChild( HWND parent
, HWND child
)
869 WND
* wndPtr
= WIN_FindWndPtr( child
);
870 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
872 if (wndPtr
->hwndParent
== parent
) return TRUE
;
873 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
879 /***********************************************************************
880 * IsWindowVisible (USER.49)
882 BOOL
IsWindowVisible(HWND hWnd
)
884 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
885 if (wndPtr
== 0) return(FALSE
);
886 else return ((wndPtr
->dwStyle
& WS_VISIBLE
) != 0);
891 /*******************************************************************
892 * GetTopWindow (USER.229)
894 HWND
GetTopWindow( HWND hwnd
)
896 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
897 if (wndPtr
) return wndPtr
->hwndChild
;
902 /*******************************************************************
903 * GetWindow (USER.262)
905 HWND
GetWindow( HWND hwnd
, WORD rel
)
907 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
908 if (!wndPtr
) return 0;
912 if (wndPtr
->hwndParent
)
914 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
915 return parentPtr
->hwndChild
;
920 if (!wndPtr
->hwndParent
) return 0; /* Desktop window */
921 while (wndPtr
->hwndNext
)
923 hwnd
= wndPtr
->hwndNext
;
924 wndPtr
= WIN_FindWndPtr( hwnd
);
929 return wndPtr
->hwndNext
;
935 if (wndPtr
->hwndParent
)
937 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
938 hwndPrev
= parentPtr
->hwndChild
;
940 else return 0; /* Desktop window */
941 if (hwndPrev
== hwnd
) return 0;
944 wndPtr
= WIN_FindWndPtr( hwndPrev
);
945 if (wndPtr
->hwndNext
== hwnd
) break;
946 hwndPrev
= wndPtr
->hwndNext
;
952 return wndPtr
->hwndOwner
;
955 return wndPtr
->hwndChild
;
961 /*******************************************************************
962 * GetNextWindow (USER.230)
964 HWND
GetNextWindow( HWND hwnd
, WORD flag
)
966 if ((flag
!= GW_HWNDNEXT
) && (flag
!= GW_HWNDPREV
)) return 0;
967 return GetWindow( hwnd
, flag
);
972 /*******************************************************************
973 * GetLastActivePopup (USER.287)
975 HWND
GetLastActivePopup(HWND hwnd
)
978 wndPtr
= WIN_FindWndPtr(hwnd
);
979 if (wndPtr
== NULL
) return hwnd
;
980 return wndPtr
->hwndLastActive
;
984 /*******************************************************************
985 * EnumWindows (USER.54)
987 BOOL
EnumWindows( FARPROC lpEnumFunc
, LPARAM lParam
)
994 /* We have to build a list of all windows first, to avoid */
995 /* unpleasant side-effects, for instance if the callback */
996 /* function changes the Z-order of the windows. */
998 /* First count the windows */
1001 for (hwnd
= hwndDesktop
; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1003 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
1006 if (!count
) return TRUE
;
1008 /* Now build the list of all windows */
1010 if (!(list
= (HWND
*)malloc( sizeof(HWND
) * count
))) return FALSE
;
1011 for (hwnd
= hwndDesktop
, pWnd
= list
; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1013 wndPtr
= WIN_FindWndPtr( hwnd
);
1017 /* Now call the callback function for every window */
1019 for (pWnd
= list
; count
> 0; count
--, pWnd
++)
1021 /* Make sure that window still exists */
1022 if (!IsWindow(*pWnd
)) continue;
1023 if (!CallEnumWindowsProc( lpEnumFunc
, *pWnd
, lParam
)) break;
1030 /**********************************************************************
1031 * EnumTaskWindows (USER.225)
1033 BOOL
EnumTaskWindows( HTASK hTask
, FARPROC lpEnumFunc
, LONG lParam
)
1038 HANDLE hQueue
= GetTaskQueue( hTask
);
1041 /* This function is the same as EnumWindows(), */
1042 /* except for an added check on the window queue. */
1044 /* First count the windows */
1047 for (hwnd
= hwndDesktop
; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1049 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
1050 if (wndPtr
->hmemTaskQ
== hQueue
) count
++;
1052 if (!count
) return TRUE
;
1054 /* Now build the list of all windows */
1056 if (!(list
= (HWND
*)malloc( sizeof(HWND
) * count
))) return FALSE
;
1057 for (hwnd
= hwndDesktop
, pWnd
= list
; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1059 wndPtr
= WIN_FindWndPtr( hwnd
);
1060 if (wndPtr
->hmemTaskQ
== hQueue
) *pWnd
++ = hwnd
;
1063 /* Now call the callback function for every window */
1065 for (pWnd
= list
; count
> 0; count
--, pWnd
++)
1067 /* Make sure that window still exists */
1068 if (!IsWindow(*pWnd
)) continue;
1069 if (!CallEnumTaskWndProc( lpEnumFunc
, *pWnd
, lParam
)) break;
1076 /*******************************************************************
1079 * o hwnd is the first child to use, loop until all next windows
1084 * o call ourselves with the next child window
1087 static BOOL
WIN_EnumChildWin(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1093 if (!(wndPtr
=WIN_FindWndPtr(hwnd
))) return 0;
1094 if (!CallEnumWindowsProc( wndenumprc
, hwnd
, lParam
)) return 0;
1095 if (!WIN_EnumChildWin(wndPtr
->hwndChild
, wndenumprc
, lParam
)) return 0;
1096 hwnd
=wndPtr
->hwndNext
;
1101 /*******************************************************************
1102 * EnumChildWindows (USER.55)
1104 * o gets the first child of hwnd
1106 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1108 BOOL
EnumChildWindows(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1112 dprintf_enum(stddeb
,"EnumChildWindows\n");
1114 if (hwnd
== 0) return 0;
1115 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1116 hwnd
= wndPtr
->hwndChild
;
1117 return WIN_EnumChildWin(hwnd
, wndenumprc
, lParam
);
1121 /*******************************************************************
1122 * AnyPopup [USER.52]
1126 dprintf_win(stdnimp
,"EMPTY STUB !! AnyPopup !\n");
1130 /*******************************************************************
1131 * FlashWindow [USER.105]
1133 BOOL
FlashWindow(HWND hWnd
, BOOL bInvert
)
1135 dprintf_win(stdnimp
,"EMPTY STUB !! FlashWindow !\n");
1140 /*******************************************************************
1141 * SetSysModalWindow [USER.188]
1143 HWND
SetSysModalWindow(HWND hWnd
)
1145 HWND hWndOldModal
= hWndSysModal
;
1146 hWndSysModal
= hWnd
;
1147 dprintf_win(stdnimp
,"EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd
);
1148 return hWndOldModal
;
1152 /*******************************************************************
1153 * GetSysModalWindow [USER.189]
1155 HWND
GetSysModalWindow(void)
1157 return hWndSysModal
;