2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993, 1994";
18 #include "sysmetrics.h"
23 /* #define DEBUG_WIN /* */
24 /* #undef DEBUG_WIN /* */
25 /* #define DEBUG_MENU /* */
26 /* #undef DEBUG_MENU /* */
29 extern Colormap COLOR_WinColormap
;
31 extern void EVENT_RegisterWindow( Window w
, HWND hwnd
); /* event.c */
32 extern void WINPOS_ChangeActiveWindow( HWND hwnd
, BOOL mouseMsg
); /*winpos.c*/
33 extern LONG
WINPOS_SendNCCalcSize( HWND hwnd
, BOOL calcValidRect
,
34 RECT
*newWindowRect
, RECT
*oldWindowRect
,
35 RECT
*oldClientRect
, WINDOWPOS
*winpos
,
36 RECT
*newClientRect
); /* winpos.c */
38 extern HMENU
CopySysMenu(); /* menu.c */
39 extern LONG
MDIClientWndProc(HWND hwnd
, WORD message
,
40 WORD wParam
, LONG lParam
); /* mdi.c */
42 static HWND hwndDesktop
= 0;
43 static HWND hWndSysModal
= 0;
45 /***********************************************************************
48 * Return a pointer to the WND structure corresponding to a HWND.
50 WND
* WIN_FindWndPtr( HWND hwnd
)
54 if (!hwnd
) return NULL
;
55 ptr
= (WND
*) USER_HEAP_ADDR( hwnd
);
56 if (IsBadReadPtr(ptr
, sizeof *ptr
)) return NULL
;
57 if (ptr
->dwMagic
!= WND_MAGIC
) return NULL
;
62 /***********************************************************************
65 * Return the X window associated to a window.
67 Window
WIN_GetXWindow( HWND hwnd
)
69 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
70 while (wndPtr
&& !wndPtr
->window
)
72 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
74 return wndPtr
? wndPtr
->window
: 0;
78 /***********************************************************************
81 * Remove a window from the siblings linked list.
83 BOOL
WIN_UnlinkWindow( HWND hwnd
)
86 WND
*parentPtr
, *wndPtr
;
88 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
89 if (!(parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
))) return FALSE
;
91 curWndPtr
= &parentPtr
->hwndChild
;
93 while (*curWndPtr
!= hwnd
)
95 WND
* curPtr
= WIN_FindWndPtr( *curWndPtr
);
96 curWndPtr
= &curPtr
->hwndNext
;
98 *curWndPtr
= wndPtr
->hwndNext
;
103 /***********************************************************************
106 * Insert a window into the siblings linked list.
107 * The window is inserted after the specified window, which can also
108 * be specified as HWND_TOP or HWND_BOTTOM.
110 BOOL
WIN_LinkWindow( HWND hwnd
, HWND hwndInsertAfter
)
112 HWND
* hwndPtr
= NULL
; /* pointer to hwnd to change */
113 WND
*wndPtr
, *parentPtr
;
115 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
116 if (!(parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
))) return FALSE
;
118 if ((hwndInsertAfter
== HWND_TOP
) || (hwndInsertAfter
== HWND_BOTTOM
))
120 hwndPtr
= &parentPtr
->hwndChild
; /* Point to first sibling hwnd */
121 if (hwndInsertAfter
== HWND_BOTTOM
) /* Find last sibling hwnd */
124 WND
* nextPtr
= WIN_FindWndPtr( *hwndPtr
);
125 hwndPtr
= &nextPtr
->hwndNext
;
128 else /* Normal case */
130 WND
* afterPtr
= WIN_FindWndPtr( hwndInsertAfter
);
131 if (afterPtr
) hwndPtr
= &afterPtr
->hwndNext
;
133 if (!hwndPtr
) return FALSE
;
134 wndPtr
->hwndNext
= *hwndPtr
;
140 /***********************************************************************
141 * WIN_FindWinToRepaint
143 * Find a window that needs repaint.
145 HWND
WIN_FindWinToRepaint( HWND hwnd
)
149 /* Note: the desktop window never gets WM_PAINT messages */
150 if (!hwnd
) hwnd
= GetTopWindow( hwndDesktop
);
151 for ( ; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
153 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
154 if (!(wndPtr
->dwStyle
& WS_VISIBLE
) || (wndPtr
->flags
& WIN_NO_REDRAW
))
156 if ((wndPtr
->dwStyle
& WS_MINIMIZE
) && (WIN_CLASS_INFO(wndPtr
).hIcon
))
158 if (wndPtr
->hrgnUpdate
|| (wndPtr
->flags
& WIN_INTERNAL_PAINT
))
160 if (wndPtr
->hwndChild
)
163 if ((child
= WIN_FindWinToRepaint( wndPtr
->hwndChild
)))
171 /***********************************************************************
172 * WIN_SendParentNotify
174 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
175 * the window has the WS_EX_NOPARENTNOTIFY style.
177 void WIN_SendParentNotify( HWND hwnd
, WORD event
, LONG lParam
)
179 HWND current
= GetParent( hwnd
);
180 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
182 if (!wndPtr
|| (wndPtr
->dwExStyle
& WS_EX_NOPARENTNOTIFY
)) return;
185 SendMessage( current
, WM_PARENTNOTIFY
, event
, lParam
);
186 current
= GetParent( current
);
191 /***********************************************************************
194 * Destroy storage associated to a window
196 static void WIN_DestroyWindow( HWND hwnd
)
198 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
199 CLASS
*classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
);
201 if (!wndPtr
|| !classPtr
) return;
202 WIN_UnlinkWindow( hwnd
); /* Remove the window from the linked list */
203 wndPtr
->dwMagic
= 0; /* Mark it as invalid */
204 if ((wndPtr
->hrgnUpdate
) || (wndPtr
->flags
& WIN_INTERNAL_PAINT
))
206 if (wndPtr
->hrgnUpdate
) DeleteObject( wndPtr
->hrgnUpdate
);
207 MSG_DecPaintCount( wndPtr
->hmemTaskQ
);
209 if (!(wndPtr
->dwStyle
& WS_CHILD
))
211 if (wndPtr
->wIDmenu
) DestroyMenu( wndPtr
->wIDmenu
);
213 if (wndPtr
->hSysMenu
) DestroyMenu( wndPtr
->hSysMenu
);
214 if (wndPtr
->window
) XDestroyWindow( display
, wndPtr
->window
);
215 if (classPtr
->wc
.style
& CS_OWNDC
) DCE_FreeDCE( wndPtr
->hdce
);
216 classPtr
->cWindows
--;
217 USER_HEAP_FREE( hwnd
);
221 /***********************************************************************
222 * WIN_CreateDesktopWindow
224 * Create the desktop window.
226 BOOL
WIN_CreateDesktopWindow()
232 if (!(hclass
= CLASS_FindClassByName( DESKTOP_CLASS_NAME
, 0, &classPtr
)))
235 hwndDesktop
= USER_HEAP_ALLOC( GMEM_MOVEABLE
,
236 sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
237 if (!hwndDesktop
) return FALSE
;
238 wndPtr
= (WND
*) USER_HEAP_ADDR( hwndDesktop
);
240 wndPtr
->hwndNext
= 0;
241 wndPtr
->hwndChild
= 0;
242 wndPtr
->dwMagic
= WND_MAGIC
;
243 wndPtr
->hwndParent
= 0;
244 wndPtr
->hwndOwner
= 0;
245 wndPtr
->hClass
= hclass
;
246 wndPtr
->hInstance
= 0;
247 wndPtr
->rectWindow
.left
= 0;
248 wndPtr
->rectWindow
.top
= 0;
249 wndPtr
->rectWindow
.right
= SYSMETRICS_CXSCREEN
;
250 wndPtr
->rectWindow
.bottom
= SYSMETRICS_CYSCREEN
;
251 wndPtr
->rectClient
= wndPtr
->rectWindow
;
252 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
253 wndPtr
->ptIconPos
.x
= -1;
254 wndPtr
->ptIconPos
.y
= -1;
255 wndPtr
->ptMaxPos
.x
= -1;
256 wndPtr
->ptMaxPos
.y
= -1;
257 wndPtr
->hmemTaskQ
= 0; /* Desktop does not belong to a task */
258 wndPtr
->hrgnUpdate
= 0;
259 wndPtr
->hwndLastActive
= hwndDesktop
;
260 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
261 wndPtr
->dwStyle
= WS_VISIBLE
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
;
262 wndPtr
->dwExStyle
= 0;
264 wndPtr
->hVScroll
= 0;
265 wndPtr
->hHScroll
= 0;
269 wndPtr
->window
= rootWindow
;
270 wndPtr
->hSysMenu
= 0;
274 /* Send dummy WM_NCCREATE message */
275 SendMessage( hwndDesktop
, WM_NCCREATE
, 0, 0 );
276 EVENT_RegisterWindow( wndPtr
->window
, hwndDesktop
);
277 RedrawWindow( hwndDesktop
, NULL
, 0,
278 RDW_INVALIDATE
| RDW_ERASE
| RDW_ERASENOW
);
283 /***********************************************************************
284 * CreateWindow (USER.41)
286 HWND
CreateWindow( LPSTR className
, LPSTR windowName
,
287 DWORD style
, short x
, short y
, short width
, short height
,
288 HWND parent
, HMENU menu
, HANDLE instance
, LPSTR data
)
290 return CreateWindowEx( 0, className
, windowName
, style
,
291 x
, y
, width
, height
, parent
, menu
, instance
, data
);
295 /***********************************************************************
296 * CreateWindowEx (USER.452)
298 HWND
CreateWindowEx( DWORD exStyle
, LPSTR className
, LPSTR windowName
,
299 DWORD style
, short x
, short y
, short width
, short height
,
300 HWND parent
, HMENU menu
, HANDLE instance
, LPSTR data
)
305 POINT maxSize
, maxPos
, minTrack
, maxTrack
;
306 CREATESTRUCT
*createStruct
;
307 HANDLE hcreateStruct
;
309 XSetWindowAttributes win_attr
;
311 dprintf_win(stddeb
, "CreateWindowEx: %04X '%s' '%s' %04X %d,%d %dx%d %04X %04X %04X %08X\n",
312 exStyle
, className
, windowName
, style
, x
, y
, width
, height
,
313 parent
, menu
, instance
, data
);
314 /* 'soundrec.exe' has negative position !
315 Why ? For now, here a patch : */
316 if (!strcmp(className
, "SoundRec"))
321 if (x
== CW_USEDEFAULT
) x
= y
= 0;
322 if (width
== CW_USEDEFAULT
)
327 if (width
== 0) width
= 1;
328 if (height
== 0) height
= 1;
330 /* Find the parent and class */
334 /* Make sure parent is valid */
335 if (!IsWindow( parent
)) return 0;
337 else if (style
& WS_CHILD
) return 0; /* WS_CHILD needs a parent */
339 if (!(class = CLASS_FindClassByName( className
, instance
, &classPtr
))) {
340 fprintf(stderr
,"CreateWindow BAD CLASSNAME '%s' !\n", className
);
344 /* Correct the window style */
346 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
347 style
|= WS_CAPTION
| WS_CLIPSIBLINGS
;
348 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
350 /* Create the window structure */
352 hwnd
= USER_HEAP_ALLOC(GMEM_MOVEABLE
, sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
355 /* Fill the structure */
357 wndPtr
= (WND
*) USER_HEAP_ADDR( hwnd
);
358 wndPtr
->hwndNext
= 0;
359 wndPtr
->hwndChild
= 0;
361 wndPtr
->dwMagic
= WND_MAGIC
;
362 wndPtr
->hwndParent
= (style
& WS_CHILD
) ? parent
: hwndDesktop
;
363 wndPtr
->hwndOwner
= (style
& WS_CHILD
) ? 0 : parent
;
364 wndPtr
->hClass
= class;
365 wndPtr
->hInstance
= instance
;
366 wndPtr
->rectWindow
.left
= x
;
367 wndPtr
->rectWindow
.top
= y
;
368 wndPtr
->rectWindow
.right
= x
+ width
;
369 wndPtr
->rectWindow
.bottom
= y
+ height
;
370 wndPtr
->rectClient
= wndPtr
->rectWindow
;
371 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
372 wndPtr
->ptIconPos
.x
= -1;
373 wndPtr
->ptIconPos
.y
= -1;
374 wndPtr
->ptMaxPos
.x
= -1;
375 wndPtr
->ptMaxPos
.y
= -1;
376 wndPtr
->hmemTaskQ
= GetTaskQueue(0);
377 wndPtr
->hrgnUpdate
= 0;
378 wndPtr
->hwndPrevActive
= 0;
379 wndPtr
->hwndLastActive
= hwnd
;
380 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
381 wndPtr
->dwStyle
= style
;
382 wndPtr
->dwExStyle
= exStyle
;
386 wndPtr
->hVScroll
= 0;
387 wndPtr
->hHScroll
= 0;
388 wndPtr
->hSysMenu
= 0;
392 if (classPtr
->wc
.cbWndExtra
)
393 memset( wndPtr
->wExtra
, 0, classPtr
->wc
.cbWndExtra
);
394 classPtr
->cWindows
++;
396 /* Make sure owner is a top-level window */
398 while (wndPtr
->hwndOwner
&& GetParent(wndPtr
->hwndOwner
))
399 wndPtr
->hwndOwner
= GetParent(wndPtr
->hwndOwner
);
401 /* Get class or window DC if needed */
403 if (classPtr
->wc
.style
& CS_OWNDC
)
404 wndPtr
->hdce
= DCE_AllocDCE( DCE_WINDOW_DC
);
405 else if (classPtr
->wc
.style
& CS_CLASSDC
)
406 wndPtr
->hdce
= classPtr
->hdce
;
410 /* Insert the window in the linked list */
412 WIN_LinkWindow( hwnd
, HWND_TOP
);
414 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
416 WINPOS_GetMinMaxInfo( hwnd
, &maxSize
, &maxPos
, &minTrack
, &maxTrack
);
418 if ( maxSize
.x
< width
)
421 wndPtr
->rectWindow
.right
= x
+ width
;
423 if ( maxSize
.y
< height
)
426 wndPtr
->rectWindow
.bottom
= y
+ height
;
429 /* Create the X window (only for top-level windows, and then only */
430 /* when there's no desktop window) */
432 if (!(style
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
435 HCURSOR hCursor
= classPtr
->wc
.hCursor
;
436 if (!hCursor
) hCursor
= LoadCursor( 0, IDC_ARROW
);
437 cursor
= (CURSORALLOC
*) GlobalLock(hCursor
);
439 win_attr
.event_mask
= ExposureMask
| KeyPressMask
| KeyReleaseMask
|
440 PointerMotionMask
| ButtonPressMask
|
441 ButtonReleaseMask
| FocusChangeMask
;
442 win_attr
.override_redirect
= TRUE
;
443 win_attr
.colormap
= COLOR_WinColormap
;
444 win_attr
.backing_store
= Options
.backingstore
? WhenMapped
: NotUseful
;
445 win_attr
.save_under
= ((classPtr
->wc
.style
& CS_SAVEBITS
) != 0);
446 win_attr
.cursor
= cursor
? cursor
->xcursor
: None
;
447 wndPtr
->window
= XCreateWindow( display
, rootWindow
, x
, y
,
448 width
, height
, 0, CopyFromParent
,
449 InputOutput
, CopyFromParent
,
450 CWEventMask
| CWOverrideRedirect
|
451 CWColormap
| CWCursor
| CWSaveUnder
|
452 CWBackingStore
, &win_attr
);
453 XStoreName( display
, wndPtr
->window
, windowName
);
454 EVENT_RegisterWindow( wndPtr
->window
, hwnd
);
455 GlobalUnlock( hCursor
);
458 dprintf_menu(stddeb
,"CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n",
459 menu
, instance
, classPtr
->wc
.lpszMenuName
);
461 if ((style
& WS_CAPTION
) && (style
& WS_CHILD
) == 0) {
465 if (classPtr
->wc
.lpszMenuName
!= NULL
)
466 SetMenu(hwnd
, LoadMenu(instance
, classPtr
->wc
.lpszMenuName
));
470 wndPtr
->wIDmenu
= menu
;
472 /* Send the WM_CREATE message */
474 hcreateStruct
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, sizeof(CREATESTRUCT
) );
475 createStruct
= (CREATESTRUCT
*) USER_HEAP_ADDR( hcreateStruct
);
476 createStruct
->lpCreateParams
= data
;
477 createStruct
->hInstance
= instance
;
478 createStruct
->hMenu
= menu
;
479 createStruct
->hwndParent
= parent
;
480 createStruct
->cx
= width
;
481 createStruct
->cy
= height
;
484 createStruct
->style
= style
;
485 createStruct
->lpszName
= windowName
;
486 createStruct
->lpszClass
= className
;
487 createStruct
->dwExStyle
= 0;
489 wmcreate
= SendMessage( hwnd
, WM_NCCREATE
, 0, (LONG
)createStruct
);
490 if (!wmcreate
) wmcreate
= -1;
493 WINPOS_SendNCCalcSize( hwnd
, FALSE
, &wndPtr
->rectWindow
,
494 NULL
, NULL
, NULL
, &wndPtr
->rectClient
);
495 wmcreate
= SendMessage( hwnd
, WM_CREATE
, 0, (LONG
)createStruct
);
498 USER_HEAP_FREE( hcreateStruct
);
502 /* Abort window creation */
503 WIN_DestroyWindow( hwnd
);
507 /* Create a copy of SysMenu */
508 if (style
& WS_SYSMENU
) wndPtr
->hSysMenu
= CopySysMenu();
510 /* Register window in current task windows list */
511 AddWindowToTask(GetCurrentTask(), hwnd
);
513 WIN_SendParentNotify( hwnd
, WM_CREATE
, MAKELONG( hwnd
, wndPtr
->wIDmenu
) );
515 if (style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
516 /* if (style & WS_MINIMIZE) ShowWindow( hwnd, SW_MINIMIZE ); */
518 dprintf_win(stddeb
, "CreateWindowEx: return %04X \n", hwnd
);
523 /***********************************************************************
524 * DestroyWindow (USER.53)
526 BOOL
DestroyWindow( HWND hwnd
)
531 dprintf_win(stddeb
, "DestroyWindow (%04x)\n", hwnd
);
535 if (hwnd
== hwndDesktop
) return FALSE
; /* Can't destroy desktop */
536 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
537 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return FALSE
;
539 /* Hide the window */
541 if (wndPtr
->dwStyle
& WS_VISIBLE
)
542 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, SWP_HIDEWINDOW
| SWP_NOACTIVATE
|
543 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOSIZE
);
544 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
546 WIN_SendParentNotify( hwnd
, WM_DESTROY
, MAKELONG(hwnd
, wndPtr
->wIDmenu
) );
548 /* Send destroy messages and destroy children */
550 SendMessage( hwnd
, WM_DESTROY
, 0, 0 );
551 while (wndPtr
->hwndChild
) /* The child removes itself from the list */
552 DestroyWindow( wndPtr
->hwndChild
);
553 SendMessage( hwnd
, WM_NCDESTROY
, 0, 0 );
555 /* Remove the window from current task windows list */
556 RemoveWindowFromTask(GetCurrentTask(), hwnd
);
558 /* Destroy the window */
560 WIN_DestroyWindow( hwnd
);
565 /***********************************************************************
566 * CloseWindow (USER.43)
568 void CloseWindow(HWND hWnd
)
570 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
571 if (wndPtr
->dwStyle
& WS_CHILD
) return;
572 ShowWindow(hWnd
, SW_MINIMIZE
);
577 /***********************************************************************
580 BOOL
OpenIcon(HWND hWnd
)
582 if (!IsIconic(hWnd
)) return FALSE
;
583 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
=Stack16Frame
[11]<<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");
986 if ( !(wndPtr
=WIN_FindWndPtr(hwnd
)) ) {
990 (*wndenumprc
)(hwnd
, lParam
);
992 result
= CallBack16(wndenumprc
, 2,
993 CALLBACK_SIZE_WORD
, (int) hwnd
,
994 CALLBACK_SIZE_LONG
, lParam
);
999 hwnd
=wndPtr
->hwndNext
;
1001 return 1; /* for now */
1004 /*******************************************************************
1007 * o hwnd is the first child to use, loop until all next windows
1010 * o call wdnenumprc with parameters in inverse order (pascal)
1012 * o call ourselves with the next child window
1015 static BOOL
WIN_EnumChildWin(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1023 if ( !(wndPtr
=WIN_FindWndPtr(hwnd
)) ) {
1027 if (!(*wndenumprc
)( 2, lParam
, (int) hwnd
)) {
1029 if (!CallBack16(wndenumprc
, 2,
1030 CALLBACK_SIZE_WORD
, (int) hwnd
,
1031 CALLBACK_SIZE_LONG
, lParam
)) {
1035 if (!WIN_EnumChildWin(wndPtr
->hwndChild
, wndenumprc
, lParam
)) {
1038 hwnd
=wndPtr
->hwndNext
;
1043 /*******************************************************************
1044 * EnumChildWindows (USER.55)
1046 * o gets the first child of hwnd
1048 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1050 BOOL
EnumChildWindows(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1054 dprintf_enum(stddeb
,"EnumChildWindows\n");
1056 if (hwnd
== 0) return 0;
1057 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1058 hwnd
= wndPtr
->hwndChild
;
1059 return WIN_EnumChildWin(hwnd
, wndenumprc
, lParam
);
1062 /*******************************************************************
1063 * AnyPopup [USER.52]
1067 dprintf_win(stdnimp
,"EMPTY STUB !! AnyPopup !\n");
1071 /*******************************************************************
1072 * FlashWindow [USER.105]
1074 BOOL
FlashWindow(HWND hWnd
, BOOL bInvert
)
1076 dprintf_win(stdnimp
,"EMPTY STUB !! FlashWindow !\n");
1081 /*******************************************************************
1082 * SetSysModalWindow [USER.188]
1084 HWND
SetSysModalWindow(HWND hWnd
)
1086 HWND hWndOldModal
= hWndSysModal
;
1087 hWndSysModal
= hWnd
;
1088 dprintf_win(stdnimp
,"EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd
);
1089 return hWndOldModal
;
1093 /*******************************************************************
1094 * GetSysModalWindow [USER.189]
1096 HWND
GetSysModalWindow(void)
1098 return hWndSysModal
;