2 * Window related functions
4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
9 #include <X11/Intrinsic.h>
10 #include <X11/StringDefs.h>
12 #include <X11/Shell.h>
13 #include <X11/Xaw/Box.h>
19 extern Display
* XT_display
;
20 extern Screen
* XT_screen
;
21 extern Colormap COLOR_WinColormap
;
23 static HWND firstWindow
= 0;
25 void SCROLLBAR_CreateScrollBar(LPSTR className
, LPSTR Label
, HWND hwnd
);
26 void LISTBOX_CreateListBox(LPSTR className
, LPSTR Label
, HWND hwnd
);
27 void COMBOBOX_CreateComboBox(LPSTR className
, LPSTR Label
, HWND hwnd
);
29 /***********************************************************************
32 * Return a pointer to the WND structure corresponding to a HWND.
34 WND
* WIN_FindWndPtr( HWND hwnd
)
38 if (!hwnd
) return NULL
;
39 ptr
= (WND
*) USER_HEAP_ADDR( hwnd
);
40 if (ptr
->dwMagic
!= WND_MAGIC
) return NULL
;
45 /***********************************************************************
46 * WIN_FindWinToRepaint
48 * Find a window that needs repaint.
50 HWND
WIN_FindWinToRepaint( HWND hwnd
)
54 if (!hwnd
) hwnd
= firstWindow
;
57 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
58 if (wndPtr
->hrgnUpdate
) return hwnd
;
59 if (wndPtr
->hwndChild
)
62 if ((child
= WIN_FindWinToRepaint( wndPtr
->hwndChild
)))
65 hwnd
= wndPtr
->hwndNext
;
71 /***********************************************************************
72 * WIN_SendParentNotify
74 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
75 * the window has the WS_EX_NOPARENTNOTIFY style.
77 static void WIN_SendParentNotify( HWND hwnd
, WND
* wndPtr
, WORD event
)
79 HWND current
= wndPtr
->hwndParent
;
81 if (wndPtr
->dwExStyle
& WS_EX_NOPARENTNOTIFY
) return;
84 SendMessage( current
, WM_PARENTNOTIFY
,
85 event
, MAKELONG( hwnd
, wndPtr
->wIDmenu
) );
86 current
= GetParent( current
);
91 /***********************************************************************
92 * CreateWindow (USER.41)
94 HWND
CreateWindow( LPSTR className
, LPSTR windowName
,
95 DWORD style
, short x
, short y
, short width
, short height
,
96 HWND parent
, HMENU menu
, HANDLE instance
, LPSTR data
)
98 return CreateWindowEx( 0, className
, windowName
, style
,
99 x
, y
, width
, height
, parent
, menu
, instance
, data
);
103 /***********************************************************************
104 * CreateWindowEx (USER.452)
106 HWND
CreateWindowEx( DWORD exStyle
, LPSTR className
, LPSTR windowName
,
107 DWORD style
, short x
, short y
, short width
, short height
,
108 HWND parent
, HMENU menu
, HANDLE instance
, LPSTR data
)
112 WND
*wndPtr
, *parentPtr
= NULL
;
113 CREATESTRUCT
*createStruct
;
114 HANDLE hcreateStruct
;
118 printf( "CreateWindowEx: %s %s %d,%d %dx%d\n", className
, windowName
, x
, y
, width
, height
);
121 if (x
== CW_USEDEFAULT
) x
= 0;
122 if (y
== CW_USEDEFAULT
) y
= 0;
123 if (width
== CW_USEDEFAULT
) width
= 600;
124 if (height
== CW_USEDEFAULT
) height
= 400;
125 if (!width
) width
= 1;
126 if (!height
) height
= 1;
128 /* Find the parent and class */
132 /* Check if parent is valid */
133 parentPtr
= WIN_FindWndPtr( parent
);
134 if (!parent
) return 0;
136 else if (style
& WS_CHILD
) return 0; /* WS_CHILD needs a parent */
138 if (!(class = CLASS_FindClassByName( className
, &classPtr
)))
141 /* Create the window structure */
143 hwnd
= USER_HEAP_ALLOC(GMEM_MOVEABLE
, sizeof(WND
)+classPtr
->wc
.cbWndExtra
);
146 /* Fill the structure */
148 wndPtr
= (WND
*) USER_HEAP_ADDR( hwnd
);
149 wndPtr
->hwndNext
= 0;
150 wndPtr
->hwndChild
= 0;
151 wndPtr
->dwMagic
= WND_MAGIC
;
152 wndPtr
->hwndParent
= parent
;
153 wndPtr
->hwndOwner
= parent
; /* What else? */
154 wndPtr
->hClass
= class;
155 wndPtr
->hInstance
= instance
;
156 wndPtr
->rectClient
.left
= x
;
157 wndPtr
->rectClient
.top
= y
;
158 wndPtr
->rectClient
.right
= x
+ width
;
159 wndPtr
->rectClient
.bottom
= y
+ height
;
160 wndPtr
->rectWindow
= wndPtr
->rectClient
;
161 wndPtr
->hrgnUpdate
= 0;
162 wndPtr
->hwndLastActive
= 0;
163 wndPtr
->lpfnWndProc
= classPtr
->wc
.lpfnWndProc
;
164 wndPtr
->dwStyle
= style
;
165 wndPtr
->dwExStyle
= exStyle
;
166 wndPtr
->hmenuSystem
= 0;
167 wndPtr
->wIDmenu
= menu
;
171 if (classPtr
->wc
.cbWndExtra
)
172 memset( wndPtr
->wExtra
, 0, classPtr
->wc
.cbWndExtra
);
173 if (classPtr
->wc
.style
& CS_OWNDC
)
174 wndPtr
->hdc
= CreateDC( "DISPLAY", NULL
, NULL
, NULL
);
175 else wndPtr
->hdc
= 0;
176 classPtr
->cWindows
++;
178 /* Insert the window in the linked list */
182 wndPtr
->hwndNext
= parentPtr
->hwndChild
;
183 parentPtr
->hwndChild
= hwnd
;
185 else /* Top-level window */
187 wndPtr
->hwndNext
= firstWindow
;
191 if (!strcasecmp(className
, "SCROLLBAR"))
193 SCROLLBAR_CreateScrollBar(className
, windowName
, hwnd
);
196 if (!strcasecmp(className
, "LISTBOX"))
198 LISTBOX_CreateListBox(className
, windowName
, hwnd
);
201 if (!strcasecmp(className
, "COMBOBOX"))
203 COMBOBOX_CreateComboBox(className
, windowName
, hwnd
);
206 /* Create the widgets */
208 if (style
& WS_CHILD
)
210 wndPtr
->shellWidget
= 0;
211 if (style
& (WS_BORDER
| WS_DLGFRAME
| WS_THICKFRAME
))
214 if (COLOR_WinColormap
== DefaultColormapOfScreen(XT_screen
))
215 borderCol
= BlackPixelOfScreen(XT_screen
);
216 wndPtr
->winWidget
= XtVaCreateManagedWidget(className
,
217 compositeWidgetClass
,
218 parentPtr
->winWidget
,
223 XtNborderColor
, borderCol
,
228 wndPtr
->winWidget
= XtVaCreateManagedWidget(className
,
229 compositeWidgetClass
,
230 parentPtr
->winWidget
,
241 wndPtr
->shellWidget
= XtVaAppCreateShell(windowName
,
243 topLevelShellWidgetClass
,
247 XtNcolormap
, COLOR_WinColormap
,
249 wndPtr
->compositeWidget
= XtVaCreateManagedWidget(className
,
253 if (wndPtr
->wIDmenu
== 0)
256 MENU_CreateMenuBar(wndPtr
->compositeWidget
,
258 classPtr
->wc
.lpszMenuName
,
260 if (wndPtr
->menuBarPtr
)
262 GlobalHandleFromPointer(wndPtr
->menuBarPtr
->firstItem
);
266 wndPtr
->menuBarPtr
= MENU_UseMenu(wndPtr
->compositeWidget
,
268 wndPtr
->wIDmenu
, width
);
271 if (wndPtr
->menuBarPtr
!= NULL
)
274 XtVaCreateManagedWidget(className
,
275 compositeWidgetClass
,
276 wndPtr
->compositeWidget
,
280 wndPtr
->menuBarPtr
->menuBarWidget
,
287 XtVaCreateManagedWidget(className
,
288 compositeWidgetClass
,
289 wndPtr
->compositeWidget
,
298 /* Send the WM_CREATE message */
300 hcreateStruct
= GlobalAlloc( GMEM_MOVEABLE
, sizeof(CREATESTRUCT
) );
301 createStruct
= (CREATESTRUCT
*) GlobalLock( hcreateStruct
);
302 createStruct
->lpCreateParams
= data
;
303 createStruct
->hInstance
= instance
;
304 createStruct
->hMenu
= menu
;
305 createStruct
->hwndParent
= parent
;
306 createStruct
->cx
= width
;
307 createStruct
->cy
= height
;
310 createStruct
->style
= style
;
311 createStruct
->lpszName
= windowName
;
312 createStruct
->lpszClass
= className
;
313 createStruct
->dwExStyle
= 0;
315 wmcreate
= SendMessage( hwnd
, WM_NCCREATE
, 0, (LONG
)createStruct
);
316 if (!wmcreate
) wmcreate
= -1;
317 else wmcreate
= SendMessage( hwnd
, WM_CREATE
, 0, (LONG
)createStruct
);
319 GlobalUnlock( hcreateStruct
);
320 GlobalFree( hcreateStruct
);
324 /* Abort window creation */
325 if (wndPtr
->shellWidget
) XtDestroyWidget( wndPtr
->shellWidget
);
326 else XtDestroyWidget( wndPtr
->winWidget
);
327 USER_HEAP_FREE( hwnd
);
331 EVENT_AddHandlers( wndPtr
->winWidget
, hwnd
);
333 if (style
& WS_VISIBLE
) ShowWindow( hwnd
, SW_SHOW
);
334 WIN_SendParentNotify( hwnd
, wndPtr
, WM_CREATE
);
338 /***********************************************************************
339 * DestroyWindow (USER.53)
341 BOOL
DestroyWindow( HWND hwnd
)
349 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return FALSE
;
350 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return FALSE
;
351 WIN_SendParentNotify( hwnd
, wndPtr
, WM_DESTROY
);
353 /* Send destroy messages */
355 SendMessage( hwnd
, WM_DESTROY
, 0, 0 );
356 SendMessage( hwnd
, WM_NCDESTROY
, 0, 0 );
358 /* Destroy all children */
360 while (wndPtr
->hwndChild
) /* The child removes itself from the list */
361 DestroyWindow( wndPtr
->hwndChild
);
363 /* Remove the window from the linked list */
365 if (wndPtr
->hwndParent
)
367 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
368 curWndPtr
= &parentPtr
->hwndChild
;
370 else curWndPtr
= &firstWindow
;
372 while (*curWndPtr
!= hwnd
)
374 WND
* curPtr
= WIN_FindWndPtr( *curWndPtr
);
375 curWndPtr
= &curPtr
->hwndNext
;
377 *curWndPtr
= wndPtr
->hwndNext
;
379 /* Destroy the window */
381 if (wndPtr
->shellWidget
) XtDestroyWidget( wndPtr
->shellWidget
);
382 else XtDestroyWidget( wndPtr
->winWidget
);
383 if (wndPtr
->hdc
) DeleteDC( wndPtr
->hdc
);
384 classPtr
->cWindows
--;
385 USER_HEAP_FREE( hwnd
);
390 /***********************************************************************
391 * GetWindowRect (USER.32)
393 void GetWindowRect( HWND hwnd
, LPRECT rect
)
395 int x
, y
, width
, height
;
396 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
400 XtVaGetValues(wndPtr
->winWidget
,
405 rect
->left
= x
& 0xffff;
406 rect
->top
= y
& 0xffff;
407 rect
->right
= width
& 0xffff;
408 rect
->bottom
= height
& 0xffff;
413 /***********************************************************************
414 * GetClientRect (USER.33)
416 void GetClientRect( HWND hwnd
, LPRECT rect
)
419 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
421 rect
->left
= rect
->top
= rect
->right
= rect
->bottom
= 0;
424 XtVaGetValues(wndPtr
->winWidget
,
428 rect
->right
= width
& 0xffff;
429 rect
->bottom
= height
& 0xffff;
434 /***********************************************************************
435 * ShowWindow (USER.42)
437 BOOL
ShowWindow( HWND hwnd
, int cmd
)
441 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
444 if (wndPtr
->shellWidget
) XtRealizeWidget( wndPtr
->shellWidget
);
445 XtVaGetValues(wndPtr
->winWidget
,
449 SendMessage( hwnd
, WM_SIZE
, SIZE_RESTORED
,
450 (width
& 0xffff) | (height
<< 16) );
451 SendMessage( hwnd
, WM_SHOWWINDOW
, TRUE
, 0 );
453 printf("ShowWindow(%X, %X); !\n", hwnd, cmd);
458 XtSetMappedWhenManaged(wndPtr
->winWidget
, FALSE
);
461 case SW_SHOWMINNOACTIVE
:
462 case SW_SHOWNOACTIVATE
:
465 case SW_SHOWMAXIMIZED
:
466 case SW_SHOWMINIMIZED
:
470 XtSetMappedWhenManaged(wndPtr
->winWidget
, TRUE
);
480 /***********************************************************************
481 * MoveWindow (USER.56)
483 void MoveWindow(HWND hWnd
, short x
, short y
, short w
, short h
, BOOL bRepaint
)
485 WND
* wndPtr
= WIN_FindWndPtr( hWnd
);
488 wndPtr
->rectClient
.left
= x
;
489 wndPtr
->rectClient
.top
= y
;
490 wndPtr
->rectClient
.right
= x
+ w
;
491 wndPtr
->rectClient
.bottom
= y
+ h
;
492 XtVaSetValues(wndPtr
->winWidget
, XtNx
, x
, XtNy
, y
,
493 XtNwidth
, w
, XtNheight
, h
, NULL
);
494 SendMessage(hWnd
, WM_MOVE
, 0, MAKELONG(x
, y
));
495 printf("MoveWindow(%X, %d, %d, %d, %d, %d); !\n",
496 hWnd
, x
, y
, w
, h
, bRepaint
);
498 InvalidateRect(hWnd
, NULL
, TRUE
);
505 /***********************************************************************
506 * UpdateWindow (USER.124)
508 void UpdateWindow( HWND hwnd
)
510 if (GetUpdateRect( hwnd
, NULL
, FALSE
))
511 SendMessage( hwnd
, WM_PAINT
, 0, 0 );
514 /**********************************************************************
517 HMENU
GetMenu( HWND hwnd
)
519 WND
* wndPtr
= WIN_FindWndPtr(hwnd
);
522 return wndPtr
->wIDmenu
;
525 /**********************************************************************
528 BOOL
SetMenu(HWND hwnd
, HMENU hmenu
)
532 wndPtr
= WIN_FindWndPtr(hwnd
);
536 if (wndPtr
->dwStyle
& WS_CHILD
) return FALSE
;
538 if (wndPtr
->menuBarPtr
!= NULL
)
540 XtVaSetValues(wndPtr
->winWidget
, XtNfromVert
, NULL
, NULL
);
541 MENU_CollapseMenu(wndPtr
->menuBarPtr
);
544 wndPtr
->menuBarPtr
= MENU_UseMenu(wndPtr
->compositeWidget
,
545 wndPtr
->hInstance
, hwnd
, hmenu
,
546 wndPtr
->rectClient
.right
-
547 wndPtr
->rectClient
.left
);
549 if (wndPtr
->menuBarPtr
!= NULL
)
551 XtVaSetValues(wndPtr
->winWidget
,
552 XtNfromVert
, wndPtr
->menuBarPtr
->menuBarWidget
,
558 if (wndPtr
->wIDmenu
!= 0)
560 wndPtr
->menuBarPtr
= MENU_UseMenu(wndPtr
->compositeWidget
,
561 wndPtr
->hInstance
, hwnd
,
563 wndPtr
->rectClient
.right
-
564 wndPtr
->rectClient
.left
);
573 /***********************************************************************
574 * SetWindowPos (USER.232)
576 void SetWindowPos(HWND hWnd
, HWND hWndInsertAfter
, short x
, short y
, short w
, short h
, WORD wFlag
)
578 WND
* wndPtr
= WIN_FindWndPtr( hWnd
);
581 if ((wFlag
& SWP_NOMOVE
) == 0) {
582 wndPtr
->rectClient
.left
= x
;
583 wndPtr
->rectClient
.top
= y
;
584 XtVaSetValues(wndPtr
->winWidget
, XtNx
, x
, XtNy
, y
, NULL
);
586 if ((wFlag
& SWP_NOSIZE
) == 0) {
587 wndPtr
->rectClient
.right
= x
+ w
;
588 wndPtr
->rectClient
.bottom
= y
+ h
;
589 XtVaSetValues(wndPtr
->winWidget
, XtNwidth
, w
, XtNheight
, h
, NULL
);
591 if ((wFlag
& SWP_NOREDRAW
) == 0) {
592 InvalidateRect(hWnd
, NULL
, TRUE
);
595 if ((wFlag
& SWP_HIDEWINDOW
) == SWP_HIDEWINDOW
)
596 ShowWindow(hWnd
, SW_HIDE
);
597 if ((wFlag
& SWP_SHOWWINDOW
) == SWP_SHOWWINDOW
)
598 ShowWindow(hWnd
, SW_SHOW
);
600 if ((wFlag & SWP_NOACTIVATE) == 0)
601 SetActiveWindow(hWnd);
603 printf("SetWindowPos(%X, %X, %d, %d, %d, %d, %X); !\n",
604 hWnd
, hWndInsertAfter
, x
, y
, w
, h
, wFlag
);
609 /**********************************************************************
610 * GetDesktopWindow (USER.286)
612 HWND
GetDesktopWindow()
619 /**********************************************************************
620 * GetWindowWord (USER.133)
622 WORD
GetWindowWord( HWND hwnd
, short offset
)
624 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
625 if (!wndPtr
) return 0;
626 if (offset
>= 0) return *(WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
629 case GWW_ID
: return wndPtr
->wIDmenu
;
630 case GWW_HWNDPARENT
: return wndPtr
->hwndParent
;
631 case GWW_HINSTANCE
: return wndPtr
->hInstance
;
637 /**********************************************************************
638 * SetWindowWord (USER.134)
640 WORD
SetWindowWord( HWND hwnd
, short offset
, WORD newval
)
643 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
644 if (!wndPtr
) return 0;
645 if (offset
>= 0) ptr
= (WORD
*)(((char *)wndPtr
->wExtra
) + offset
);
648 case GWW_ID
: ptr
= &wndPtr
->wIDmenu
;
649 case GWW_HINSTANCE
: ptr
= &wndPtr
->hInstance
;
658 /**********************************************************************
659 * GetWindowLong (USER.135)
661 LONG
GetWindowLong( HWND hwnd
, short offset
)
663 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
664 if (!wndPtr
) return 0;
665 if (offset
>= 0) return *(LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
668 case GWL_STYLE
: return wndPtr
->dwStyle
;
669 case GWL_EXSTYLE
: return wndPtr
->dwExStyle
;
670 case GWL_WNDPROC
: return (LONG
)wndPtr
->lpfnWndProc
;
676 /**********************************************************************
677 * SetWindowLong (USER.136)
679 LONG
SetWindowLong( HWND hwnd
, short offset
, LONG newval
)
682 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
683 if (!wndPtr
) return 0;
684 if (offset
>= 0) ptr
= (LONG
*)(((char *)wndPtr
->wExtra
) + offset
);
687 case GWL_STYLE
: ptr
= &wndPtr
->dwStyle
;
688 case GWL_EXSTYLE
: ptr
= &wndPtr
->dwExStyle
;
689 case GWL_WNDPROC
: ptr
= (LONG
*)(&wndPtr
->lpfnWndProc
);
698 /*****************************************************************
699 * GetParent (USER.46)
701 HWND
GetParent(HWND hwnd
)
703 WND
*wndPtr
= WIN_FindWndPtr(hwnd
);
704 return wndPtr
->hwndParent
;
708 /*******************************************************************
709 * GetWindowText (USER.36)
711 int GetWindowText(HWND hwnd
, LPSTR lpString
, int nMaxCount
)
713 return (int)SendMessage(hwnd
, WM_GETTEXT
, (WORD
)nMaxCount
,
717 /*******************************************************************
718 * SetWindowText (USER.37)
720 void SetWindowText(HWND hwnd
, LPSTR lpString
)
722 SendMessage(hwnd
, WM_SETTEXT
, (WORD
)NULL
, (DWORD
)lpString
);
725 /*******************************************************************
726 * GetWindowTextLength (USER.38)
728 int GetWindowTextLength(HWND hwnd
)
730 return (int)SendMessage(hwnd
, WM_GETTEXTLENGTH
, (WORD
)NULL
,
735 /*******************************************************************
738 BOOL
IsChild( HWND parent
, HWND child
)
744 if (!(parentPtr
= WIN_FindWndPtr( parent
))) return FALSE
;
745 curChild
= parentPtr
->hwndChild
;
749 if (curChild
== child
) return TRUE
;
750 if (IsChild( curChild
, child
)) return TRUE
;
751 if (!(childPtr
= WIN_FindWndPtr( curChild
))) return FALSE
;
752 curChild
= childPtr
->hwndNext
;
758 /*******************************************************************
759 * GetTopWindow (USER.229)
761 HWND
GetTopWindow( HWND hwnd
)
763 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
764 if (wndPtr
) return wndPtr
->hwndChild
;
769 /*******************************************************************
770 * GetWindow (USER.262)
772 HWND
GetWindow( HWND hwnd
, WORD rel
)
774 WND
* wndPtr
= WIN_FindWndPtr( hwnd
);
775 if (!wndPtr
) return 0;
779 if (wndPtr
->hwndParent
)
781 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
782 return parentPtr
->hwndChild
;
784 else return firstWindow
;
787 while (wndPtr
->hwndNext
)
789 hwnd
= wndPtr
->hwndNext
;
790 wndPtr
= WIN_FindWndPtr( hwnd
);
795 return wndPtr
->hwndNext
;
801 if (wndPtr
->hwndParent
)
803 WND
* parentPtr
= WIN_FindWndPtr( wndPtr
->hwndParent
);
804 hwndPrev
= parentPtr
->hwndChild
;
806 else hwndPrev
= firstWindow
;
807 if (hwndPrev
== hwnd
) return 0;
810 wndPtr
= WIN_FindWndPtr( hwndPrev
);
811 if (wndPtr
->hwndNext
== hwnd
) break;
812 hwndPrev
= wndPtr
->hwndNext
;
818 return wndPtr
->hwndOwner
;
821 return wndPtr
->hwndChild
;
827 /*******************************************************************
828 * GetNextWindow (USER.230)
830 HWND
GetNextWindow( HWND hwnd
, WORD flag
)
832 if ((flag
!= GW_HWNDNEXT
) && (flag
!= GW_HWNDPREV
)) return 0;
833 return GetWindow( hwnd
, flag
);