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()
219 if (!(hclass
= CLASS_FindClassByName( DESKTOP_CLASS_NAME
, 0, &classPtr
)))
222 hwndDesktop
= USER_HEAP_ALLOC( sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
223 if (!hwndDesktop
) return FALSE
;
224 wndPtr
= (WND
*) USER_HEAP_LIN_ADDR( hwndDesktop
);
226 wndPtr
->hwndNext
= 0;
227 wndPtr
->hwndChild
= 0;
228 wndPtr
->dwMagic
= WND_MAGIC
;
229 wndPtr
->hwndParent
= 0;
230 wndPtr
->hwndOwner
= 0;
231 wndPtr
->hClass
= hclass
;
232 wndPtr
->hInstance
= 0;
233 wndPtr
->rectWindow
.left
= 0;
234 wndPtr
->rectWindow
.top
= 0;
235 wndPtr
->rectWindow
.right
= SYSMETRICS_CXSCREEN
;
236 wndPtr
->rectWindow
.bottom
= SYSMETRICS_CYSCREEN
;
237 wndPtr
->rectClient
= wndPtr
->rectWindow
;
238 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
239 wndPtr
->ptIconPos
.x
= -1;
240 wndPtr
->ptIconPos
.y
= -1;
241 wndPtr
->ptMaxPos
.x
= -1;
242 wndPtr
->ptMaxPos
.y
= -1;
243 wndPtr
->hmemTaskQ
= 0; /* Desktop does not belong to a task */
244 wndPtr
->hrgnUpdate
= 0;
245 wndPtr
->hwndLastActive
= hwndDesktop
;
246 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
247 wndPtr
->dwStyle
= WS_VISIBLE
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
;
248 wndPtr
->dwExStyle
= 0;
250 wndPtr
->hVScroll
= 0;
251 wndPtr
->hHScroll
= 0;
255 wndPtr
->window
= rootWindow
;
256 wndPtr
->hSysMenu
= 0;
260 /* Send dummy WM_NCCREATE message */
261 SendMessage( hwndDesktop
, WM_NCCREATE
, 0, 0 );
262 EVENT_RegisterWindow( wndPtr
->window
, hwndDesktop
);
263 RedrawWindow( hwndDesktop
, NULL
, 0,
264 RDW_INVALIDATE
| RDW_ERASE
| RDW_ERASENOW
);
269 /***********************************************************************
270 * CreateWindow (USER.41)
272 HWND
CreateWindow( LPSTR className
, LPSTR windowName
,
273 DWORD style
, short x
, short y
, short width
, short height
,
274 HWND parent
, HMENU menu
, HANDLE instance
, SEGPTR data
)
276 return CreateWindowEx( 0, className
, windowName
, style
,
277 x
, y
, width
, height
, parent
, menu
, instance
, data
);
281 /***********************************************************************
282 * CreateWindowEx (USER.452)
284 HWND
CreateWindowEx( DWORD exStyle
, LPSTR className
, LPSTR windowName
,
285 DWORD style
, short x
, short y
, short width
, short height
,
286 HWND parent
, HMENU menu
, HANDLE instance
, SEGPTR data
)
291 POINT maxSize
, maxPos
, minTrack
, maxTrack
;
292 CREATESTRUCT
*createStruct
;
293 HANDLE hcreateStruct
, hwinName
, hclassName
;
295 XSetWindowAttributes win_attr
;
297 dprintf_win(stddeb
, "CreateWindowEx: %08lX '%s' '%s' %08lX %d,%d %dx%d %04X %04X %04X %08lx\n",
298 exStyle
, className
, windowName
, style
, x
, y
, width
, height
,
299 parent
, menu
, instance
, data
);
300 /* 'soundrec.exe' has negative position !
301 Why ? For now, here a patch : */
302 if (!strcmp(className
, "SoundRec"))
307 if (x
== CW_USEDEFAULT
) x
= y
= 0;
308 if (width
== CW_USEDEFAULT
)
313 if (width
== 0) width
= 1;
314 if (height
== 0) height
= 1;
316 /* Find the parent and class */
320 /* Make sure parent is valid */
321 if (!IsWindow( parent
)) return 0;
323 else if (style
& WS_CHILD
) return 0; /* WS_CHILD needs a parent */
325 if (!(class = CLASS_FindClassByName( className
, instance
, &classPtr
))) {
326 fprintf(stderr
,"CreateWindow BAD CLASSNAME '%s' !\n", className
);
330 /* Correct the window style */
332 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
333 style
|= WS_CAPTION
| WS_CLIPSIBLINGS
;
334 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
336 /* Create the window structure */
338 hwnd
= USER_HEAP_ALLOC( sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
341 /* Fill the structure */
343 wndPtr
= (WND
*) USER_HEAP_LIN_ADDR( hwnd
);
344 wndPtr
->hwndNext
= 0;
345 wndPtr
->hwndChild
= 0;
347 wndPtr
->dwMagic
= WND_MAGIC
;
348 wndPtr
->hwndParent
= (style
& WS_CHILD
) ? parent
: hwndDesktop
;
349 wndPtr
->hwndOwner
= (style
& WS_CHILD
) ? 0 : parent
;
350 wndPtr
->hClass
= class;
351 wndPtr
->hInstance
= instance
;
352 wndPtr
->rectWindow
.left
= x
;
353 wndPtr
->rectWindow
.top
= y
;
354 wndPtr
->rectWindow
.right
= x
+ width
;
355 wndPtr
->rectWindow
.bottom
= y
+ height
;
356 wndPtr
->rectClient
= wndPtr
->rectWindow
;
357 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
358 wndPtr
->ptIconPos
.x
= -1;
359 wndPtr
->ptIconPos
.y
= -1;
360 wndPtr
->ptMaxPos
.x
= -1;
361 wndPtr
->ptMaxPos
.y
= -1;
362 wndPtr
->hmemTaskQ
= GetTaskQueue(0);
363 wndPtr
->hrgnUpdate
= 0;
364 wndPtr
->hwndPrevActive
= 0;
365 wndPtr
->hwndLastActive
= hwnd
;
366 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
367 wndPtr
->dwStyle
= style
;
368 wndPtr
->dwExStyle
= exStyle
;
372 wndPtr
->hVScroll
= 0;
373 wndPtr
->hHScroll
= 0;
374 wndPtr
->hSysMenu
= 0;
378 if (classPtr
->wc
.cbWndExtra
)
379 memset( wndPtr
->wExtra
, 0, classPtr
->wc
.cbWndExtra
);
380 classPtr
->cWindows
++;
382 /* Make sure owner is a top-level window */
384 while (wndPtr
->hwndOwner
&& GetParent(wndPtr
->hwndOwner
))
385 wndPtr
->hwndOwner
= GetParent(wndPtr
->hwndOwner
);
387 /* Get class or window DC if needed */
389 if (classPtr
->wc
.style
& CS_OWNDC
)
390 wndPtr
->hdce
= DCE_AllocDCE( DCE_WINDOW_DC
);
391 else if (classPtr
->wc
.style
& CS_CLASSDC
)
392 wndPtr
->hdce
= classPtr
->hdce
;
396 /* Insert the window in the linked list */
398 WIN_LinkWindow( hwnd
, HWND_TOP
);
400 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
402 NC_GetMinMaxInfo( hwnd
, &maxSize
, &maxPos
, &minTrack
, &maxTrack
);
404 if ( maxSize
.x
< width
)
407 wndPtr
->rectWindow
.right
= x
+ width
;
409 if ( maxSize
.y
< height
)
412 wndPtr
->rectWindow
.bottom
= y
+ height
;
415 /* Create the X window (only for top-level windows, and then only */
416 /* when there's no desktop window) */
418 if (!(style
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
421 HCURSOR hCursor
= classPtr
->wc
.hCursor
;
422 if (!hCursor
) hCursor
= LoadCursor( 0, IDC_ARROW
);
423 cursor
= (CURSORALLOC
*) GlobalLock(hCursor
);
425 win_attr
.event_mask
= ExposureMask
| KeyPressMask
| KeyReleaseMask
|
426 PointerMotionMask
| ButtonPressMask
|
427 ButtonReleaseMask
| FocusChangeMask
;
428 win_attr
.override_redirect
= TRUE
;
429 win_attr
.colormap
= COLOR_WinColormap
;
430 win_attr
.backing_store
= Options
.backingstore
? WhenMapped
: NotUseful
;
431 win_attr
.save_under
= ((classPtr
->wc
.style
& CS_SAVEBITS
) != 0);
432 win_attr
.cursor
= cursor
? cursor
->xcursor
: None
;
433 wndPtr
->window
= XCreateWindow( display
, rootWindow
, x
, y
,
434 width
, height
, 0, CopyFromParent
,
435 InputOutput
, CopyFromParent
,
436 CWEventMask
| CWOverrideRedirect
|
437 CWColormap
| CWCursor
| CWSaveUnder
|
438 CWBackingStore
, &win_attr
);
439 XStoreName( display
, wndPtr
->window
, windowName
);
440 EVENT_RegisterWindow( wndPtr
->window
, hwnd
);
441 GlobalUnlock( hCursor
);
444 if ((style
& WS_CAPTION
) && !(style
& WS_CHILD
))
446 if (menu
) SetMenu(hwnd
, menu
);
447 else if (classPtr
->wc
.lpszMenuName
)
448 SetMenu(hwnd
,LoadMenu(instance
,(SEGPTR
)classPtr
->wc
.lpszMenuName
));
450 else wndPtr
->wIDmenu
= menu
;
452 /* Send the WM_CREATE message */
454 hcreateStruct
= USER_HEAP_ALLOC( sizeof(CREATESTRUCT
) );
455 hclassName
= USER_HEAP_ALLOC( strlen(className
)+1 );
456 strcpy( USER_HEAP_LIN_ADDR(hclassName
), className
);
457 createStruct
= (CREATESTRUCT
*) USER_HEAP_LIN_ADDR( hcreateStruct
);
458 createStruct
->lpCreateParams
= (LPSTR
)data
;
459 createStruct
->hInstance
= instance
;
460 createStruct
->hMenu
= menu
;
461 createStruct
->hwndParent
= parent
;
462 createStruct
->cx
= width
;
463 createStruct
->cy
= height
;
466 createStruct
->style
= style
;
467 createStruct
->lpszClass
= (LPSTR
)USER_HEAP_SEG_ADDR(hclassName
);
468 createStruct
->dwExStyle
= 0;
471 hwinName
= USER_HEAP_ALLOC( strlen(windowName
)+1 );
472 strcpy( USER_HEAP_LIN_ADDR(hwinName
), windowName
);
473 createStruct
->lpszName
= (LPSTR
)USER_HEAP_SEG_ADDR(hwinName
);
478 createStruct
->lpszName
= NULL
;
481 wmcreate
= SendMessage( hwnd
, WM_NCCREATE
, 0,
482 USER_HEAP_SEG_ADDR(hcreateStruct
) );
483 if (!wmcreate
) wmcreate
= -1;
486 WINPOS_SendNCCalcSize( hwnd
, FALSE
, &wndPtr
->rectWindow
,
487 NULL
, NULL
, NULL
, &wndPtr
->rectClient
);
488 wmcreate
= SendMessage( hwnd
, WM_CREATE
, 0,
489 USER_HEAP_SEG_ADDR(hcreateStruct
) );
492 USER_HEAP_FREE( hcreateStruct
);
493 USER_HEAP_FREE( hclassName
);
494 if (hwinName
) USER_HEAP_FREE( hwinName
);
498 /* Abort window creation */
499 WIN_DestroyWindow( hwnd
);
503 /* Create a copy of SysMenu */
504 if (style
& WS_SYSMENU
) wndPtr
->hSysMenu
= CopySysMenu();
506 /* Register window in current task windows list */
507 AddWindowToTask(GetCurrentTask(), hwnd
);
509 WIN_SendParentNotify( hwnd
, WM_CREATE
, MAKELONG( hwnd
, wndPtr
->wIDmenu
) );
511 if (style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
512 /* if (style & WS_MINIMIZE) ShowWindow( hwnd, SW_MINIMIZE ); */
514 dprintf_win(stddeb
, "CreateWindowEx: return %04X \n", hwnd
);
519 /***********************************************************************
520 * DestroyWindow (USER.53)
522 BOOL
DestroyWindow( HWND hwnd
)
527 dprintf_win(stddeb
, "DestroyWindow (%04x)\n", hwnd
);
531 if (hwnd
== hwndDesktop
) return FALSE
; /* Can't destroy desktop */
532 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
533 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return FALSE
;
535 /* Hide the window */
537 if (wndPtr
->dwStyle
& WS_VISIBLE
)
538 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, SWP_HIDEWINDOW
| SWP_NOACTIVATE
|
539 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOSIZE
);
540 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
542 WIN_SendParentNotify( hwnd
, WM_DESTROY
, MAKELONG(hwnd
, wndPtr
->wIDmenu
) );
544 /* Recursively destroy owned windows */
548 HWND hwndSibling
= GetWindow( hwnd
, GW_HWNDFIRST
);
551 WND
*siblingPtr
= WIN_FindWndPtr( hwndSibling
);
552 if (siblingPtr
->hwndOwner
== hwnd
) break;
553 hwndSibling
= siblingPtr
->hwndNext
;
555 if (hwndSibling
) DestroyWindow( hwndSibling
);
559 /* Send destroy messages and destroy children */
561 SendMessage( hwnd
, WM_DESTROY
, 0, 0 );
562 while (wndPtr
->hwndChild
) /* The child removes itself from the list */
563 DestroyWindow( wndPtr
->hwndChild
);
564 SendMessage( hwnd
, WM_NCDESTROY
, 0, 0 );
566 /* Remove the window from current task windows list */
567 RemoveWindowFromTask(GetCurrentTask(), hwnd
);
569 /* Destroy the window */
571 WIN_DestroyWindow( hwnd
);
576 /***********************************************************************
577 * CloseWindow (USER.43)
579 void CloseWindow(HWND hWnd
)
581 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
582 if (wndPtr
->dwStyle
& WS_CHILD
) return;
583 ShowWindow(hWnd
, SW_MINIMIZE
);
587 /***********************************************************************
590 BOOL
OpenIcon(HWND hWnd
)
592 if (!IsIconic(hWnd
)) return FALSE
;
593 ShowWindow(hWnd
, SW_SHOWNORMAL
);
598 /***********************************************************************
599 * FindWindow (USER.50)
601 HWND
FindWindow(LPSTR ClassMatch
, LPSTR TitleMatch
)
609 hclass
= CLASS_FindClassByName( ClassMatch
, 0xffff, &classPtr
);
610 if (!hclass
) return 0;
614 hwnd
= GetTopWindow( hwndDesktop
);
617 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
618 if (!hclass
|| (wndPtr
->hClass
== hclass
))
620 /* Found matching class */
621 if (!TitleMatch
) return hwnd
;
624 char *textPtr
= (char *) USER_HEAP_LIN_ADDR( wndPtr
->hText
);
625 if (!strcmp( textPtr
, TitleMatch
)) return hwnd
;
628 hwnd
= wndPtr
->hwndNext
;
634 /**********************************************************************
635 * GetDesktopWindow (USER.286)
636 * GetDeskTopHwnd (USER.278)
638 HWND
GetDesktopWindow(void)
644 /*******************************************************************
645 * EnableWindow (USER.34)
647 BOOL
EnableWindow( HWND hwnd
, BOOL enable
)
651 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
652 if (enable
&& (wndPtr
->dwStyle
& WS_DISABLED
))
655 wndPtr
->dwStyle
&= ~WS_DISABLED
;
656 SendMessage( hwnd
, WM_ENABLE
, TRUE
, 0 );
659 else if (!enable
&& !(wndPtr
->dwStyle
& WS_DISABLED
))
662 wndPtr
->dwStyle
|= WS_DISABLED
;
663 if ((hwnd
== GetFocus()) || IsChild( hwnd
, GetFocus() ))
664 SetFocus( 0 ); /* A disabled window can't have the focus */
665 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
666 ReleaseCapture(); /* A disabled window can't capture the mouse */
667 SendMessage( hwnd
, WM_ENABLE
, FALSE
, 0 );
670 return ((wndPtr
->dwStyle
& WS_DISABLED
) != 0);
674 /***********************************************************************
675 * IsWindowEnabled (USER.35)
677 BOOL
IsWindowEnabled(HWND hWnd
)
681 if (!(wndPtr
= WIN_FindWndPtr(hWnd
))) return FALSE
;
682 return !(wndPtr
->dwStyle
& WS_DISABLED
);
686 /**********************************************************************
687 * GetWindowWord (USER.133)
689 WORD
GetWindowWord( HWND hwnd
, short offset
)
691 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
692 if (!wndPtr
) return 0;
693 if (offset
>= 0) return *(WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
696 case GWW_ID
: return wndPtr
->wIDmenu
;
697 case GWW_HWNDPARENT
: return wndPtr
->hwndParent
;
698 case GWW_HINSTANCE
: return wndPtr
->hInstance
;
704 /**********************************************************************
705 * SetWindowWord (USER.134)
707 WORD
SetWindowWord( HWND hwnd
, short offset
, WORD newval
)
710 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
711 if (!wndPtr
) return 0;
712 if (offset
>= 0) ptr
= (WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
715 case GWW_ID
: ptr
= &wndPtr
->wIDmenu
;
716 case GWW_HINSTANCE
: ptr
= &wndPtr
->hInstance
;
725 /**********************************************************************
726 * GetWindowLong (USER.135)
728 LONG
GetWindowLong( HWND hwnd
, short offset
)
730 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
731 if (!wndPtr
) return 0;
732 if (offset
>= 0) return *(LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
735 case GWL_STYLE
: return wndPtr
->dwStyle
;
736 case GWL_EXSTYLE
: return wndPtr
->dwExStyle
;
737 case GWL_WNDPROC
: return (LONG
)wndPtr
->lpfnWndProc
;
743 /**********************************************************************
744 * SetWindowLong (USER.136)
746 LONG
SetWindowLong( HWND hwnd
, short offset
, LONG newval
)
749 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
750 if (!wndPtr
) return 0;
751 if (offset
>= 0) ptr
= (LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
754 case GWL_STYLE
: ptr
= &wndPtr
->dwStyle
;
756 case GWL_EXSTYLE
: ptr
= &wndPtr
->dwExStyle
;
758 case GWL_WNDPROC
: ptr
= (LONG
*)(&wndPtr
->lpfnWndProc
);
768 /*******************************************************************
769 * GetWindowText (USER.36)
771 int WIN16_GetWindowText( HWND hwnd
, SEGPTR lpString
, int nMaxCount
)
773 return (int)SendMessage(hwnd
, WM_GETTEXT
, (WORD
)nMaxCount
,
777 int GetWindowText( HWND hwnd
, LPSTR lpString
, int nMaxCount
)
782 /* We have to allocate a buffer on the USER heap */
783 /* to be able to pass its address to 16-bit code */
784 if (!(handle
= USER_HEAP_ALLOC( nMaxCount
))) return 0;
785 len
= (int)SendMessage( hwnd
, WM_GETTEXT
, (WORD
)nMaxCount
,
786 USER_HEAP_SEG_ADDR(handle
) );
787 strncpy( lpString
, USER_HEAP_LIN_ADDR(handle
), nMaxCount
);
788 USER_HEAP_FREE( handle
);
793 /*******************************************************************
794 * SetWindowText (USER.37)
796 void WIN16_SetWindowText( HWND hwnd
, SEGPTR lpString
)
798 SendMessage( hwnd
, WM_SETTEXT
, 0, (DWORD
)lpString
);
801 void SetWindowText( HWND hwnd
, LPSTR lpString
)
805 /* We have to allocate a buffer on the USER heap */
806 /* to be able to pass its address to 16-bit code */
807 if (!(handle
= USER_HEAP_ALLOC( strlen(lpString
)+1 ))) return;
808 strcpy( USER_HEAP_LIN_ADDR(handle
), lpString
);
809 SendMessage( hwnd
, WM_SETTEXT
, 0, USER_HEAP_SEG_ADDR(handle
) );
810 USER_HEAP_FREE( handle
);
814 /*******************************************************************
815 * GetWindowTextLength (USER.38)
817 int GetWindowTextLength(HWND hwnd
)
819 return (int)SendMessage(hwnd
, WM_GETTEXTLENGTH
, 0, 0 );
823 /*******************************************************************
826 BOOL
IsWindow( HWND hwnd
)
828 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
829 return ((wndPtr
!= NULL
) && (wndPtr
->dwMagic
== WND_MAGIC
));
833 /*****************************************************************
834 * GetParent (USER.46)
836 HWND
GetParent(HWND hwnd
)
838 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
839 if (!wndPtr
|| !(wndPtr
->dwStyle
& WS_CHILD
)) return 0;
840 return wndPtr
->hwndParent
;
843 /*****************************************************************
844 * SetParent (USER.233)
846 HWND
SetParent(HWND hwndChild
, HWND hwndNewParent
)
850 WND
*wndPtr
= WIN_FindWndPtr(hwndChild
);
851 if (!wndPtr
|| !(wndPtr
->dwStyle
& WS_CHILD
)) return 0;
853 temp
= wndPtr
->hwndParent
;
856 wndPtr
->hwndParent
= hwndNewParent
;
858 wndPtr
->hwndParent
= GetDesktopWindow();
865 /*******************************************************************
868 BOOL
IsChild( HWND parent
, HWND child
)
870 WND
* wndPtr
= WIN_FindWndPtr( child
);
871 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
873 if (wndPtr
->hwndParent
== parent
) return TRUE
;
874 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
880 /***********************************************************************
881 * IsWindowVisible (USER.49)
883 BOOL
IsWindowVisible(HWND hWnd
)
885 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
886 if (wndPtr
== 0) return(FALSE
);
887 else return ((wndPtr
->dwStyle
& WS_VISIBLE
) != 0);
892 /*******************************************************************
893 * GetTopWindow (USER.229)
895 HWND
GetTopWindow( HWND hwnd
)
897 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
898 if (wndPtr
) return wndPtr
->hwndChild
;
903 /*******************************************************************
904 * GetWindow (USER.262)
906 HWND
GetWindow( HWND hwnd
, WORD rel
)
908 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
909 if (!wndPtr
) return 0;
913 if (wndPtr
->hwndParent
)
915 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
916 return parentPtr
->hwndChild
;
921 if (!wndPtr
->hwndParent
) return 0; /* Desktop window */
922 while (wndPtr
->hwndNext
)
924 hwnd
= wndPtr
->hwndNext
;
925 wndPtr
= WIN_FindWndPtr( hwnd
);
930 return wndPtr
->hwndNext
;
936 if (wndPtr
->hwndParent
)
938 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
939 hwndPrev
= parentPtr
->hwndChild
;
941 else return 0; /* Desktop window */
942 if (hwndPrev
== hwnd
) return 0;
945 wndPtr
= WIN_FindWndPtr( hwndPrev
);
946 if (wndPtr
->hwndNext
== hwnd
) break;
947 hwndPrev
= wndPtr
->hwndNext
;
953 return wndPtr
->hwndOwner
;
956 return wndPtr
->hwndChild
;
962 /*******************************************************************
963 * GetNextWindow (USER.230)
965 HWND
GetNextWindow( HWND hwnd
, WORD flag
)
967 if ((flag
!= GW_HWNDNEXT
) && (flag
!= GW_HWNDPREV
)) return 0;
968 return GetWindow( hwnd
, flag
);
973 /*******************************************************************
974 * GetLastActivePopup (USER.287)
976 HWND
GetLastActivePopup(HWND hwnd
)
979 wndPtr
= WIN_FindWndPtr(hwnd
);
980 if (wndPtr
== NULL
) return hwnd
;
981 return wndPtr
->hwndLastActive
;
985 /*******************************************************************
986 * EnumWindows (USER.54)
988 * o gets the desktop window and iterates over all the windows
989 * which are direct decendents of the desktop * by iterating over
990 * the desktop's child window and all the child windows next
993 * o call wndenumprc for every child window the desktop has
994 * (parameters to Callback16 passed backwards so they are
995 * put in in pascal calling order)
997 * o if wndenumprc returns 0 exit
1000 BOOL
EnumWindows(FARPROC wndenumprc
, LPARAM lParam
)
1002 HWND hwnd
= GetTopWindow( GetDesktopWindow() );
1006 dprintf_enum(stddeb
,"EnumWindows\n");
1009 if ( !(wndPtr
=WIN_FindWndPtr(hwnd
)) ) {
1013 (*wndenumprc
)(hwnd
, lParam
);
1015 result
= CallBack16(wndenumprc
, 2,
1016 CALLBACK_SIZE_WORD
, (int) hwnd
,
1017 CALLBACK_SIZE_LONG
, lParam
);
1022 hwnd
=wndPtr
->hwndNext
;
1024 return 1; /* for now */
1027 /*******************************************************************
1030 * o hwnd is the first child to use, loop until all next windows
1033 * o call wdnenumprc with parameters in inverse order (pascal)
1035 * o call ourselves with the next child window
1038 static BOOL
WIN_EnumChildWin(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1043 if ( !(wndPtr
=WIN_FindWndPtr(hwnd
)) ) {
1047 if (!(*wndenumprc
)( 2, lParam
, (int) hwnd
)) {
1049 if (!CallBack16(wndenumprc
, 2,
1050 CALLBACK_SIZE_WORD
, (int) hwnd
,
1051 CALLBACK_SIZE_LONG
, lParam
)) {
1055 if (!WIN_EnumChildWin(wndPtr
->hwndChild
, wndenumprc
, lParam
)) {
1058 hwnd
=wndPtr
->hwndNext
;
1063 /*******************************************************************
1064 * EnumChildWindows (USER.55)
1066 * o gets the first child of hwnd
1068 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1070 BOOL
EnumChildWindows(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1074 dprintf_enum(stddeb
,"EnumChildWindows\n");
1076 if (hwnd
== 0) return 0;
1077 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1078 hwnd
= wndPtr
->hwndChild
;
1079 return WIN_EnumChildWin(hwnd
, wndenumprc
, lParam
);
1082 /*******************************************************************
1083 * AnyPopup [USER.52]
1087 dprintf_win(stdnimp
,"EMPTY STUB !! AnyPopup !\n");
1091 /*******************************************************************
1092 * FlashWindow [USER.105]
1094 BOOL
FlashWindow(HWND hWnd
, BOOL bInvert
)
1096 dprintf_win(stdnimp
,"EMPTY STUB !! FlashWindow !\n");
1101 /*******************************************************************
1102 * SetSysModalWindow [USER.188]
1104 HWND
SetSysModalWindow(HWND hWnd
)
1106 HWND hWndOldModal
= hWndSysModal
;
1107 hWndSysModal
= hWnd
;
1108 dprintf_win(stdnimp
,"EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd
);
1109 return hWndOldModal
;
1113 /*******************************************************************
1114 * GetSysModalWindow [USER.189]
1116 HWND
GetSysModalWindow(void)
1118 return hWndSysModal
;