2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
15 #include "sysmetrics.h"
21 #include "nonclient.h"
24 #include "shm_main_blk.h"
28 /* #define DEBUG_WIN */
29 /* #define DEBUG_MENU */
32 static HWND hwndDesktop
= 0;
33 static HWND hWndSysModal
= 0;
35 /***********************************************************************
38 * Return a pointer to the WND structure corresponding to a HWND.
40 WND
* WIN_FindWndPtr( HWND hwnd
)
44 if (!hwnd
) return NULL
;
45 ptr
= (WND
*) USER_HEAP_LIN_ADDR( hwnd
);
46 if (ptr
->dwMagic
!= WND_MAGIC
) return NULL
;
51 /***********************************************************************
54 * Return the X window associated to a window.
56 Window
WIN_GetXWindow( HWND hwnd
)
58 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
59 while (wndPtr
&& !wndPtr
->window
)
61 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
63 return wndPtr
? wndPtr
->window
: 0;
67 /***********************************************************************
70 * Remove a window from the siblings linked list.
72 BOOL
WIN_UnlinkWindow( HWND hwnd
)
75 WND
*parentPtr
, *wndPtr
;
77 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
78 if (!(parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
))) return FALSE
;
80 curWndPtr
= &parentPtr
->hwndChild
;
82 while (*curWndPtr
!= hwnd
)
84 WND
* curPtr
= WIN_FindWndPtr( *curWndPtr
);
85 curWndPtr
= &curPtr
->hwndNext
;
87 *curWndPtr
= wndPtr
->hwndNext
;
92 /***********************************************************************
95 * Insert a window into the siblings linked list.
96 * The window is inserted after the specified window, which can also
97 * be specified as HWND_TOP or HWND_BOTTOM.
99 BOOL
WIN_LinkWindow( HWND hwnd
, HWND hwndInsertAfter
)
101 HWND
* hwndPtr
= NULL
; /* pointer to hwnd to change */
102 WND
*wndPtr
, *parentPtr
;
104 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
105 if (!(parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
))) return FALSE
;
107 if ((hwndInsertAfter
== HWND_TOP
) || (hwndInsertAfter
== HWND_BOTTOM
))
109 hwndPtr
= &parentPtr
->hwndChild
; /* Point to first sibling hwnd */
110 if (hwndInsertAfter
== HWND_BOTTOM
) /* Find last sibling hwnd */
113 WND
* nextPtr
= WIN_FindWndPtr( *hwndPtr
);
114 hwndPtr
= &nextPtr
->hwndNext
;
117 else /* Normal case */
119 WND
* afterPtr
= WIN_FindWndPtr( hwndInsertAfter
);
120 if (afterPtr
) hwndPtr
= &afterPtr
->hwndNext
;
122 if (!hwndPtr
) return FALSE
;
123 wndPtr
->hwndNext
= *hwndPtr
;
129 /***********************************************************************
130 * WIN_FindWinToRepaint
132 * Find a window that needs repaint.
134 HWND
WIN_FindWinToRepaint( HWND hwnd
)
138 /* Note: the desktop window never gets WM_PAINT messages */
139 if (!hwnd
) hwnd
= GetTopWindow( hwndDesktop
);
140 for ( ; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
142 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
143 dprintf_win( stddeb
, "WIN_FindWinToRepaint: %04x, style %08lx\n",
144 hwnd
, wndPtr
->dwStyle
);
145 if (!(wndPtr
->dwStyle
& WS_VISIBLE
) || (wndPtr
->flags
& WIN_NO_REDRAW
))
147 if ((wndPtr
->dwStyle
& WS_MINIMIZE
) && (WIN_CLASS_INFO(wndPtr
).hIcon
))
149 if (wndPtr
->hrgnUpdate
|| (wndPtr
->flags
& WIN_INTERNAL_PAINT
))
151 if (wndPtr
->hwndChild
)
154 if ((child
= WIN_FindWinToRepaint( wndPtr
->hwndChild
)))
162 /***********************************************************************
163 * WIN_SendParentNotify
165 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
166 * the window has the WS_EX_NOPARENTNOTIFY style.
168 void WIN_SendParentNotify( HWND hwnd
, WORD event
, LONG lParam
)
170 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
172 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
174 if (wndPtr
->dwExStyle
& WS_EX_NOPARENTNOTIFY
) break;
175 SendMessage( wndPtr
->hwndParent
, WM_PARENTNOTIFY
, event
, lParam
);
176 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
182 /***********************************************************************
185 * Destroy storage associated to a window
187 static void WIN_DestroyWindow( HWND hwnd
)
189 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
190 CLASS
*classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
);
194 DDE_DestroyWindow(hwnd
);
195 #endif /* CONFIG_IPC */
197 if (!wndPtr
|| !classPtr
) return;
198 WIN_UnlinkWindow( hwnd
); /* Remove the window from the linked list */
199 wndPtr
->dwMagic
= 0; /* Mark it as invalid */
200 if ((wndPtr
->hrgnUpdate
) || (wndPtr
->flags
& WIN_INTERNAL_PAINT
))
202 if (wndPtr
->hrgnUpdate
) DeleteObject( wndPtr
->hrgnUpdate
);
203 MSG_DecPaintCount( wndPtr
->hmemTaskQ
);
205 if (!(wndPtr
->dwStyle
& WS_CHILD
))
207 if (wndPtr
->wIDmenu
) DestroyMenu( wndPtr
->wIDmenu
);
209 if (wndPtr
->hSysMenu
) DestroyMenu( wndPtr
->hSysMenu
);
210 if (wndPtr
->window
) XDestroyWindow( display
, wndPtr
->window
);
211 if (classPtr
->wc
.style
& CS_OWNDC
) DCE_FreeDCE( wndPtr
->hdce
);
212 classPtr
->cWindows
--;
213 USER_HEAP_FREE( hwnd
);
217 /***********************************************************************
218 * WIN_CreateDesktopWindow
220 * Create the desktop window.
222 BOOL
WIN_CreateDesktopWindow(void)
229 if (!(hclass
= CLASS_FindClassByName( DESKTOP_CLASS_ATOM
, 0, &classPtr
)))
232 hwndDesktop
= USER_HEAP_ALLOC( sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
233 if (!hwndDesktop
) return FALSE
;
234 wndPtr
= (WND
*) USER_HEAP_LIN_ADDR( hwndDesktop
);
236 wndPtr
->hwndNext
= 0;
237 wndPtr
->hwndChild
= 0;
238 wndPtr
->dwMagic
= WND_MAGIC
;
239 wndPtr
->hwndParent
= 0;
240 wndPtr
->hwndOwner
= 0;
241 wndPtr
->hClass
= hclass
;
242 wndPtr
->hInstance
= 0;
243 wndPtr
->rectWindow
.left
= 0;
244 wndPtr
->rectWindow
.top
= 0;
245 wndPtr
->rectWindow
.right
= SYSMETRICS_CXSCREEN
;
246 wndPtr
->rectWindow
.bottom
= SYSMETRICS_CYSCREEN
;
247 wndPtr
->rectClient
= wndPtr
->rectWindow
;
248 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
249 wndPtr
->ptIconPos
.x
= -1;
250 wndPtr
->ptIconPos
.y
= -1;
251 wndPtr
->ptMaxPos
.x
= -1;
252 wndPtr
->ptMaxPos
.y
= -1;
253 wndPtr
->hmemTaskQ
= 0; /* Desktop does not belong to a task */
254 wndPtr
->hrgnUpdate
= 0;
255 wndPtr
->hwndLastActive
= hwndDesktop
;
256 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
257 wndPtr
->dwStyle
= WS_VISIBLE
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
;
258 wndPtr
->dwExStyle
= 0;
260 wndPtr
->hVScroll
= 0;
261 wndPtr
->hHScroll
= 0;
265 wndPtr
->window
= rootWindow
;
266 wndPtr
->hSysMenu
= 0;
268 EVENT_RegisterWindow( wndPtr
->window
, hwndDesktop
);
269 SendMessage( hwndDesktop
, WM_NCCREATE
, 0, 0 );
270 if ((hdc
= GetDC( hwndDesktop
)) != 0)
272 SendMessage( hwndDesktop
, WM_ERASEBKGND
, hdc
, 0 );
273 ReleaseDC( hwndDesktop
, hdc
);
279 /***********************************************************************
280 * CreateWindow (USER.41)
282 HWND
CreateWindow( SEGPTR className
, SEGPTR windowName
,
283 DWORD style
, short x
, short y
, short width
, short height
,
284 HWND parent
, HMENU menu
, HANDLE instance
, SEGPTR data
)
286 return CreateWindowEx( 0, className
, windowName
, style
,
287 x
, y
, width
, height
, parent
, menu
, instance
, data
);
291 /***********************************************************************
292 * CreateWindowEx (USER.452)
294 HWND
CreateWindowEx( DWORD exStyle
, SEGPTR className
, SEGPTR windowName
,
295 DWORD style
, short x
, short y
, short width
, short height
,
296 HWND parent
, HMENU menu
, HANDLE instance
, SEGPTR data
)
301 POINT maxSize
, maxPos
, minTrack
, maxTrack
;
302 CREATESTRUCT createStruct
;
304 XSetWindowAttributes win_attr
;
306 /* FIXME: windowName and className should be SEGPTRs */
308 dprintf_win( stddeb
, "CreateWindowEx: " );
309 if (HIWORD(windowName
))
310 dprintf_win( stddeb
, "'%s' ", (char *)PTR_SEG_TO_LIN(windowName
) );
312 dprintf_win( stddeb
, "%04x ", LOWORD(windowName
) );
313 if (HIWORD(className
))
314 dprintf_win( stddeb
, "'%s' ", (char *)PTR_SEG_TO_LIN(className
) );
316 dprintf_win( stddeb
, "%04x ", LOWORD(className
) );
318 dprintf_win(stddeb
, "%08lx %08lx %d,%d %dx%d %04x %04x %04x %08lx\n",
319 exStyle
, style
, x
, y
, width
, height
,
320 parent
, menu
, instance
, data
);
322 if (x
== CW_USEDEFAULT
) x
= y
= 0;
323 if (width
== CW_USEDEFAULT
)
329 /* Find the parent and class */
333 /* Make sure parent is valid */
334 if (!IsWindow( parent
)) {
335 dprintf_win(stddeb
,"CreateWindowEx: Parent %x is not a window\n", parent
);
341 if (style
& WS_CHILD
) {
342 dprintf_win(stddeb
,"CreateWindowEx: no parent\n");
343 return 0; /* WS_CHILD needs a parent */
347 if (!(class = CLASS_FindClassByName( className
, GetExePtr(instance
),
350 fprintf(stderr
,"CreateWindow BAD CLASSNAME " );
351 if (HIWORD(className
)) fprintf( stderr
, "'%s'\n",
352 (char *)PTR_SEG_TO_LIN(className
) );
353 else fprintf( stderr
, "%04x\n", LOWORD(className
) );
357 /* Correct the window style */
359 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
360 style
|= WS_CAPTION
| WS_CLIPSIBLINGS
;
361 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
363 /* Create the window structure */
365 hwnd
= USER_HEAP_ALLOC( sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
367 dprintf_win(stddeb
,"CreateWindowEx: Out of memory\n");
371 /* Fill the structure */
373 wndPtr
= (WND
*) USER_HEAP_LIN_ADDR( hwnd
);
374 wndPtr
->hwndNext
= 0;
375 wndPtr
->hwndChild
= 0;
377 wndPtr
->dwMagic
= WND_MAGIC
;
378 wndPtr
->hwndParent
= (style
& WS_CHILD
) ? parent
: hwndDesktop
;
379 wndPtr
->hwndOwner
= (style
& WS_CHILD
) ? 0 : WIN_GetTopParent(parent
);
380 wndPtr
->hClass
= class;
381 wndPtr
->hInstance
= instance
;
382 wndPtr
->ptIconPos
.x
= -1;
383 wndPtr
->ptIconPos
.y
= -1;
384 wndPtr
->ptMaxPos
.x
= -1;
385 wndPtr
->ptMaxPos
.y
= -1;
386 wndPtr
->hmemTaskQ
= GetTaskQueue(0);
387 wndPtr
->hrgnUpdate
= 0;
388 wndPtr
->hwndPrevActive
= 0;
389 wndPtr
->hwndLastActive
= hwnd
;
390 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
391 wndPtr
->dwStyle
= style
& ~WS_VISIBLE
;
392 wndPtr
->dwExStyle
= exStyle
;
396 wndPtr
->hVScroll
= 0;
397 wndPtr
->hHScroll
= 0;
398 wndPtr
->hSysMenu
= 0;
401 if (classPtr
->wc
.cbWndExtra
)
402 memset( wndPtr
->wExtra
, 0, classPtr
->wc
.cbWndExtra
);
403 classPtr
->cWindows
++;
405 /* Get class or window DC if needed */
407 if (classPtr
->wc
.style
& CS_OWNDC
)
408 wndPtr
->hdce
= DCE_AllocDCE( DCE_WINDOW_DC
);
409 else if (classPtr
->wc
.style
& CS_CLASSDC
)
410 wndPtr
->hdce
= classPtr
->hdce
;
414 /* Insert the window in the linked list */
416 WIN_LinkWindow( hwnd
, HWND_TOP
);
418 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
420 NC_GetMinMaxInfo( hwnd
, &maxSize
, &maxPos
, &minTrack
, &maxTrack
);
422 if (maxSize
.x
< width
) width
= maxSize
.x
;
423 if (maxSize
.y
< height
) height
= maxSize
.y
;
424 if (width
<= 0) width
= 1;
425 if (height
<= 0) height
= 1;
427 wndPtr
->rectWindow
.left
= x
;
428 wndPtr
->rectWindow
.top
= y
;
429 wndPtr
->rectWindow
.right
= x
+ width
;
430 wndPtr
->rectWindow
.bottom
= y
+ height
;
431 wndPtr
->rectClient
= wndPtr
->rectWindow
;
432 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
434 /* Create the X window (only for top-level windows, and then only */
435 /* when there's no desktop window) */
437 if (!(style
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
440 HCURSOR hCursor
= classPtr
->wc
.hCursor
;
441 if (!hCursor
) hCursor
= LoadCursor( 0, IDC_ARROW
);
442 cursor
= (CURSORALLOC
*) GlobalLock(hCursor
);
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
= cursor
? cursor
->xcursor
: None
;
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
);
460 GlobalUnlock( hCursor
);
463 if ((style
& WS_CAPTION
) && !(style
& WS_CHILD
))
465 if (menu
) SetMenu(hwnd
, menu
);
466 else if (classPtr
->wc
.lpszMenuName
)
467 SetMenu( hwnd
, LoadMenu( instance
, classPtr
->wc
.lpszMenuName
) );
469 else wndPtr
->wIDmenu
= menu
;
471 /* Send the WM_CREATE message */
473 createStruct
.lpCreateParams
= (LPSTR
)data
;
474 createStruct
.hInstance
= instance
;
475 createStruct
.hMenu
= menu
;
476 createStruct
.hwndParent
= parent
;
477 createStruct
.cx
= width
;
478 createStruct
.cy
= height
;
481 createStruct
.style
= style
;
482 createStruct
.lpszName
= windowName
;
483 createStruct
.lpszClass
= className
;
484 createStruct
.dwExStyle
= 0;
486 wmcreate
= SendMessage( hwnd
, WM_NCCREATE
, 0, MAKE_SEGPTR(&createStruct
) );
489 dprintf_win(stddeb
,"CreateWindowEx: WM_NCCREATE return 0\n");
494 WINPOS_SendNCCalcSize( hwnd
, FALSE
, &wndPtr
->rectWindow
,
495 NULL
, NULL
, NULL
, &wndPtr
->rectClient
);
496 wmcreate
= SendMessage(hwnd
, WM_CREATE
, 0, MAKE_SEGPTR(&createStruct
));
501 /* Abort window creation */
502 dprintf_win(stddeb
,"CreateWindowEx: wmcreate==-1, aborting\n");
503 WIN_DestroyWindow( hwnd
);
507 /* Create a copy of SysMenu */
508 if (style
& WS_SYSMENU
) wndPtr
->hSysMenu
= CopySysMenu();
510 WIN_SendParentNotify( hwnd
, WM_CREATE
, MAKELONG( hwnd
, wndPtr
->wIDmenu
) );
512 /* Show the window, maximizing or minimizing if needed */
514 if (wndPtr
->dwStyle
& WS_MINIMIZE
)
516 wndPtr
->dwStyle
&= ~WS_MAXIMIZE
;
517 WINPOS_FindIconPos( hwnd
);
518 SetWindowPos( hwnd
, 0, wndPtr
->ptIconPos
.x
, wndPtr
->ptIconPos
.y
,
519 SYSMETRICS_CXICON
, SYSMETRICS_CYICON
,
521 (style
& WS_VISIBLE
) ? SWP_SHOWWINDOW
: 0 );
523 else if (wndPtr
->dwStyle
& WS_MAXIMIZE
)
525 SetWindowPos( hwnd
, 0, maxPos
.x
, maxPos
.y
, maxSize
.x
, maxSize
.y
,
527 (style
& WS_VISIBLE
) ? SWP_SHOWWINDOW
: 0 );
529 else if (style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
531 dprintf_win(stddeb
, "CreateWindowEx: return %04X \n", hwnd
);
536 /***********************************************************************
537 * DestroyWindow (USER.53)
539 BOOL
DestroyWindow( HWND hwnd
)
544 dprintf_win(stddeb
, "DestroyWindow (%04x)\n", hwnd
);
548 if (hwnd
== hwndDesktop
) return FALSE
; /* Can't destroy desktop */
549 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
550 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return FALSE
;
552 /* Hide the window */
554 if (wndPtr
->dwStyle
& WS_VISIBLE
)
555 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, SWP_HIDEWINDOW
| SWP_NOACTIVATE
|
556 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOSIZE
);
557 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
559 WIN_SendParentNotify( hwnd
, WM_DESTROY
, MAKELONG(hwnd
, wndPtr
->wIDmenu
) );
561 /* Recursively destroy owned windows */
565 HWND hwndSibling
= GetWindow( hwnd
, GW_HWNDFIRST
);
568 WND
*siblingPtr
= WIN_FindWndPtr( hwndSibling
);
569 if (siblingPtr
->hwndOwner
== hwnd
) break;
570 hwndSibling
= siblingPtr
->hwndNext
;
572 if (hwndSibling
) DestroyWindow( hwndSibling
);
576 /* Send destroy messages and destroy children */
578 SendMessage( hwnd
, WM_DESTROY
, 0, 0 );
579 while (wndPtr
->hwndChild
) /* The child removes itself from the list */
580 DestroyWindow( wndPtr
->hwndChild
);
581 SendMessage( hwnd
, WM_NCDESTROY
, 0, 0 );
583 /* Destroy the window */
585 WIN_DestroyWindow( hwnd
);
590 /***********************************************************************
591 * CloseWindow (USER.43)
593 void CloseWindow(HWND hWnd
)
595 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
596 if (wndPtr
->dwStyle
& WS_CHILD
) return;
597 ShowWindow(hWnd
, SW_MINIMIZE
);
601 /***********************************************************************
604 BOOL
OpenIcon(HWND hWnd
)
606 if (!IsIconic(hWnd
)) return FALSE
;
607 ShowWindow(hWnd
, SW_SHOWNORMAL
);
612 /***********************************************************************
613 * FindWindow (USER.50)
615 HWND
FindWindow( SEGPTR ClassMatch
, LPSTR TitleMatch
)
623 hclass
= CLASS_FindClassByName( ClassMatch
, 0xffff, &classPtr
);
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
;
711 case GWW_HWNDPARENT
: return wndPtr
->hwndParent
;
712 case GWW_HINSTANCE
: return wndPtr
->hInstance
;
718 /**********************************************************************
719 * SetWindowWord (USER.134)
721 WORD
SetWindowWord( HWND hwnd
, short offset
, WORD newval
)
724 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
725 if (!wndPtr
) return 0;
726 if (offset
>= 0) ptr
= (WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
729 case GWW_ID
: ptr
= &wndPtr
->wIDmenu
; break;
730 case GWW_HINSTANCE
: ptr
= &wndPtr
->hInstance
; break;
739 /**********************************************************************
740 * GetWindowLong (USER.135)
742 LONG
GetWindowLong( HWND hwnd
, short offset
)
744 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
745 if (!wndPtr
) return 0;
746 if (offset
>= 0) return *(LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
749 case GWL_STYLE
: return wndPtr
->dwStyle
;
750 case GWL_EXSTYLE
: return wndPtr
->dwExStyle
;
751 case GWL_WNDPROC
: return (LONG
)wndPtr
->lpfnWndProc
;
757 /**********************************************************************
758 * SetWindowLong (USER.136)
760 LONG
SetWindowLong( HWND hwnd
, short offset
, LONG newval
)
763 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
764 if (!wndPtr
) return 0;
765 if (offset
>= 0) ptr
= (LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
768 case GWL_STYLE
: ptr
= &wndPtr
->dwStyle
; break;
769 case GWL_EXSTYLE
: ptr
= &wndPtr
->dwExStyle
; break;
770 case GWL_WNDPROC
: ptr
= (LONG
*)&wndPtr
->lpfnWndProc
; break;
779 /*******************************************************************
780 * GetWindowText (USER.36)
782 int WIN16_GetWindowText( HWND hwnd
, SEGPTR lpString
, int nMaxCount
)
784 return (int)SendMessage(hwnd
, WM_GETTEXT
, (WORD
)nMaxCount
,
788 int GetWindowText( HWND hwnd
, LPSTR lpString
, int nMaxCount
)
793 /* We have to allocate a buffer on the USER heap */
794 /* to be able to pass its address to 16-bit code */
795 if (!(handle
= USER_HEAP_ALLOC( nMaxCount
))) return 0;
796 len
= (int)SendMessage( hwnd
, WM_GETTEXT
, (WORD
)nMaxCount
,
797 USER_HEAP_SEG_ADDR(handle
) );
798 strncpy( lpString
, USER_HEAP_LIN_ADDR(handle
), nMaxCount
);
799 USER_HEAP_FREE( handle
);
804 /*******************************************************************
805 * SetWindowText (USER.37)
807 void WIN16_SetWindowText( HWND hwnd
, SEGPTR lpString
)
809 SendMessage( hwnd
, WM_SETTEXT
, 0, (DWORD
)lpString
);
812 void SetWindowText( HWND hwnd
, LPSTR lpString
)
816 /* We have to allocate a buffer on the USER heap */
817 /* to be able to pass its address to 16-bit code */
818 if (!(handle
= USER_HEAP_ALLOC( strlen(lpString
)+1 ))) return;
819 strcpy( USER_HEAP_LIN_ADDR(handle
), lpString
);
820 SendMessage( hwnd
, WM_SETTEXT
, 0, USER_HEAP_SEG_ADDR(handle
) );
821 USER_HEAP_FREE( handle
);
825 /*******************************************************************
826 * GetWindowTextLength (USER.38)
828 int GetWindowTextLength(HWND hwnd
)
830 return (int)SendMessage(hwnd
, WM_GETTEXTLENGTH
, 0, 0 );
834 /*******************************************************************
837 BOOL
IsWindow( HWND hwnd
)
839 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
840 return ((wndPtr
!= NULL
) && (wndPtr
->dwMagic
== WND_MAGIC
));
844 /*****************************************************************
845 * GetParent (USER.46)
847 HWND
GetParent(HWND hwnd
)
849 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
850 if (!wndPtr
) return 0;
851 return (wndPtr
->dwStyle
& WS_CHILD
) ?
852 wndPtr
->hwndParent
: wndPtr
->hwndOwner
;
856 /*****************************************************************
859 * Get the top-level parent for a child window.
861 HWND
WIN_GetTopParent( HWND hwnd
)
865 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
866 if (wndPtr
->dwStyle
& WS_CHILD
) hwnd
= wndPtr
->hwndParent
;
873 /*****************************************************************
874 * SetParent (USER.233)
876 HWND
SetParent(HWND hwndChild
, HWND hwndNewParent
)
880 WND
*wndPtr
= WIN_FindWndPtr(hwndChild
);
881 if (!wndPtr
|| !(wndPtr
->dwStyle
& WS_CHILD
)) return 0;
883 temp
= wndPtr
->hwndParent
;
885 WIN_UnlinkWindow(hwndChild
);
887 wndPtr
->hwndParent
= hwndNewParent
;
889 wndPtr
->hwndParent
= GetDesktopWindow();
890 WIN_LinkWindow(hwndChild
, HWND_BOTTOM
);
892 if (IsWindowVisible(hwndChild
)) UpdateWindow(hwndChild
);
899 /*******************************************************************
902 BOOL
IsChild( HWND parent
, HWND child
)
904 WND
* wndPtr
= WIN_FindWndPtr( child
);
905 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
907 if (wndPtr
->hwndParent
== parent
) return TRUE
;
908 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
914 /***********************************************************************
915 * IsWindowVisible (USER.49)
917 BOOL
IsWindowVisible( HWND hwnd
)
919 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
920 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
922 if (!(wndPtr
->dwStyle
& WS_VISIBLE
)) return FALSE
;
923 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
925 return (wndPtr
&& (wndPtr
->dwStyle
& WS_VISIBLE
));
930 /*******************************************************************
931 * GetTopWindow (USER.229)
933 HWND
GetTopWindow( HWND hwnd
)
935 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
936 if (wndPtr
) return wndPtr
->hwndChild
;
941 /*******************************************************************
942 * GetWindow (USER.262)
944 HWND
GetWindow( HWND hwnd
, WORD rel
)
946 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
947 if (!wndPtr
) return 0;
951 if (wndPtr
->hwndParent
)
953 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
954 return parentPtr
->hwndChild
;
959 if (!wndPtr
->hwndParent
) return 0; /* Desktop window */
960 while (wndPtr
->hwndNext
)
962 hwnd
= wndPtr
->hwndNext
;
963 wndPtr
= WIN_FindWndPtr( hwnd
);
968 return wndPtr
->hwndNext
;
974 if (wndPtr
->hwndParent
)
976 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
977 hwndPrev
= parentPtr
->hwndChild
;
979 else return 0; /* Desktop window */
980 if (hwndPrev
== hwnd
) return 0;
983 wndPtr
= WIN_FindWndPtr( hwndPrev
);
984 if (wndPtr
->hwndNext
== hwnd
) break;
985 hwndPrev
= wndPtr
->hwndNext
;
991 return wndPtr
->hwndOwner
;
994 return wndPtr
->hwndChild
;
1000 /*******************************************************************
1001 * GetNextWindow (USER.230)
1003 HWND
GetNextWindow( HWND hwnd
, WORD flag
)
1005 if ((flag
!= GW_HWNDNEXT
) && (flag
!= GW_HWNDPREV
)) return 0;
1006 return GetWindow( hwnd
, flag
);
1009 /*******************************************************************
1010 * ShowOwnedPopups (USER.265)
1012 void ShowOwnedPopups( HWND owner
, BOOL fShow
)
1014 HWND hwnd
= GetWindow( hwndDesktop
, GW_CHILD
);
1017 WND
*wnd
= WIN_FindWndPtr(hwnd
);
1018 if (wnd
->hwndOwner
== owner
&& (wnd
->dwStyle
& WS_POPUP
))
1019 ShowWindow( hwnd
, fShow
? SW_SHOW
: SW_HIDE
);
1020 hwnd
= wnd
->hwndNext
;
1025 /*******************************************************************
1026 * GetLastActivePopup (USER.287)
1028 HWND
GetLastActivePopup(HWND hwnd
)
1031 wndPtr
= WIN_FindWndPtr(hwnd
);
1032 if (wndPtr
== NULL
) return hwnd
;
1033 return wndPtr
->hwndLastActive
;
1037 /*******************************************************************
1038 * EnumWindows (USER.54)
1040 BOOL
EnumWindows( FARPROC lpEnumFunc
, LPARAM lParam
)
1047 /* We have to build a list of all windows first, to avoid */
1048 /* unpleasant side-effects, for instance if the callback */
1049 /* function changes the Z-order of the windows. */
1051 /* First count the windows */
1054 for (hwnd
= GetTopWindow(hwndDesktop
); hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1056 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
1059 if (!count
) return TRUE
;
1061 /* Now build the list of all windows */
1063 if (!(list
= (HWND
*)malloc( sizeof(HWND
) * count
))) return FALSE
;
1064 for (hwnd
= GetTopWindow(hwndDesktop
), pWnd
= list
; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1066 wndPtr
= WIN_FindWndPtr( hwnd
);
1070 /* Now call the callback function for every window */
1072 for (pWnd
= list
; count
> 0; count
--, pWnd
++)
1074 /* Make sure that window still exists */
1075 if (!IsWindow(*pWnd
)) continue;
1076 if (!CallEnumWindowsProc( lpEnumFunc
, *pWnd
, lParam
)) break;
1083 /**********************************************************************
1084 * EnumTaskWindows (USER.225)
1086 BOOL
EnumTaskWindows( HTASK hTask
, FARPROC lpEnumFunc
, LONG lParam
)
1091 HANDLE hQueue
= GetTaskQueue( hTask
);
1094 /* This function is the same as EnumWindows(), */
1095 /* except for an added check on the window queue. */
1097 /* First count the windows */
1100 for (hwnd
= GetTopWindow(hwndDesktop
); hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1102 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
1103 if (wndPtr
->hmemTaskQ
== hQueue
) count
++;
1105 if (!count
) return TRUE
;
1107 /* Now build the list of all windows */
1109 if (!(list
= (HWND
*)malloc( sizeof(HWND
) * count
))) return FALSE
;
1110 for (hwnd
= GetTopWindow(hwndDesktop
), pWnd
= list
; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
1112 wndPtr
= WIN_FindWndPtr( hwnd
);
1113 if (wndPtr
->hmemTaskQ
== hQueue
) *pWnd
++ = hwnd
;
1116 /* Now call the callback function for every window */
1118 for (pWnd
= list
; count
> 0; count
--, pWnd
++)
1120 /* Make sure that window still exists */
1121 if (!IsWindow(*pWnd
)) continue;
1122 if (!CallEnumTaskWndProc( lpEnumFunc
, *pWnd
, lParam
)) break;
1129 /*******************************************************************
1132 * o hwnd is the first child to use, loop until all next windows
1137 * o call ourselves with the next child window
1140 static BOOL
WIN_EnumChildWin(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1146 if (!(wndPtr
=WIN_FindWndPtr(hwnd
))) return 0;
1147 if (!CallEnumWindowsProc( wndenumprc
, hwnd
, lParam
)) return 0;
1148 if (!WIN_EnumChildWin(wndPtr
->hwndChild
, wndenumprc
, lParam
)) return 0;
1149 hwnd
=wndPtr
->hwndNext
;
1154 /*******************************************************************
1155 * EnumChildWindows (USER.55)
1157 * o gets the first child of hwnd
1159 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1161 BOOL
EnumChildWindows(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1165 dprintf_enum(stddeb
,"EnumChildWindows\n");
1167 if (hwnd
== 0) return 0;
1168 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1169 hwnd
= wndPtr
->hwndChild
;
1170 return WIN_EnumChildWin(hwnd
, wndenumprc
, lParam
);
1174 /*******************************************************************
1175 * AnyPopup [USER.52]
1179 dprintf_win(stdnimp
,"EMPTY STUB !! AnyPopup !\n");
1183 /*******************************************************************
1184 * FlashWindow [USER.105]
1186 BOOL
FlashWindow(HWND hWnd
, BOOL bInvert
)
1188 dprintf_win(stdnimp
,"EMPTY STUB !! FlashWindow !\n");
1193 /*******************************************************************
1194 * SetSysModalWindow [USER.188]
1196 HWND
SetSysModalWindow(HWND hWnd
)
1198 HWND hWndOldModal
= hWndSysModal
;
1199 hWndSysModal
= hWnd
;
1200 dprintf_win(stdnimp
,"EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd
);
1201 return hWndOldModal
;
1205 /*******************************************************************
1206 * GetSysModalWindow [USER.189]
1208 HWND
GetSysModalWindow(void)
1210 return hWndSysModal
;