Release 940201
[wine.git] / windows / win.c
blob5cef378027ca4897e8c1a5de8a32f109e77b0bb4
1 /*
2 * Window related functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
9 #include <X11/Intrinsic.h>
10 #include <X11/StringDefs.h>
11 #include <X11/Core.h>
12 #include <X11/Shell.h>
14 #include "class.h"
15 #include "win.h"
16 #include "user.h"
17 #include "dce.h"
18 #include "sysmetrics.h"
19 #include "scroll.h"
21 extern Display * display;
22 extern Colormap COLOR_WinColormap;
24 extern void EVENT_RegisterWindow( Window w, HWND hwnd ); /* event.c */
25 extern HMENU CopySysMenu(); /* menu.c */
27 HWND firstWindow = 0;
29 /***********************************************************************
30 * WIN_FindWndPtr
32 * Return a pointer to the WND structure corresponding to a HWND.
34 WND * WIN_FindWndPtr( HWND hwnd )
36 WND * ptr;
38 if (!hwnd) return NULL;
39 ptr = (WND *) USER_HEAP_ADDR( hwnd );
40 if (ptr->dwMagic != WND_MAGIC) return NULL;
41 return ptr;
45 /***********************************************************************
46 * WIN_UnlinkWindow
48 * Remove a window from the siblings linked list.
50 BOOL WIN_UnlinkWindow( HWND hwnd )
52 HWND * curWndPtr;
53 WND * wndPtr = WIN_FindWndPtr( hwnd );
55 if (!wndPtr) return FALSE;
56 if (wndPtr->hwndParent)
58 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
59 curWndPtr = &parentPtr->hwndChild;
61 else curWndPtr = &firstWindow;
63 while (*curWndPtr != hwnd)
65 WND * curPtr = WIN_FindWndPtr( *curWndPtr );
66 curWndPtr = &curPtr->hwndNext;
68 *curWndPtr = wndPtr->hwndNext;
69 return TRUE;
73 /***********************************************************************
74 * WIN_LinkWindow
76 * Insert a window into the siblings linked list.
77 * The window is inserted after the specified window, which can also
78 * be specified as HWND_TOP or HWND_BOTTOM.
80 BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
82 HWND * hwndPtr = NULL; /* pointer to hwnd to change */
84 WND * wndPtr = WIN_FindWndPtr( hwnd );
85 if (!wndPtr) return FALSE;
87 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
89 /* Make hwndPtr point to the first sibling hwnd */
90 if (wndPtr->hwndParent)
92 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
93 if (parentPtr) hwndPtr = &parentPtr->hwndChild;
95 else hwndPtr = &firstWindow;
96 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
97 while (*hwndPtr)
99 WND * nextPtr = WIN_FindWndPtr( *hwndPtr );
100 hwndPtr = &nextPtr->hwndNext;
103 else /* Normal case */
105 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
106 if (afterPtr) hwndPtr = &afterPtr->hwndNext;
108 if (!hwndPtr) return FALSE;
109 wndPtr->hwndNext = *hwndPtr;
110 *hwndPtr = hwnd;
111 return TRUE;
115 /***********************************************************************
116 * WIN_FindWinToRepaint
118 * Find a window that needs repaint.
120 HWND WIN_FindWinToRepaint( HWND hwnd )
122 WND * wndPtr;
124 if (!hwnd) hwnd = firstWindow;
125 for ( ; hwnd != 0; hwnd = wndPtr->hwndNext )
127 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
128 if (wndPtr->hrgnUpdate) return hwnd;
129 if (wndPtr->hwndChild)
131 HWND child;
132 if ((child = WIN_FindWinToRepaint( wndPtr->hwndChild )))
133 return child;
136 return 0;
140 /***********************************************************************
141 * WIN_SendParentNotify
143 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
144 * the window has the WS_EX_NOPARENTNOTIFY style.
146 static void WIN_SendParentNotify( HWND hwnd, WND * wndPtr, WORD event )
148 HWND current = wndPtr->hwndParent;
150 if (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY) return;
151 while (current)
153 SendMessage( current, WM_PARENTNOTIFY,
154 event, MAKELONG( hwnd, wndPtr->wIDmenu ) );
155 current = GetParent( current );
160 /***********************************************************************
161 * CreateWindow (USER.41)
163 HWND CreateWindow( LPSTR className, LPSTR windowName,
164 DWORD style, short x, short y, short width, short height,
165 HWND parent, HMENU menu, HANDLE instance, LPSTR data )
167 return CreateWindowEx( 0, className, windowName, style,
168 x, y, width, height, parent, menu, instance, data );
172 /***********************************************************************
173 * CreateWindowEx (USER.452)
175 HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
176 DWORD style, short x, short y, short width, short height,
177 HWND parent, HMENU menu, HANDLE instance, LPSTR data )
179 HANDLE class, hwnd;
180 CLASS *classPtr;
181 WND *wndPtr, *parentPtr = NULL;
182 CREATESTRUCT *createStruct;
183 HANDLE hcreateStruct;
184 int wmcreate;
185 XSetWindowAttributes win_attr;
186 Window parentWindow;
187 int x_rel, y_rel;
188 LPPOPUPMENU lpbar;
190 #ifdef DEBUG_WIN
191 printf( "CreateWindowEx: %d '%s' '%s' %d,%d %dx%d %08x %x\n",
192 exStyle, className, windowName, x, y, width, height, style, parent);
193 #endif
195 if (x == CW_USEDEFAULT) x = y = 0;
196 if (width == CW_USEDEFAULT)
198 width = 600;
199 height = 400;
201 if (width == 0) width = 1;
202 if (height == 0) height = 1;
204 /* Find the parent and class */
206 if (parent)
208 /* Check if parent is valid */
209 parentPtr = WIN_FindWndPtr( parent );
210 if (!parent) return 0;
212 else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */
214 if (!(class = CLASS_FindClassByName( className, &classPtr ))) {
215 printf("CreateWindow BAD CLASSNAME '%s' !\n", className);
216 return 0;
219 /* Correct the window style */
221 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
222 style |= WS_CAPTION | WS_CLIPSIBLINGS;
223 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
225 /* Create the window structure */
227 hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra);
228 if (!hwnd) return 0;
230 /* Fill the structure */
232 wndPtr = (WND *) USER_HEAP_ADDR( hwnd );
233 wndPtr->hwndNext = 0;
234 wndPtr->hwndChild = 0;
235 wndPtr->dwMagic = WND_MAGIC;
236 wndPtr->hwndParent = (style & WS_CHILD) ? parent : 0;
237 wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : parent;
238 wndPtr->hClass = class;
239 wndPtr->hInstance = instance;
240 wndPtr->rectWindow.left = x;
241 wndPtr->rectWindow.top = y;
242 wndPtr->rectWindow.right = x + width;
243 wndPtr->rectWindow.bottom = y + height;
244 wndPtr->rectClient = wndPtr->rectWindow;
245 wndPtr->rectNormal = wndPtr->rectWindow;
246 wndPtr->ptIconPos.x = -1;
247 wndPtr->ptIconPos.y = -1;
248 wndPtr->ptMaxPos.x = -1;
249 wndPtr->ptMaxPos.y = -1;
250 wndPtr->hmemTaskQ = GetTaskQueue(0);
251 wndPtr->hrgnUpdate = 0;
252 wndPtr->hwndLastActive = 0;
253 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
254 wndPtr->dwStyle = style;
255 wndPtr->dwExStyle = exStyle;
256 wndPtr->hmenuSystem = 0;
257 wndPtr->wIDmenu = menu;
258 wndPtr->hText = 0;
259 wndPtr->flags = 0;
260 wndPtr->hCursor = 0;
261 wndPtr->VScroll = NULL;
262 wndPtr->HScroll = NULL;
263 wndPtr->hSysMenu = 0;
264 wndPtr->hWndMenuBar = 0;
266 if (classPtr->wc.cbWndExtra)
267 memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
268 if (classPtr->wc.style & CS_DBLCLKS) wndPtr->flags |= WIN_DOUBLE_CLICKS;
269 classPtr->cWindows++;
271 /* Get class or window DC if needed */
272 if (classPtr->wc.style & CS_OWNDC)
274 wndPtr->flags |= WIN_OWN_DC;
275 wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC );
277 else if (classPtr->wc.style & CS_CLASSDC)
279 wndPtr->flags |= WIN_CLASS_DC;
280 wndPtr->hdce = classPtr->hdce;
282 else wndPtr->hdce = 0;
284 /* Insert the window in the linked list */
286 WIN_LinkWindow( hwnd, HWND_TOP );
288 /* Create the X window */
290 win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
291 PointerMotionMask | ButtonPressMask |
292 ButtonReleaseMask | FocusChangeMask | EnterWindowMask;
293 win_attr.override_redirect = True;
294 win_attr.colormap = COLOR_WinColormap;
295 if (style & WS_CHILD)
297 parentWindow = parentPtr->window;
298 x_rel = x + parentPtr->rectClient.left - parentPtr->rectWindow.left;
299 y_rel = y + parentPtr->rectClient.top - parentPtr->rectWindow.top;
301 else
303 parentWindow = DefaultRootWindow( display );
304 x_rel = x;
305 y_rel = y;
307 wndPtr->window = XCreateWindow(display, parentWindow,
308 x_rel, y_rel, width, height, 0,
309 CopyFromParent, InputOutput, CopyFromParent,
310 CWEventMask | CWOverrideRedirect |
311 CWColormap, &win_attr );
312 XStoreName( display, wndPtr->window, windowName );
314 /* Send the WM_CREATE message */
316 hcreateStruct = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CREATESTRUCT) );
317 createStruct = (CREATESTRUCT *) USER_HEAP_ADDR( hcreateStruct );
318 createStruct->lpCreateParams = data;
319 createStruct->hInstance = instance;
320 createStruct->hMenu = menu;
321 createStruct->hwndParent = parent;
322 createStruct->cx = width;
323 createStruct->cy = height;
324 createStruct->x = x;
325 createStruct->y = y;
326 createStruct->style = style;
327 createStruct->lpszName = windowName;
328 createStruct->lpszClass = className;
329 createStruct->dwExStyle = 0;
331 wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LONG)createStruct );
332 if (!wmcreate) wmcreate = -1;
333 else
335 /* Send WM_NCCALCSIZE message */
336 NCCALCSIZE_PARAMS *params;
337 HANDLE hparams;
338 hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) );
339 if (hparams)
341 params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams );
342 params->rgrc[0] = wndPtr->rectWindow;
343 params->lppos = NULL;
344 SendMessage( hwnd, WM_NCCALCSIZE, FALSE, (LONG)params );
345 wndPtr->rectClient = params->rgrc[0];
346 USER_HEAP_FREE( hparams );
348 wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct );
351 USER_HEAP_FREE( hcreateStruct );
353 if (wmcreate == -1)
355 /* Abort window creation */
357 WIN_UnlinkWindow( hwnd );
358 XDestroyWindow( display, wndPtr->window );
359 if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
360 classPtr->cWindows--;
361 USER_HEAP_FREE( hwnd );
362 return 0;
365 /* Create scrollbars */
367 if ((style & WS_SYSMENU) == WS_SYSMENU) {
368 wndPtr->hSysMenu = CopySysMenu();
370 if (((style & WS_CHILD) != WS_CHILD) && (wndPtr->wIDmenu != 0)) {
371 lpbar = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
372 if (lpbar != NULL) {
373 lpbar->ownerWnd = hwnd;
374 wndPtr->hWndMenuBar = CreateWindow("POPUPMENU", "",
375 WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
376 0, 0, width, 20, hwnd, 2, instance, (LPSTR)lpbar);
379 /* Create scrollbars */
380 if ((style & WS_VSCROLL) == WS_VSCROLL ||
381 (style & WS_HSCROLL) == WS_HSCROLL) {
382 NC_CreateScrollBars(hwnd);
384 EVENT_RegisterWindow( wndPtr->window, hwnd );
386 WIN_SendParentNotify( hwnd, wndPtr, WM_CREATE );
388 if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
389 return hwnd;
392 /***********************************************************************
393 * DestroyWindow (USER.53)
395 BOOL DestroyWindow( HWND hwnd )
397 WND * wndPtr;
398 CLASS * classPtr;
400 /* Initialisation */
402 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
403 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return FALSE;
404 WIN_SendParentNotify( hwnd, wndPtr, WM_DESTROY );
406 /* Send destroy messages */
408 SendMessage( hwnd, WM_DESTROY, 0, 0 );
409 SendMessage( hwnd, WM_NCDESTROY, 0, 0 );
411 /* Destroy all children */
413 if (wndPtr->VScroll) free(wndPtr->VScroll);
414 if (wndPtr->HScroll) free(wndPtr->HScroll);
415 while (wndPtr->hwndChild) /* The child removes itself from the list */
416 DestroyWindow( wndPtr->hwndChild );
418 /* Remove the window from the linked list */
420 WIN_UnlinkWindow( hwnd );
422 /* Destroy the window */
424 wndPtr->dwMagic = 0; /* Mark it as invalid */
425 XDestroyWindow( display, wndPtr->window );
426 if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
427 classPtr->cWindows--;
428 USER_HEAP_FREE( hwnd );
430 printf("End of DestroyWindow // hwnd=%04X !\n", hwnd);
432 return TRUE;
436 /***********************************************************************
437 * CloseWindow (USER.43)
439 void CloseWindow(HWND hWnd)
441 WND * wndPtr = WIN_FindWndPtr(hWnd);
442 if (wndPtr->dwStyle & WS_CHILD) return;
443 ShowWindow(hWnd, SW_MINIMIZE);
448 /***********************************************************************
449 * OpenIcon (USER.44)
451 BOOL OpenIcon(HWND hWnd)
453 if (!IsIconic(hWnd)) return FALSE;
454 ShowWindow(hWnd, SW_SHOWNORMAL);
455 return(TRUE);
460 /***********************************************************************
461 * FindWindow (USER.50)
463 HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch)
465 return((HWND)NULL);
469 /***********************************************************************
470 * UpdateWindow (USER.124)
472 void UpdateWindow( HWND hwnd )
474 if (GetUpdateRect( hwnd, NULL, FALSE ))
476 if (IsWindowVisible( hwnd )) SendMessage( hwnd, WM_PAINT, 0, 0 );
481 /**********************************************************************
482 * GetDesktopWindow (USER.286)
484 HWND GetDesktopWindow()
486 return 0;
491 /**********************************************************************
492 * GetWindowWord (USER.133)
494 WORD GetWindowWord( HWND hwnd, short offset )
496 WND * wndPtr = WIN_FindWndPtr( hwnd );
497 if (!wndPtr) return 0;
498 if (offset >= 0) return *(WORD *)(((char *)wndPtr->wExtra) + offset);
499 switch(offset)
501 case GWW_ID: return wndPtr->wIDmenu;
502 case GWW_HWNDPARENT: return wndPtr->hwndParent;
503 case GWW_HINSTANCE: return wndPtr->hInstance;
505 return 0;
509 /**********************************************************************
510 * SetWindowWord (USER.134)
512 WORD SetWindowWord( HWND hwnd, short offset, WORD newval )
514 WORD *ptr, retval;
515 WND * wndPtr = WIN_FindWndPtr( hwnd );
516 if (!wndPtr) return 0;
517 if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
518 else switch(offset)
520 case GWW_ID: ptr = &wndPtr->wIDmenu;
521 case GWW_HINSTANCE: ptr = &wndPtr->hInstance;
522 default: return 0;
524 retval = *ptr;
525 *ptr = newval;
526 return retval;
531 /*******************************************************************
532 * WIN_SetSensitive
534 * sets hWnd and all children to the same sensitivity
536 * sets hWnd sensitive and then calls SetSensitive on hWnd's child
537 * and all of hWnd's child's Next windows
539 static BOOL WIN_SetSensitive(HWND hWnd, BOOL fEnable)
541 WND *wndPtr;
542 HWND hwnd;
544 printf("in SetSenitive\n");
546 if (!hWnd) return 0;
547 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return 0;
550 if (fEnable) {
551 wndPtr->dwStyle &= ~WS_DISABLED;
552 } else {
553 wndPtr->dwStyle |= WS_DISABLED;
556 hwnd=wndPtr->hwndChild;
557 while (hwnd) { /* mk next child sens */
558 WIN_SetSensitive(hwnd, fEnable);
559 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) return 0;
560 hwnd=wndPtr->hwndNext;
562 return 1;
566 /*******************************************************************
567 * EnableWindow (USER.34)
572 BOOL EnableWindow(HWND hWnd, BOOL fEnable)
574 WND *wndPtr;
575 int eprev;
577 if (hWnd == 0) return 0;
579 wndPtr = WIN_FindWndPtr(hWnd);
580 if (wndPtr == 0) return 0;
582 eprev = ! (wndPtr->dwStyle & WS_DISABLED);
584 if (fEnable != eprev) { /* change req */
585 printf("changing window\n");
586 WIN_SetSensitive(hWnd, fEnable);
587 SendMessage(hWnd, WM_ENABLE, (WORD)fEnable, 0);
589 return !eprev;
592 /***********************************************************************
593 * IsWindowEnabled (USER.35)
596 BOOL IsWindowEnabled(HWND hWnd)
598 WND * wndPtr;
600 if (hWnd == 0) return 0;
601 wndPtr = WIN_FindWndPtr(hWnd);
602 if (wndPtr == 0) return 0;
604 return !(wndPtr->dwStyle & WS_DISABLED);
610 /**********************************************************************
611 * GetWindowLong (USER.135)
613 LONG GetWindowLong( HWND hwnd, short offset )
615 WND * wndPtr = WIN_FindWndPtr( hwnd );
616 if (!wndPtr) return 0;
617 if (offset >= 0) return *(LONG *)(((char *)wndPtr->wExtra) + offset);
618 switch(offset)
620 case GWL_STYLE: return wndPtr->dwStyle;
621 case GWL_EXSTYLE: return wndPtr->dwExStyle;
622 case GWL_WNDPROC: return (LONG)wndPtr->lpfnWndProc;
624 return 0;
628 /**********************************************************************
629 * SetWindowLong (USER.136)
631 LONG SetWindowLong( HWND hwnd, short offset, LONG newval )
633 LONG *ptr, retval;
634 WND * wndPtr = WIN_FindWndPtr( hwnd );
635 if (!wndPtr) return 0;
636 if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
637 else switch(offset)
639 case GWL_STYLE: ptr = &wndPtr->dwStyle;
640 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle;
641 case GWL_WNDPROC: ptr = (LONG *)(&wndPtr->lpfnWndProc);
642 default: return 0;
644 retval = *ptr;
645 *ptr = newval;
646 return retval;
650 /*******************************************************************
651 * GetWindowText (USER.36)
653 int GetWindowText(HWND hwnd, LPSTR lpString, int nMaxCount)
655 return (int)SendMessage(hwnd, WM_GETTEXT, (WORD)nMaxCount,
656 (DWORD)lpString);
659 /*******************************************************************
660 * SetWindowText (USER.37)
662 void SetWindowText(HWND hwnd, LPSTR lpString)
664 SendMessage(hwnd, WM_SETTEXT, (WORD)NULL, (DWORD)lpString);
667 /*******************************************************************
668 * GetWindowTextLength (USER.38)
670 int GetWindowTextLength(HWND hwnd)
672 return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, (WORD)NULL,
673 (DWORD)NULL);
677 /*******************************************************************
678 * IsWindow (USER.47)
680 BOOL IsWindow( HWND hwnd )
682 WND * wndPtr = WIN_FindWndPtr( hwnd );
683 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
687 /*****************************************************************
688 * GetParent (USER.46)
690 HWND GetParent(HWND hwnd)
692 WND *wndPtr = WIN_FindWndPtr(hwnd);
693 if (!wndPtr) return 0;
694 return wndPtr->hwndParent;
698 /*******************************************************************
699 * IsChild (USER.48)
701 BOOL IsChild( HWND parent, HWND child )
703 HWND curChild;
704 WND * parentPtr;
705 WND * childPtr;
707 if (!(parentPtr = WIN_FindWndPtr( parent ))) return FALSE;
708 curChild = parentPtr->hwndChild;
710 while (curChild)
712 if (curChild == child) return TRUE;
713 if (IsChild( curChild, child )) return TRUE;
714 if (!(childPtr = WIN_FindWndPtr( curChild ))) return FALSE;
715 curChild = childPtr->hwndNext;
717 return FALSE;
721 /***********************************************************************
722 * IsWindowVisible (USER.49)
724 BOOL IsWindowVisible(HWND hWnd)
726 WND * wndPtr = WIN_FindWndPtr(hWnd);
727 if (wndPtr == 0) return(FALSE);
728 else return ((wndPtr->dwStyle & WS_VISIBLE) != 0);
733 /*******************************************************************
734 * GetTopWindow (USER.229)
736 HWND GetTopWindow( HWND hwnd )
738 WND * wndPtr = WIN_FindWndPtr( hwnd );
739 if (wndPtr) return wndPtr->hwndChild;
740 else return 0;
744 /*******************************************************************
745 * GetWindow (USER.262)
747 HWND GetWindow( HWND hwnd, WORD rel )
749 WND * wndPtr = WIN_FindWndPtr( hwnd );
750 if (!wndPtr) return 0;
751 switch(rel)
753 case GW_HWNDFIRST:
754 if (wndPtr->hwndParent)
756 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
757 return parentPtr->hwndChild;
759 else return firstWindow;
761 case GW_HWNDLAST:
762 while (wndPtr->hwndNext)
764 hwnd = wndPtr->hwndNext;
765 wndPtr = WIN_FindWndPtr( hwnd );
767 return hwnd;
769 case GW_HWNDNEXT:
770 return wndPtr->hwndNext;
772 case GW_HWNDPREV:
774 HWND hwndPrev;
776 if (wndPtr->hwndParent)
778 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
779 hwndPrev = parentPtr->hwndChild;
781 else hwndPrev = firstWindow;
782 if (hwndPrev == hwnd) return 0;
783 while (hwndPrev)
785 wndPtr = WIN_FindWndPtr( hwndPrev );
786 if (wndPtr->hwndNext == hwnd) break;
787 hwndPrev = wndPtr->hwndNext;
789 return hwndPrev;
792 case GW_OWNER:
793 return wndPtr->hwndOwner;
795 case GW_CHILD:
796 return wndPtr->hwndChild;
798 return 0;
802 /*******************************************************************
803 * GetNextWindow (USER.230)
805 HWND GetNextWindow( HWND hwnd, WORD flag )
807 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
808 return GetWindow( hwnd, flag );
814 /*******************************************************************
815 * EnumWindows (USER.54)
817 * o gets the desktop window and iterates over all the windows
818 * which are direct decendents of the desktop * by iterating over
819 * the desktop's child window and all the child windows next
820 * pointers
822 * o call wndenumprc for every child window the desktop has
823 * (parameters to Callback16 passed backwards so they are
824 * put in in pascal calling order)
826 * o if wndenumprc returns 0 exit
828 * * remove the HAS_DESKTOP_WINDOW ifdef when the GetDesktopWindow() call
829 * is fixed to actually return the desktop window
832 BOOL EnumWindows(FARPROC wndenumprc, LPARAM lParam)
834 HWND hwnd = GetDesktopWindow();
835 WND *wndPtr;
836 int result;
838 #ifdef DEBUG_ENUM
839 printf("EnumWindows\n");
840 #endif
841 #ifdef HAS_DESKTOP_WINDOW
842 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
843 hwnd = wndPtr->hwndChild;
844 #else
845 hwnd = firstWindow;
846 #endif
848 while (hwnd) {
849 char *ptr;
851 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
852 return 0;
854 #ifdef DEBUG_ENUM
855 if (XFetchName(display, wndPtr->window, &ptr) && ptr)
856 printf("found a window (%s)\n", ptr);
857 else
858 printf("found nameless parent window\n");
859 #endif
860 result = CallBack16(wndenumprc, 2, lParam, (int) hwnd);
861 if ( ! result ) {
862 return 0;
864 hwnd=wndPtr->hwndNext;
866 return 1; /* for now */
869 /*******************************************************************
870 * WIN_EnumChildWin
872 * o hwnd is the first child to use, loop until all next windows
873 * are processed
875 * o call wdnenumprc with parameters in inverse order (pascal)
877 * o call ourselves with the next child window
880 static BOOL WIN_EnumChildWin(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
882 WND *wndPtr;
883 int result;
886 while (hwnd) {
887 char *ptr;
888 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
889 return 0;
891 #ifdef DEBUG_ENUM
892 if (XFetchName(display, wndPtr->window, &ptr) && ptr)
893 printf("EnumChild: found a child window (%s)\n", ptr);
894 else
895 printf("EnumChild: nameless child\n");
897 if (!(wndPtr->dwStyle & WS_CHILD)) {
898 printf("this is not a child window! What is it doing here?\n");
899 return 0;
901 #endif
902 if (!CallBack16(wndenumprc, 2, lParam, (int) hwnd)) {
903 return 0;
905 if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) {
906 return 0;
908 hwnd=wndPtr->hwndNext;
910 return 1;
913 /*******************************************************************
914 * EnumChildWindows (USER.55)
916 * o gets the first child of hwnd
918 * o calls WIN_EnumChildWin to do a recursive decent of child windows
920 BOOL EnumChildWindows(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
922 WND *wndPtr;
924 #ifdef DEBUG_ENUM
925 printf("EnumChildWindows\n");
926 #endif
928 if (hwnd == 0) return 0;
929 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
930 hwnd = wndPtr->hwndChild;
931 return WIN_EnumChildWin(hwnd, wndenumprc, lParam);