2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
15 #include "sysmetrics.h"
25 /* #define DEBUG_WIN */
26 /* #define DEBUG_MENU */
29 static HWND hwndDesktop
= 0;
30 static HWND hWndSysModal
= 0;
32 /***********************************************************************
35 * Return a pointer to the WND structure corresponding to a HWND.
37 WND
* WIN_FindWndPtr( HWND hwnd
)
41 if (!hwnd
) return NULL
;
42 ptr
= (WND
*) USER_HEAP_ADDR( hwnd
);
43 if (IsBadReadPtr(ptr
, sizeof *ptr
)) return NULL
;
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( GMEM_MOVEABLE
,
223 sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
224 if (!hwndDesktop
) return FALSE
;
225 wndPtr
= (WND
*) USER_HEAP_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;
261 /* Send dummy WM_NCCREATE message */
262 SendMessage( hwndDesktop
, WM_NCCREATE
, 0, 0 );
263 EVENT_RegisterWindow( wndPtr
->window
, hwndDesktop
);
264 RedrawWindow( hwndDesktop
, NULL
, 0,
265 RDW_INVALIDATE
| RDW_ERASE
| RDW_ERASENOW
);
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
, LPSTR 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
, LPSTR data
)
292 POINT maxSize
, maxPos
, minTrack
, maxTrack
;
293 CREATESTRUCT
*createStruct
;
294 HANDLE hcreateStruct
;
296 XSetWindowAttributes win_attr
;
298 dprintf_win(stddeb
, "CreateWindowEx: %08lX '%s' '%s' %08lX %d,%d %dx%d %04X %04X %04X %p\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
)) return 0;
324 else if (style
& WS_CHILD
) return 0; /* WS_CHILD needs a parent */
326 if (!(class = CLASS_FindClassByName( className
, instance
, &classPtr
))) {
327 fprintf(stderr
,"CreateWindow BAD CLASSNAME '%s' !\n", className
);
331 /* Correct the window style */
333 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
334 style
|= WS_CAPTION
| WS_CLIPSIBLINGS
;
335 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
337 /* Create the window structure */
339 hwnd
= USER_HEAP_ALLOC(GMEM_MOVEABLE
, sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
342 /* Fill the structure */
344 wndPtr
= (WND
*) USER_HEAP_ADDR( hwnd
);
345 wndPtr
->hwndNext
= 0;
346 wndPtr
->hwndChild
= 0;
348 wndPtr
->dwMagic
= WND_MAGIC
;
349 wndPtr
->hwndParent
= (style
& WS_CHILD
) ? parent
: hwndDesktop
;
350 wndPtr
->hwndOwner
= (style
& WS_CHILD
) ? 0 : parent
;
351 wndPtr
->hClass
= class;
352 wndPtr
->hInstance
= instance
;
353 wndPtr
->rectWindow
.left
= x
;
354 wndPtr
->rectWindow
.top
= y
;
355 wndPtr
->rectWindow
.right
= x
+ width
;
356 wndPtr
->rectWindow
.bottom
= y
+ height
;
357 wndPtr
->rectClient
= wndPtr
->rectWindow
;
358 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
359 wndPtr
->ptIconPos
.x
= -1;
360 wndPtr
->ptIconPos
.y
= -1;
361 wndPtr
->ptMaxPos
.x
= -1;
362 wndPtr
->ptMaxPos
.y
= -1;
363 wndPtr
->hmemTaskQ
= GetTaskQueue(0);
364 wndPtr
->hrgnUpdate
= 0;
365 wndPtr
->hwndPrevActive
= 0;
366 wndPtr
->hwndLastActive
= hwnd
;
367 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
368 wndPtr
->dwStyle
= style
;
369 wndPtr
->dwExStyle
= exStyle
;
373 wndPtr
->hVScroll
= 0;
374 wndPtr
->hHScroll
= 0;
375 wndPtr
->hSysMenu
= 0;
379 if (classPtr
->wc
.cbWndExtra
)
380 memset( wndPtr
->wExtra
, 0, classPtr
->wc
.cbWndExtra
);
381 classPtr
->cWindows
++;
383 /* Make sure owner is a top-level window */
385 while (wndPtr
->hwndOwner
&& GetParent(wndPtr
->hwndOwner
))
386 wndPtr
->hwndOwner
= GetParent(wndPtr
->hwndOwner
);
388 /* Get class or window DC if needed */
390 if (classPtr
->wc
.style
& CS_OWNDC
)
391 wndPtr
->hdce
= DCE_AllocDCE( DCE_WINDOW_DC
);
392 else if (classPtr
->wc
.style
& CS_CLASSDC
)
393 wndPtr
->hdce
= classPtr
->hdce
;
397 /* Insert the window in the linked list */
399 WIN_LinkWindow( hwnd
, HWND_TOP
);
401 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
403 NC_GetMinMaxInfo( hwnd
, &maxSize
, &maxPos
, &minTrack
, &maxTrack
);
405 if ( maxSize
.x
< width
)
408 wndPtr
->rectWindow
.right
= x
+ width
;
410 if ( maxSize
.y
< height
)
413 wndPtr
->rectWindow
.bottom
= y
+ height
;
416 /* Create the X window (only for top-level windows, and then only */
417 /* when there's no desktop window) */
419 if (!(style
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
422 HCURSOR hCursor
= classPtr
->wc
.hCursor
;
423 if (!hCursor
) hCursor
= LoadCursor( 0, IDC_ARROW
);
424 cursor
= (CURSORALLOC
*) GlobalLock(hCursor
);
426 win_attr
.event_mask
= ExposureMask
| KeyPressMask
| KeyReleaseMask
|
427 PointerMotionMask
| ButtonPressMask
|
428 ButtonReleaseMask
| FocusChangeMask
;
429 win_attr
.override_redirect
= TRUE
;
430 win_attr
.colormap
= COLOR_WinColormap
;
431 win_attr
.backing_store
= Options
.backingstore
? WhenMapped
: NotUseful
;
432 win_attr
.save_under
= ((classPtr
->wc
.style
& CS_SAVEBITS
) != 0);
433 win_attr
.cursor
= cursor
? cursor
->xcursor
: None
;
434 wndPtr
->window
= XCreateWindow( display
, rootWindow
, x
, y
,
435 width
, height
, 0, CopyFromParent
,
436 InputOutput
, CopyFromParent
,
437 CWEventMask
| CWOverrideRedirect
|
438 CWColormap
| CWCursor
| CWSaveUnder
|
439 CWBackingStore
, &win_attr
);
440 XStoreName( display
, wndPtr
->window
, windowName
);
441 EVENT_RegisterWindow( wndPtr
->window
, hwnd
);
442 GlobalUnlock( hCursor
);
445 dprintf_menu(stddeb
,"CreateWindowEx // menu=%04X instance=%04X classmenu=%p !\n",
446 menu
, instance
, classPtr
->wc
.lpszMenuName
);
448 if ((style
& WS_CAPTION
) && (style
& WS_CHILD
) == 0) {
452 if (classPtr
->wc
.lpszMenuName
!= NULL
)
453 SetMenu(hwnd
, LoadMenu(instance
, classPtr
->wc
.lpszMenuName
));
457 wndPtr
->wIDmenu
= menu
;
459 /* Send the WM_CREATE message */
461 hcreateStruct
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, sizeof(CREATESTRUCT
) );
462 createStruct
= (CREATESTRUCT
*) USER_HEAP_ADDR( hcreateStruct
);
463 createStruct
->lpCreateParams
= data
;
464 createStruct
->hInstance
= instance
;
465 createStruct
->hMenu
= menu
;
466 createStruct
->hwndParent
= parent
;
467 createStruct
->cx
= width
;
468 createStruct
->cy
= height
;
471 createStruct
->style
= style
;
472 createStruct
->lpszName
= windowName
;
473 createStruct
->lpszClass
= className
;
474 createStruct
->dwExStyle
= 0;
476 wmcreate
= SendMessage( hwnd
, WM_NCCREATE
, 0, (LONG
)createStruct
);
477 if (!wmcreate
) wmcreate
= -1;
480 WINPOS_SendNCCalcSize( hwnd
, FALSE
, &wndPtr
->rectWindow
,
481 NULL
, NULL
, NULL
, &wndPtr
->rectClient
);
482 wmcreate
= SendMessage( hwnd
, WM_CREATE
, 0, (LONG
)createStruct
);
485 USER_HEAP_FREE( hcreateStruct
);
489 /* Abort window creation */
490 WIN_DestroyWindow( hwnd
);
494 /* Create a copy of SysMenu */
495 if (style
& WS_SYSMENU
) wndPtr
->hSysMenu
= CopySysMenu();
497 /* Register window in current task windows list */
498 AddWindowToTask(GetCurrentTask(), hwnd
);
500 WIN_SendParentNotify( hwnd
, WM_CREATE
, MAKELONG( hwnd
, wndPtr
->wIDmenu
) );
502 if (style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
503 /* if (style & WS_MINIMIZE) ShowWindow( hwnd, SW_MINIMIZE ); */
505 dprintf_win(stddeb
, "CreateWindowEx: return %04X \n", hwnd
);
510 /***********************************************************************
511 * DestroyWindow (USER.53)
513 BOOL
DestroyWindow( HWND hwnd
)
518 dprintf_win(stddeb
, "DestroyWindow (%04x)\n", hwnd
);
522 if (hwnd
== hwndDesktop
) return FALSE
; /* Can't destroy desktop */
523 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
524 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return FALSE
;
526 /* Hide the window */
528 if (wndPtr
->dwStyle
& WS_VISIBLE
)
529 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, SWP_HIDEWINDOW
| SWP_NOACTIVATE
|
530 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOSIZE
);
531 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
533 WIN_SendParentNotify( hwnd
, WM_DESTROY
, MAKELONG(hwnd
, wndPtr
->wIDmenu
) );
535 /* Recursively destroy owned windows */
539 HWND hwndSibling
= GetWindow( hwnd
, GW_HWNDFIRST
);
542 WND
*siblingPtr
= WIN_FindWndPtr( hwndSibling
);
543 if (siblingPtr
->hwndOwner
== hwnd
) break;
544 hwndSibling
= siblingPtr
->hwndNext
;
546 if (hwndSibling
) DestroyWindow( hwndSibling
);
550 /* Send destroy messages and destroy children */
552 SendMessage( hwnd
, WM_DESTROY
, 0, 0 );
553 while (wndPtr
->hwndChild
) /* The child removes itself from the list */
554 DestroyWindow( wndPtr
->hwndChild
);
555 SendMessage( hwnd
, WM_NCDESTROY
, 0, 0 );
557 /* Remove the window from current task windows list */
558 RemoveWindowFromTask(GetCurrentTask(), hwnd
);
560 /* Destroy the window */
562 WIN_DestroyWindow( hwnd
);
567 /***********************************************************************
568 * CloseWindow (USER.43)
570 void CloseWindow(HWND hWnd
)
572 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
573 if (wndPtr
->dwStyle
& WS_CHILD
) return;
574 ShowWindow(hWnd
, SW_MINIMIZE
);
578 /***********************************************************************
581 BOOL
OpenIcon(HWND hWnd
)
583 if (!IsIconic(hWnd
)) return FALSE
;
584 ShowWindow(hWnd
, SW_SHOWNORMAL
);
589 /***********************************************************************
590 * FindWindow (USER.50)
592 HWND
FindWindow(LPSTR ClassMatch
, LPSTR TitleMatch
)
600 hclass
= CLASS_FindClassByName( ClassMatch
, 0xffff, &classPtr
);
601 if (!hclass
) return 0;
605 hwnd
= GetTopWindow( hwndDesktop
);
608 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
609 if (!hclass
|| (wndPtr
->hClass
== hclass
))
611 /* Found matching class */
612 if (!TitleMatch
) return hwnd
;
615 char *textPtr
= (char *) USER_HEAP_ADDR( wndPtr
->hText
);
616 if (!strcmp( textPtr
, TitleMatch
)) return hwnd
;
619 hwnd
= wndPtr
->hwndNext
;
625 /**********************************************************************
626 * GetDesktopWindow (USER.286)
627 * GetDeskTopHwnd (USER.278)
629 HWND
GetDesktopWindow(void)
635 /*******************************************************************
636 * EnableWindow (USER.34)
638 BOOL
EnableWindow( HWND hwnd
, BOOL enable
)
642 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
643 if (enable
&& (wndPtr
->dwStyle
& WS_DISABLED
))
646 wndPtr
->dwStyle
&= ~WS_DISABLED
;
647 SendMessage( hwnd
, WM_ENABLE
, TRUE
, 0 );
650 else if (!enable
&& !(wndPtr
->dwStyle
& WS_DISABLED
))
653 wndPtr
->dwStyle
|= WS_DISABLED
;
654 if ((hwnd
== GetFocus()) || IsChild( hwnd
, GetFocus() ))
655 SetFocus( 0 ); /* A disabled window can't have the focus */
656 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
657 ReleaseCapture(); /* A disabled window can't capture the mouse */
658 SendMessage( hwnd
, WM_ENABLE
, FALSE
, 0 );
661 return ((wndPtr
->dwStyle
& WS_DISABLED
) != 0);
665 /***********************************************************************
666 * IsWindowEnabled (USER.35)
668 BOOL
IsWindowEnabled(HWND hWnd
)
672 if (!(wndPtr
= WIN_FindWndPtr(hWnd
))) return FALSE
;
673 return !(wndPtr
->dwStyle
& WS_DISABLED
);
677 /**********************************************************************
678 * GetWindowWord (USER.133)
680 WORD
GetWindowWord( HWND hwnd
, short offset
)
682 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
683 if (!wndPtr
) return 0;
684 if (offset
>= 0) return *(WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
687 case GWW_ID
: return wndPtr
->wIDmenu
;
688 case GWW_HWNDPARENT
: return wndPtr
->hwndParent
;
689 case GWW_HINSTANCE
: return wndPtr
->hInstance
;
695 /**********************************************************************
696 * SetWindowWord (USER.134)
698 WORD
SetWindowWord( HWND hwnd
, short offset
, WORD newval
)
701 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
702 if (!wndPtr
) return 0;
703 if (offset
>= 0) ptr
= (WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
706 case GWW_ID
: ptr
= &wndPtr
->wIDmenu
;
707 case GWW_HINSTANCE
: ptr
= &wndPtr
->hInstance
;
716 /**********************************************************************
717 * GetWindowLong (USER.135)
719 LONG
GetWindowLong( HWND hwnd
, short offset
)
721 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
722 if (!wndPtr
) return 0;
723 if (offset
>= 0) return *(LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
726 case GWL_STYLE
: return wndPtr
->dwStyle
;
727 case GWL_EXSTYLE
: return wndPtr
->dwExStyle
;
729 if (!IS_16_BIT_ADDRESS(wndPtr
->lpfnWndProc
))
731 /* The window procedure is part of Wine.
732 Unfortunately, MS-Windows programs can't access these
734 FIXME: There should be a jump table somewhere in if1632
736 long x
=pStack16Frame
->cs
<<16 | 0x0010;
737 /* Just to make Borland's OWL happy */
740 else return (LONG
)wndPtr
->lpfnWndProc
;
746 /**********************************************************************
747 * SetWindowLong (USER.136)
749 LONG
SetWindowLong( HWND hwnd
, short offset
, LONG newval
)
752 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
753 if (!wndPtr
) return 0;
754 if (offset
>= 0) ptr
= (LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
757 case GWL_STYLE
: ptr
= &wndPtr
->dwStyle
;
759 case GWL_EXSTYLE
: ptr
= &wndPtr
->dwExStyle
;
761 case GWL_WNDPROC
: ptr
= (LONG
*)(&wndPtr
->lpfnWndProc
);
771 /*******************************************************************
772 * GetWindowText (USER.36)
774 int GetWindowText(HWND hwnd
, LPSTR lpString
, int nMaxCount
)
776 return (int)SendMessage(hwnd
, WM_GETTEXT
, (WORD
)nMaxCount
,
780 /*******************************************************************
781 * SetWindowText (USER.37)
783 void SetWindowText(HWND hwnd
, LPSTR lpString
)
785 SendMessage(hwnd
, WM_SETTEXT
, (WORD
)NULL
, (DWORD
)lpString
);
788 /*******************************************************************
789 * GetWindowTextLength (USER.38)
791 int GetWindowTextLength(HWND hwnd
)
793 return (int)SendMessage(hwnd
, WM_GETTEXTLENGTH
, (WORD
)NULL
,
798 /*******************************************************************
801 BOOL
IsWindow( HWND hwnd
)
803 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
804 return ((wndPtr
!= NULL
) && (wndPtr
->dwMagic
== WND_MAGIC
));
808 /*****************************************************************
809 * GetParent (USER.46)
811 HWND
GetParent(HWND hwnd
)
813 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
814 if (!wndPtr
|| !(wndPtr
->dwStyle
& WS_CHILD
)) return 0;
815 return wndPtr
->hwndParent
;
818 /*****************************************************************
819 * SetParent (USER.233)
821 HWND
SetParent(HWND hwndChild
, HWND hwndNewParent
)
825 WND
*wndPtr
= WIN_FindWndPtr(hwndChild
);
826 if (!wndPtr
|| !(wndPtr
->dwStyle
& WS_CHILD
)) return 0;
828 temp
= wndPtr
->hwndParent
;
831 wndPtr
->hwndParent
= hwndNewParent
;
833 wndPtr
->hwndParent
= GetDesktopWindow();
840 /*******************************************************************
843 BOOL
IsChild( HWND parent
, HWND child
)
845 WND
* wndPtr
= WIN_FindWndPtr( child
);
846 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
848 if (wndPtr
->hwndParent
== parent
) return TRUE
;
849 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
855 /***********************************************************************
856 * IsWindowVisible (USER.49)
858 BOOL
IsWindowVisible(HWND hWnd
)
860 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
861 if (wndPtr
== 0) return(FALSE
);
862 else return ((wndPtr
->dwStyle
& WS_VISIBLE
) != 0);
867 /*******************************************************************
868 * GetTopWindow (USER.229)
870 HWND
GetTopWindow( HWND hwnd
)
872 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
873 if (wndPtr
) return wndPtr
->hwndChild
;
878 /*******************************************************************
879 * GetWindow (USER.262)
881 HWND
GetWindow( HWND hwnd
, WORD rel
)
883 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
884 if (!wndPtr
) return 0;
888 if (wndPtr
->hwndParent
)
890 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
891 return parentPtr
->hwndChild
;
896 if (!wndPtr
->hwndParent
) return 0; /* Desktop window */
897 while (wndPtr
->hwndNext
)
899 hwnd
= wndPtr
->hwndNext
;
900 wndPtr
= WIN_FindWndPtr( hwnd
);
905 return wndPtr
->hwndNext
;
911 if (wndPtr
->hwndParent
)
913 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
914 hwndPrev
= parentPtr
->hwndChild
;
916 else return 0; /* Desktop window */
917 if (hwndPrev
== hwnd
) return 0;
920 wndPtr
= WIN_FindWndPtr( hwndPrev
);
921 if (wndPtr
->hwndNext
== hwnd
) break;
922 hwndPrev
= wndPtr
->hwndNext
;
928 return wndPtr
->hwndOwner
;
931 return wndPtr
->hwndChild
;
937 /*******************************************************************
938 * GetNextWindow (USER.230)
940 HWND
GetNextWindow( HWND hwnd
, WORD flag
)
942 if ((flag
!= GW_HWNDNEXT
) && (flag
!= GW_HWNDPREV
)) return 0;
943 return GetWindow( hwnd
, flag
);
948 /*******************************************************************
949 * GetLastActivePopup (USER.287)
951 HWND
GetLastActivePopup(HWND hwnd
)
954 wndPtr
= WIN_FindWndPtr(hwnd
);
955 if (wndPtr
== NULL
) return hwnd
;
956 return wndPtr
->hwndLastActive
;
960 /*******************************************************************
961 * EnumWindows (USER.54)
963 * o gets the desktop window and iterates over all the windows
964 * which are direct decendents of the desktop * by iterating over
965 * the desktop's child window and all the child windows next
968 * o call wndenumprc for every child window the desktop has
969 * (parameters to Callback16 passed backwards so they are
970 * put in in pascal calling order)
972 * o if wndenumprc returns 0 exit
975 BOOL
EnumWindows(FARPROC wndenumprc
, LPARAM lParam
)
977 HWND hwnd
= GetTopWindow( GetDesktopWindow() );
981 dprintf_enum(stddeb
,"EnumWindows\n");
984 if ( !(wndPtr
=WIN_FindWndPtr(hwnd
)) ) {
988 (*wndenumprc
)(hwnd
, lParam
);
990 result
= CallBack16(wndenumprc
, 2,
991 CALLBACK_SIZE_WORD
, (int) hwnd
,
992 CALLBACK_SIZE_LONG
, lParam
);
997 hwnd
=wndPtr
->hwndNext
;
999 return 1; /* for now */
1002 /*******************************************************************
1005 * o hwnd is the first child to use, loop until all next windows
1008 * o call wdnenumprc with parameters in inverse order (pascal)
1010 * o call ourselves with the next child window
1013 static BOOL
WIN_EnumChildWin(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1018 if ( !(wndPtr
=WIN_FindWndPtr(hwnd
)) ) {
1022 if (!(*wndenumprc
)( 2, lParam
, (int) hwnd
)) {
1024 if (!CallBack16(wndenumprc
, 2,
1025 CALLBACK_SIZE_WORD
, (int) hwnd
,
1026 CALLBACK_SIZE_LONG
, lParam
)) {
1030 if (!WIN_EnumChildWin(wndPtr
->hwndChild
, wndenumprc
, lParam
)) {
1033 hwnd
=wndPtr
->hwndNext
;
1038 /*******************************************************************
1039 * EnumChildWindows (USER.55)
1041 * o gets the first child of hwnd
1043 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1045 BOOL
EnumChildWindows(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1049 dprintf_enum(stddeb
,"EnumChildWindows\n");
1051 if (hwnd
== 0) return 0;
1052 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1053 hwnd
= wndPtr
->hwndChild
;
1054 return WIN_EnumChildWin(hwnd
, wndenumprc
, lParam
);
1057 /*******************************************************************
1058 * AnyPopup [USER.52]
1062 dprintf_win(stdnimp
,"EMPTY STUB !! AnyPopup !\n");
1066 /*******************************************************************
1067 * FlashWindow [USER.105]
1069 BOOL
FlashWindow(HWND hWnd
, BOOL bInvert
)
1071 dprintf_win(stdnimp
,"EMPTY STUB !! FlashWindow !\n");
1076 /*******************************************************************
1077 * SetSysModalWindow [USER.188]
1079 HWND
SetSysModalWindow(HWND hWnd
)
1081 HWND hWndOldModal
= hWndSysModal
;
1082 hWndSysModal
= hWnd
;
1083 dprintf_win(stdnimp
,"EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd
);
1084 return hWndOldModal
;
1088 /*******************************************************************
1089 * GetSysModalWindow [USER.189]
1091 HWND
GetSysModalWindow(void)
1093 return hWndSysModal
;