2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993, 1994";
18 #include "sysmetrics.h"
24 /* #define DEBUG_WIN /* */
25 /* #undef DEBUG_WIN /* */
26 /* #define DEBUG_MENU /* */
27 /* #undef DEBUG_MENU /* */
30 extern Colormap COLOR_WinColormap
;
32 extern void EVENT_RegisterWindow( Window w
, HWND hwnd
); /* event.c */
33 extern void WINPOS_ChangeActiveWindow( HWND hwnd
, BOOL mouseMsg
); /*winpos.c*/
34 extern LONG
WINPOS_SendNCCalcSize( HWND hwnd
, BOOL calcValidRect
,
35 RECT
*newWindowRect
, RECT
*oldWindowRect
,
36 RECT
*oldClientRect
, WINDOWPOS
*winpos
,
37 RECT
*newClientRect
); /* winpos.c */
39 extern HMENU
CopySysMenu(); /* menu.c */
40 extern LONG
MDIClientWndProc(HWND hwnd
, WORD message
,
41 WORD wParam
, LONG lParam
); /* mdi.c */
44 static HWND hwndDesktop
= 0;
45 static HWND hWndSysModal
= 0;
47 /***********************************************************************
50 * Return a pointer to the WND structure corresponding to a HWND.
52 WND
* WIN_FindWndPtr( HWND hwnd
)
56 if (!hwnd
) return NULL
;
57 ptr
= (WND
*) USER_HEAP_ADDR( hwnd
);
58 if (IsBadReadPtr(ptr
, sizeof *ptr
)) return NULL
;
59 if (ptr
->dwMagic
!= WND_MAGIC
) return NULL
;
64 /***********************************************************************
67 * Return the X window associated to a window.
69 Window
WIN_GetXWindow( HWND hwnd
)
71 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
72 while (wndPtr
&& !wndPtr
->window
)
74 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
76 return wndPtr
? wndPtr
->window
: 0;
80 /***********************************************************************
83 * Remove a window from the siblings linked list.
85 BOOL
WIN_UnlinkWindow( HWND hwnd
)
88 WND
*parentPtr
, *wndPtr
;
90 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
91 if (!(parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
))) return FALSE
;
93 curWndPtr
= &parentPtr
->hwndChild
;
95 while (*curWndPtr
!= hwnd
)
97 WND
* curPtr
= WIN_FindWndPtr( *curWndPtr
);
98 curWndPtr
= &curPtr
->hwndNext
;
100 *curWndPtr
= wndPtr
->hwndNext
;
105 /***********************************************************************
108 * Insert a window into the siblings linked list.
109 * The window is inserted after the specified window, which can also
110 * be specified as HWND_TOP or HWND_BOTTOM.
112 BOOL
WIN_LinkWindow( HWND hwnd
, HWND hwndInsertAfter
)
114 HWND
* hwndPtr
= NULL
; /* pointer to hwnd to change */
115 WND
*wndPtr
, *parentPtr
;
117 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
118 if (!(parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
))) return FALSE
;
120 if ((hwndInsertAfter
== HWND_TOP
) || (hwndInsertAfter
== HWND_BOTTOM
))
122 hwndPtr
= &parentPtr
->hwndChild
; /* Point to first sibling hwnd */
123 if (hwndInsertAfter
== HWND_BOTTOM
) /* Find last sibling hwnd */
126 WND
* nextPtr
= WIN_FindWndPtr( *hwndPtr
);
127 hwndPtr
= &nextPtr
->hwndNext
;
130 else /* Normal case */
132 WND
* afterPtr
= WIN_FindWndPtr( hwndInsertAfter
);
133 if (afterPtr
) hwndPtr
= &afterPtr
->hwndNext
;
135 if (!hwndPtr
) return FALSE
;
136 wndPtr
->hwndNext
= *hwndPtr
;
142 /***********************************************************************
143 * WIN_FindWinToRepaint
145 * Find a window that needs repaint.
147 HWND
WIN_FindWinToRepaint( HWND hwnd
)
151 /* Note: the desktop window never gets WM_PAINT messages */
152 if (!hwnd
) hwnd
= GetTopWindow( hwndDesktop
);
153 for ( ; hwnd
!= 0; hwnd
= wndPtr
->hwndNext
)
155 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
156 if (!(wndPtr
->dwStyle
& WS_VISIBLE
) || (wndPtr
->flags
& WIN_NO_REDRAW
))
158 if ((wndPtr
->dwStyle
& WS_MINIMIZE
) && (WIN_CLASS_INFO(wndPtr
).hIcon
))
160 if (wndPtr
->hrgnUpdate
|| (wndPtr
->flags
& WIN_INTERNAL_PAINT
))
162 if (wndPtr
->hwndChild
)
165 if ((child
= WIN_FindWinToRepaint( wndPtr
->hwndChild
)))
173 /***********************************************************************
174 * WIN_SendParentNotify
176 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
177 * the window has the WS_EX_NOPARENTNOTIFY style.
179 void WIN_SendParentNotify( HWND hwnd
, WORD event
, LONG lParam
)
181 HWND current
= GetParent( hwnd
);
182 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
184 if (!wndPtr
|| (wndPtr
->dwExStyle
& WS_EX_NOPARENTNOTIFY
)) return;
187 SendMessage( current
, WM_PARENTNOTIFY
, event
, lParam
);
188 current
= GetParent( current
);
193 /***********************************************************************
196 * Destroy storage associated to a window
198 static void WIN_DestroyWindow( HWND hwnd
)
200 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
201 CLASS
*classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
);
203 if (!wndPtr
|| !classPtr
) return;
204 wndPtr
->dwMagic
= 0; /* Mark it as invalid */
205 if ((wndPtr
->hrgnUpdate
) || (wndPtr
->flags
& WIN_INTERNAL_PAINT
))
207 if (wndPtr
->hrgnUpdate
) DeleteObject( wndPtr
->hrgnUpdate
);
208 MSG_DecPaintCount( wndPtr
->hmemTaskQ
);
210 if (!(wndPtr
->dwStyle
& WS_CHILD
))
212 if (wndPtr
->wIDmenu
) DestroyMenu( wndPtr
->wIDmenu
);
214 if (wndPtr
->hSysMenu
) DestroyMenu( wndPtr
->hSysMenu
);
215 if (wndPtr
->window
) XDestroyWindow( display
, wndPtr
->window
);
216 if (classPtr
->wc
.style
& CS_OWNDC
) DCE_FreeDCE( wndPtr
->hdce
);
217 classPtr
->cWindows
--;
218 USER_HEAP_FREE( hwnd
);
222 /***********************************************************************
223 * WIN_CreateDesktopWindow
225 * Create the desktop window.
227 BOOL
WIN_CreateDesktopWindow()
233 if (!(hclass
= CLASS_FindClassByName( DESKTOP_CLASS_NAME
, &classPtr
)))
236 hwndDesktop
= USER_HEAP_ALLOC( GMEM_MOVEABLE
,
237 sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
238 if (!hwndDesktop
) return FALSE
;
239 wndPtr
= (WND
*) USER_HEAP_ADDR( hwndDesktop
);
241 wndPtr
->hwndNext
= 0;
242 wndPtr
->hwndChild
= 0;
243 wndPtr
->dwMagic
= WND_MAGIC
;
244 wndPtr
->hwndParent
= 0;
245 wndPtr
->hwndOwner
= 0;
246 wndPtr
->hClass
= hclass
;
247 wndPtr
->hInstance
= 0;
248 wndPtr
->rectWindow
.left
= 0;
249 wndPtr
->rectWindow
.top
= 0;
250 wndPtr
->rectWindow
.right
= SYSMETRICS_CXSCREEN
;
251 wndPtr
->rectWindow
.bottom
= SYSMETRICS_CYSCREEN
;
252 wndPtr
->rectClient
= wndPtr
->rectWindow
;
253 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
254 wndPtr
->ptIconPos
.x
= -1;
255 wndPtr
->ptIconPos
.y
= -1;
256 wndPtr
->ptMaxPos
.x
= -1;
257 wndPtr
->ptMaxPos
.y
= -1;
258 wndPtr
->hmemTaskQ
= 0; /* Desktop does not belong to a task */
259 wndPtr
->hrgnUpdate
= 0;
260 wndPtr
->hwndLastActive
= hwndDesktop
;
261 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
262 wndPtr
->dwStyle
= WS_VISIBLE
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
;
263 wndPtr
->dwExStyle
= 0;
265 wndPtr
->VScroll
= NULL
;
266 wndPtr
->HScroll
= NULL
;
267 wndPtr
->scroll_flags
= 0;
271 wndPtr
->window
= rootWindow
;
272 wndPtr
->hSysMenu
= 0;
276 /* Send dummy WM_NCCREATE message */
277 SendMessage( hwndDesktop
, WM_NCCREATE
, 0, 0 );
278 EVENT_RegisterWindow( wndPtr
->window
, hwndDesktop
);
279 RedrawWindow( hwndDesktop
, NULL
, 0,
280 RDW_INVALIDATE
| RDW_ERASE
| RDW_ERASENOW
);
285 /***********************************************************************
286 * CreateWindow (USER.41)
288 HWND
CreateWindow( LPSTR className
, LPSTR windowName
,
289 DWORD style
, short x
, short y
, short width
, short height
,
290 HWND parent
, HMENU menu
, HANDLE instance
, LPSTR data
)
292 return CreateWindowEx( 0, className
, windowName
, style
,
293 x
, y
, width
, height
, parent
, menu
, instance
, data
);
297 /***********************************************************************
298 * CreateWindowEx (USER.452)
300 HWND
CreateWindowEx( DWORD exStyle
, LPSTR className
, LPSTR windowName
,
301 DWORD style
, short x
, short y
, short width
, short height
,
302 HWND parent
, HMENU menu
, HANDLE instance
, LPSTR data
)
307 POINT maxSize
, maxPos
, minTrack
, maxTrack
;
308 CREATESTRUCT
*createStruct
;
309 HANDLE hcreateStruct
;
311 XSetWindowAttributes win_attr
;
313 dprintf_win(stddeb
, "CreateWindowEx: %04X '%s' '%s' %04X %d,%d %dx%d %04X %04X %04X %08X\n",
314 exStyle
, className
, windowName
, style
, x
, y
, width
, height
,
315 parent
, menu
, instance
, data
);
316 /* 'soundrec.exe' has negative position !
317 Why ? For now, here a patch : */
318 if (!strcmp(className
, "SoundRec"))
323 if (x
== CW_USEDEFAULT
) x
= y
= 0;
324 if (width
== CW_USEDEFAULT
)
329 if (width
== 0) width
= 1;
330 if (height
== 0) height
= 1;
332 /* Find the parent and class */
336 /* Make sure parent is valid */
337 if (!IsWindow( parent
)) return 0;
339 else if (style
& WS_CHILD
) return 0; /* WS_CHILD needs a parent */
341 if (!(class = CLASS_FindClassByName( className
, &classPtr
))) {
342 fprintf(stderr
,"CreateWindow BAD CLASSNAME '%s' !\n", className
);
346 /* Correct the window style */
348 if (!(style
& (WS_POPUP
| WS_CHILD
))) /* Overlapped window */
349 style
|= WS_CAPTION
| WS_CLIPSIBLINGS
;
350 if (exStyle
& WS_EX_DLGMODALFRAME
) style
&= ~WS_THICKFRAME
;
352 /* Create the window structure */
354 hwnd
= USER_HEAP_ALLOC(GMEM_MOVEABLE
, sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
357 /* Fill the structure */
359 wndPtr
= (WND
*) USER_HEAP_ADDR( hwnd
);
360 wndPtr
->hwndNext
= 0;
361 wndPtr
->hwndChild
= 0;
363 wndPtr
->dwMagic
= WND_MAGIC
;
364 wndPtr
->hwndParent
= (style
& WS_CHILD
) ? parent
: hwndDesktop
;
365 wndPtr
->hwndOwner
= (style
& WS_CHILD
) ? 0 : parent
;
366 wndPtr
->hClass
= class;
367 wndPtr
->hInstance
= instance
;
368 wndPtr
->rectWindow
.left
= x
;
369 wndPtr
->rectWindow
.top
= y
;
370 wndPtr
->rectWindow
.right
= x
+ width
;
371 wndPtr
->rectWindow
.bottom
= y
+ height
;
372 wndPtr
->rectClient
= wndPtr
->rectWindow
;
373 wndPtr
->rectNormal
= wndPtr
->rectWindow
;
374 wndPtr
->ptIconPos
.x
= -1;
375 wndPtr
->ptIconPos
.y
= -1;
376 wndPtr
->ptMaxPos
.x
= -1;
377 wndPtr
->ptMaxPos
.y
= -1;
378 wndPtr
->hmemTaskQ
= GetTaskQueue(0);
379 wndPtr
->hrgnUpdate
= 0;
380 wndPtr
->hwndPrevActive
= 0;
381 wndPtr
->hwndLastActive
= hwnd
;
382 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
383 wndPtr
->dwStyle
= style
;
384 wndPtr
->dwExStyle
= exStyle
;
388 wndPtr
->VScroll
= NULL
;
389 wndPtr
->HScroll
= NULL
;
390 wndPtr
->scroll_flags
= 0;
391 wndPtr
->hSysMenu
= 0;
395 if (classPtr
->wc
.cbWndExtra
)
396 memset( wndPtr
->wExtra
, 0, classPtr
->wc
.cbWndExtra
);
397 classPtr
->cWindows
++;
399 /* Make sure owner is a top-level window */
401 while (wndPtr
->hwndOwner
&& GetParent(wndPtr
->hwndOwner
))
402 wndPtr
->hwndOwner
= GetParent(wndPtr
->hwndOwner
);
404 /* Get class or window DC if needed */
406 if (classPtr
->wc
.style
& CS_OWNDC
)
407 wndPtr
->hdce
= DCE_AllocDCE( DCE_WINDOW_DC
);
408 else if (classPtr
->wc
.style
& CS_CLASSDC
)
409 wndPtr
->hdce
= classPtr
->hdce
;
413 /* Insert the window in the linked list */
415 WIN_LinkWindow( hwnd
, HWND_TOP
);
417 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
419 WINPOS_GetMinMaxInfo( hwnd
, &maxSize
, &maxPos
, &minTrack
, &maxTrack
);
421 if ( maxSize
.x
< width
)
424 wndPtr
->rectWindow
.right
= x
+ width
;
426 if ( maxSize
.y
< height
)
429 wndPtr
->rectWindow
.bottom
= y
+ height
;
432 /* Create the X window (only for top-level windows, and then only */
433 /* when there's no desktop window) */
435 if (!(style
& WS_CHILD
) && (rootWindow
== DefaultRootWindow(display
)))
438 HCURSOR hCursor
= classPtr
->wc
.hCursor
;
439 if (!hCursor
) hCursor
= LoadCursor( 0, IDC_ARROW
);
440 cursor
= (CURSORALLOC
*) GlobalLock(hCursor
);
442 win_attr
.event_mask
= ExposureMask
| KeyPressMask
| KeyReleaseMask
|
443 PointerMotionMask
| ButtonPressMask
|
444 ButtonReleaseMask
| FocusChangeMask
;
445 win_attr
.override_redirect
= TRUE
;
446 win_attr
.colormap
= COLOR_WinColormap
;
447 win_attr
.backing_store
= Options
.backingstore
? WhenMapped
: NotUseful
;
448 win_attr
.save_under
= ((classPtr
->wc
.style
& CS_SAVEBITS
) != 0);
449 win_attr
.cursor
= cursor
? cursor
->xcursor
: None
;
450 wndPtr
->window
= XCreateWindow( display
, rootWindow
, x
, y
,
451 width
, height
, 0, CopyFromParent
,
452 InputOutput
, CopyFromParent
,
453 CWEventMask
| CWOverrideRedirect
|
454 CWColormap
| CWCursor
| CWSaveUnder
|
455 CWBackingStore
, &win_attr
);
456 XStoreName( display
, wndPtr
->window
, windowName
);
457 EVENT_RegisterWindow( wndPtr
->window
, hwnd
);
458 GlobalUnlock( hCursor
);
461 dprintf_menu(stddeb
,"CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n",
462 menu
, instance
, classPtr
->wc
.lpszMenuName
);
464 if ((style
& WS_CAPTION
) && (style
& WS_CHILD
) == 0) {
468 if (classPtr
->wc
.lpszMenuName
!= NULL
)
469 SetMenu(hwnd
, LoadMenu(instance
, classPtr
->wc
.lpszMenuName
));
473 wndPtr
->wIDmenu
= menu
;
475 /* Send the WM_CREATE message */
477 hcreateStruct
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, sizeof(CREATESTRUCT
) );
478 createStruct
= (CREATESTRUCT
*) USER_HEAP_ADDR( hcreateStruct
);
479 createStruct
->lpCreateParams
= data
;
480 createStruct
->hInstance
= instance
;
481 createStruct
->hMenu
= menu
;
482 createStruct
->hwndParent
= parent
;
483 createStruct
->cx
= width
;
484 createStruct
->cy
= height
;
487 createStruct
->style
= style
;
488 createStruct
->lpszName
= windowName
;
489 createStruct
->lpszClass
= className
;
490 createStruct
->dwExStyle
= 0;
492 wmcreate
= SendMessage( hwnd
, WM_NCCREATE
, 0, (LONG
)createStruct
);
493 if (!wmcreate
) wmcreate
= -1;
496 WINPOS_SendNCCalcSize( hwnd
, FALSE
, &wndPtr
->rectWindow
,
497 NULL
, NULL
, NULL
, &wndPtr
->rectClient
);
498 wmcreate
= SendMessage( hwnd
, WM_CREATE
, 0, (LONG
)createStruct
);
501 USER_HEAP_FREE( hcreateStruct
);
505 /* Abort window creation */
506 WIN_DestroyWindow( hwnd
);
510 /* Create a copy of SysMenu */
511 if (style
& WS_SYSMENU
) wndPtr
->hSysMenu
= CopySysMenu();
513 /* Register window in current task windows list */
514 AddWindowToTask(GetCurrentTask(), hwnd
);
516 WIN_SendParentNotify( hwnd
, WM_CREATE
, MAKELONG( hwnd
, wndPtr
->wIDmenu
) );
518 if (style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
519 /* if (style & WS_MINIMIZE) ShowWindow( hwnd, SW_MINIMIZE ); */
521 dprintf_win(stddeb
, "CreateWindowEx: return %04X \n", hwnd
);
526 /***********************************************************************
527 * DestroyWindow (USER.53)
529 BOOL
DestroyWindow( HWND hwnd
)
534 dprintf_win(stddeb
, "DestroyWindow (%04x)\n", hwnd
);
538 if (hwnd
== hwndDesktop
) return FALSE
; /* Can't destroy desktop */
539 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
540 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return FALSE
;
542 /* Hide the window */
544 if (wndPtr
->dwStyle
& WS_VISIBLE
)
545 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, SWP_HIDEWINDOW
| SWP_NOACTIVATE
|
546 SWP_NOZORDER
| SWP_NOMOVE
| SWP_NOSIZE
);
547 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
549 WIN_SendParentNotify( hwnd
, WM_DESTROY
, MAKELONG(hwnd
, wndPtr
->wIDmenu
) );
551 /* Send destroy messages and destroy children */
553 SendMessage( hwnd
, WM_DESTROY
, 0, 0 );
554 while (wndPtr
->hwndChild
) /* The child removes itself from the list */
555 DestroyWindow( wndPtr
->hwndChild
);
556 SendMessage( hwnd
, WM_NCDESTROY
, 0, 0 );
558 /* Remove the window from current task windows list */
559 RemoveWindowFromTask(GetCurrentTask(), hwnd
);
561 /* Remove the window from the linked list */
562 WIN_UnlinkWindow( hwnd
);
564 /* Destroy the window */
566 WIN_DestroyWindow( hwnd
);
571 /***********************************************************************
572 * CloseWindow (USER.43)
574 void CloseWindow(HWND hWnd
)
576 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
577 if (wndPtr
->dwStyle
& WS_CHILD
) return;
578 ShowWindow(hWnd
, SW_MINIMIZE
);
583 /***********************************************************************
586 BOOL
OpenIcon(HWND hWnd
)
588 if (!IsIconic(hWnd
)) return FALSE
;
589 ShowWindow(hWnd
, SW_SHOWNORMAL
);
595 /***********************************************************************
596 * FindWindow (USER.50)
598 HWND
FindWindow(LPSTR ClassMatch
, LPSTR TitleMatch
)
606 hclass
= CLASS_FindClassByName( ClassMatch
, &classPtr
);
607 if (!hclass
) return 0;
611 hwnd
= GetTopWindow( hwndDesktop
);
614 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
615 if (!hclass
|| (wndPtr
->hClass
== hclass
))
617 /* Found matching class */
618 if (!TitleMatch
) return hwnd
;
621 char *textPtr
= (char *) USER_HEAP_ADDR( wndPtr
->hText
);
622 if (!strcmp( textPtr
, TitleMatch
)) return hwnd
;
625 hwnd
= wndPtr
->hwndNext
;
631 /**********************************************************************
632 * GetDesktopWindow (USER.286)
633 * GetDeskTopHwnd (USER.278)
635 HWND
GetDesktopWindow(void)
641 /*******************************************************************
642 * EnableWindow (USER.34)
644 BOOL
EnableWindow( HWND hwnd
, BOOL enable
)
648 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
649 if (enable
&& (wndPtr
->dwStyle
& WS_DISABLED
))
652 wndPtr
->dwStyle
&= ~WS_DISABLED
;
653 SendMessage( hwnd
, WM_ENABLE
, TRUE
, 0 );
656 else if (!enable
&& !(wndPtr
->dwStyle
& WS_DISABLED
))
659 wndPtr
->dwStyle
|= WS_DISABLED
;
660 if ((hwnd
== GetFocus()) || IsChild( hwnd
, GetFocus() ))
661 SetFocus( 0 ); /* A disabled window can't have the focus */
662 if ((hwnd
== GetCapture()) || IsChild( hwnd
, GetCapture() ))
663 ReleaseCapture(); /* A disabled window can't capture the mouse */
664 SendMessage( hwnd
, WM_ENABLE
, FALSE
, 0 );
667 return ((wndPtr
->dwStyle
& WS_DISABLED
) != 0);
671 /***********************************************************************
672 * IsWindowEnabled (USER.35)
674 BOOL
IsWindowEnabled(HWND hWnd
)
678 if (!(wndPtr
= WIN_FindWndPtr(hWnd
))) return FALSE
;
679 return !(wndPtr
->dwStyle
& WS_DISABLED
);
683 /**********************************************************************
684 * GetWindowWord (USER.133)
686 WORD
GetWindowWord( HWND hwnd
, short offset
)
688 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
689 if (!wndPtr
) return 0;
690 if (offset
>= 0) return *(WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
693 case GWW_ID
: return wndPtr
->wIDmenu
;
694 case GWW_HWNDPARENT
: return wndPtr
->hwndParent
;
695 case GWW_HINSTANCE
: return wndPtr
->hInstance
;
701 /**********************************************************************
702 * SetWindowWord (USER.134)
704 WORD
SetWindowWord( HWND hwnd
, short offset
, WORD newval
)
707 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
708 if (!wndPtr
) return 0;
709 if (offset
>= 0) ptr
= (WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
712 case GWW_ID
: ptr
= &wndPtr
->wIDmenu
;
713 case GWW_HINSTANCE
: ptr
= &wndPtr
->hInstance
;
722 /**********************************************************************
723 * GetWindowLong (USER.135)
725 LONG
GetWindowLong( HWND hwnd
, short offset
)
727 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
728 if (!wndPtr
) return 0;
729 if (offset
>= 0) return *(LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
732 case GWL_STYLE
: return wndPtr
->dwStyle
;
733 case GWL_EXSTYLE
: return wndPtr
->dwExStyle
;
734 case GWL_WNDPROC
: return (LONG
)wndPtr
->lpfnWndProc
;
740 /**********************************************************************
741 * SetWindowLong (USER.136)
743 LONG
SetWindowLong( HWND hwnd
, short offset
, LONG newval
)
746 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
747 if (!wndPtr
) return 0;
748 if (offset
>= 0) ptr
= (LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
751 case GWL_STYLE
: ptr
= &wndPtr
->dwStyle
;
753 case GWL_EXSTYLE
: ptr
= &wndPtr
->dwExStyle
;
755 case GWL_WNDPROC
: ptr
= (LONG
*)(&wndPtr
->lpfnWndProc
);
765 /*******************************************************************
766 * GetWindowText (USER.36)
768 int GetWindowText(HWND hwnd
, LPSTR lpString
, int nMaxCount
)
770 return (int)SendMessage(hwnd
, WM_GETTEXT
, (WORD
)nMaxCount
,
774 /*******************************************************************
775 * SetWindowText (USER.37)
777 void SetWindowText(HWND hwnd
, LPSTR lpString
)
779 SendMessage(hwnd
, WM_SETTEXT
, (WORD
)NULL
, (DWORD
)lpString
);
782 /*******************************************************************
783 * GetWindowTextLength (USER.38)
785 int GetWindowTextLength(HWND hwnd
)
787 return (int)SendMessage(hwnd
, WM_GETTEXTLENGTH
, (WORD
)NULL
,
792 /*******************************************************************
795 BOOL
IsWindow( HWND hwnd
)
797 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
798 return ((wndPtr
!= NULL
) && (wndPtr
->dwMagic
== WND_MAGIC
));
802 /*****************************************************************
803 * GetParent (USER.46)
805 HWND
GetParent(HWND hwnd
)
807 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
808 if (!wndPtr
|| !(wndPtr
->dwStyle
& WS_CHILD
)) return 0;
809 return wndPtr
->hwndParent
;
812 /*****************************************************************
813 * SetParent (USER.233)
815 HWND
SetParent(HWND hwndChild
, HWND hwndNewParent
)
819 WND
*wndPtr
= WIN_FindWndPtr(hwndChild
);
820 if (!wndPtr
|| !(wndPtr
->dwStyle
& WS_CHILD
)) return 0;
822 temp
= wndPtr
->hwndParent
;
825 wndPtr
->hwndParent
= hwndNewParent
;
827 wndPtr
->hwndParent
= GetDesktopWindow();
834 /*******************************************************************
837 BOOL
IsChild( HWND parent
, HWND child
)
839 WND
* wndPtr
= WIN_FindWndPtr( child
);
840 while (wndPtr
&& (wndPtr
->dwStyle
& WS_CHILD
))
842 if (wndPtr
->hwndParent
== parent
) return TRUE
;
843 wndPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
849 /***********************************************************************
850 * IsWindowVisible (USER.49)
852 BOOL
IsWindowVisible(HWND hWnd
)
854 WND
* wndPtr
= WIN_FindWndPtr(hWnd
);
855 if (wndPtr
== 0) return(FALSE
);
856 else return ((wndPtr
->dwStyle
& WS_VISIBLE
) != 0);
861 /*******************************************************************
862 * GetTopWindow (USER.229)
864 HWND
GetTopWindow( HWND hwnd
)
866 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
867 if (wndPtr
) return wndPtr
->hwndChild
;
872 /*******************************************************************
873 * GetWindow (USER.262)
875 HWND
GetWindow( HWND hwnd
, WORD rel
)
877 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
878 if (!wndPtr
) return 0;
882 if (wndPtr
->hwndParent
)
884 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
885 return parentPtr
->hwndChild
;
890 if (!wndPtr
->hwndParent
) return 0; /* Desktop window */
891 while (wndPtr
->hwndNext
)
893 hwnd
= wndPtr
->hwndNext
;
894 wndPtr
= WIN_FindWndPtr( hwnd
);
899 return wndPtr
->hwndNext
;
905 if (wndPtr
->hwndParent
)
907 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
908 hwndPrev
= parentPtr
->hwndChild
;
910 else return 0; /* Desktop window */
911 if (hwndPrev
== hwnd
) return 0;
914 wndPtr
= WIN_FindWndPtr( hwndPrev
);
915 if (wndPtr
->hwndNext
== hwnd
) break;
916 hwndPrev
= wndPtr
->hwndNext
;
922 return wndPtr
->hwndOwner
;
925 return wndPtr
->hwndChild
;
931 /*******************************************************************
932 * GetNextWindow (USER.230)
934 HWND
GetNextWindow( HWND hwnd
, WORD flag
)
936 if ((flag
!= GW_HWNDNEXT
) && (flag
!= GW_HWNDPREV
)) return 0;
937 return GetWindow( hwnd
, flag
);
942 /*******************************************************************
943 * GetLastActivePopup (USER.287)
945 HWND
GetLastActivePopup(HWND hwnd
)
948 wndPtr
= WIN_FindWndPtr(hwnd
);
949 if (wndPtr
== NULL
) return hwnd
;
950 return wndPtr
->hwndLastActive
;
954 /*******************************************************************
955 * EnumWindows (USER.54)
957 * o gets the desktop window and iterates over all the windows
958 * which are direct decendents of the desktop * by iterating over
959 * the desktop's child window and all the child windows next
962 * o call wndenumprc for every child window the desktop has
963 * (parameters to Callback16 passed backwards so they are
964 * put in in pascal calling order)
966 * o if wndenumprc returns 0 exit
969 BOOL
EnumWindows(FARPROC wndenumprc
, LPARAM lParam
)
971 HWND hwnd
= GetTopWindow( GetDesktopWindow() );
975 dprintf_enum(stddeb
,"EnumWindows\n");
980 if ( !(wndPtr
=WIN_FindWndPtr(hwnd
)) ) {
984 (*wndenumprc
)(hwnd
, lParam
);
986 result
= CallBack16(wndenumprc
, 2,
987 CALLBACK_SIZE_WORD
, (int) hwnd
,
988 CALLBACK_SIZE_LONG
, lParam
);
993 hwnd
=wndPtr
->hwndNext
;
995 return 1; /* for now */
998 /*******************************************************************
1001 * o hwnd is the first child to use, loop until all next windows
1004 * o call wdnenumprc with parameters in inverse order (pascal)
1006 * o call ourselves with the next child window
1009 static BOOL
WIN_EnumChildWin(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1017 if ( !(wndPtr
=WIN_FindWndPtr(hwnd
)) ) {
1021 if (!(*wndenumprc
)( 2, lParam
, (int) hwnd
)) {
1023 if (!CallBack16(wndenumprc
, 2,
1024 CALLBACK_SIZE_WORD
, (int) hwnd
,
1025 CALLBACK_SIZE_LONG
, lParam
)) {
1029 if (!WIN_EnumChildWin(wndPtr
->hwndChild
, wndenumprc
, lParam
)) {
1032 hwnd
=wndPtr
->hwndNext
;
1037 /*******************************************************************
1038 * EnumChildWindows (USER.55)
1040 * o gets the first child of hwnd
1042 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1044 BOOL
EnumChildWindows(HWND hwnd
, FARPROC wndenumprc
, LPARAM lParam
)
1048 dprintf_enum(stddeb
,"EnumChildWindows\n");
1050 if (hwnd
== 0) return 0;
1051 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1052 hwnd
= wndPtr
->hwndChild
;
1053 return WIN_EnumChildWin(hwnd
, wndenumprc
, lParam
);
1056 /*******************************************************************
1057 * AnyPopup [USER.52]
1061 dprintf_win(stdnimp
,"EMPTY STUB !! AnyPopup !\n");
1065 /*******************************************************************
1066 * FlashWindow [USER.105]
1068 BOOL
FlashWindow(HWND hWnd
, BOOL bInvert
)
1070 dprintf_win(stdnimp
,"EMPTY STUB !! FlashWindow !\n");
1075 /*******************************************************************
1076 * SetSysModalWindow [USER.188]
1078 HWND
SetSysModalWindow(HWND hWnd
)
1080 HWND hWndOldModal
= hWndSysModal
;
1081 hWndSysModal
= hWnd
;
1082 dprintf_win(stdnimp
,"EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd
);
1083 return hWndOldModal
;
1087 /*******************************************************************
1088 * GetSysModalWindow [USER.189]
1090 HWND
GetSysModalWindow(void)
1092 return hWndSysModal
;