Release 940405
[wine/multimedia.git] / windows / win.c
blobcfc8e852e6fbdf9346f86574e19a3effcedc4965
1 /*
2 * Window related functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
13 #include "class.h"
14 #include "win.h"
15 #include "user.h"
16 #include "dce.h"
17 #include "sysmetrics.h"
18 #include "scroll.h"
20 extern Colormap COLOR_WinColormap;
22 extern void EVENT_RegisterWindow( Window w, HWND hwnd ); /* event.c */
23 extern void CURSOR_SetWinCursor( HWND hwnd, HCURSOR hcursor ); /* cursor.c */
24 extern void WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); /*winpos.c*/
25 extern HMENU CopySysMenu(); /* menu.c */
26 extern LONG MDIClientWndProc(HWND hwnd, WORD message,
27 WORD wParam, LONG lParam); /* mdi.c */
30 static HWND hwndDesktop = 0;
32 /***********************************************************************
33 * WIN_FindWndPtr
35 * Return a pointer to the WND structure corresponding to a HWND.
37 WND * WIN_FindWndPtr( HWND hwnd )
39 WND * ptr;
41 if (!hwnd) return NULL;
42 ptr = (WND *) USER_HEAP_ADDR( hwnd );
43 if (ptr->dwMagic != WND_MAGIC) return NULL;
44 return ptr;
48 /***********************************************************************
49 * WIN_UnlinkWindow
51 * Remove a window from the siblings linked list.
53 BOOL WIN_UnlinkWindow( HWND hwnd )
55 HWND * curWndPtr;
56 WND *parentPtr, *wndPtr;
58 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
59 if (!(parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ))) return FALSE;
61 curWndPtr = &parentPtr->hwndChild;
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 */
83 WND *wndPtr, *parentPtr;
85 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
86 if (!(parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ))) return FALSE;
88 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
90 hwndPtr = &parentPtr->hwndChild; /* Point to first sibling hwnd */
91 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
92 while (*hwndPtr)
94 WND * nextPtr = WIN_FindWndPtr( *hwndPtr );
95 hwndPtr = &nextPtr->hwndNext;
98 else /* Normal case */
100 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
101 if (afterPtr) hwndPtr = &afterPtr->hwndNext;
103 if (!hwndPtr) return FALSE;
104 wndPtr->hwndNext = *hwndPtr;
105 *hwndPtr = hwnd;
106 return TRUE;
110 /***********************************************************************
111 * WIN_FindWinToRepaint
113 * Find a window that needs repaint.
115 HWND WIN_FindWinToRepaint( HWND hwnd )
117 WND * wndPtr;
119 /* Note: the desktop window never gets WM_PAINT messages */
120 if (!hwnd) hwnd = GetTopWindow( hwndDesktop );
121 for ( ; hwnd != 0; hwnd = wndPtr->hwndNext )
123 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
124 if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT))
125 return hwnd;
126 if (wndPtr->hwndChild)
128 HWND child;
129 if ((child = WIN_FindWinToRepaint( wndPtr->hwndChild )))
130 return child;
133 return 0;
137 /***********************************************************************
138 * WIN_SendParentNotify
140 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
141 * the window has the WS_EX_NOPARENTNOTIFY style.
143 void WIN_SendParentNotify( HWND hwnd, WORD event, LONG lParam )
145 HWND current = GetParent( hwnd );
146 WND *wndPtr = WIN_FindWndPtr( hwnd );
148 if (!wndPtr || (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY)) return;
149 while (current)
151 SendMessage( current, WM_PARENTNOTIFY, event, lParam );
152 current = GetParent( current );
157 /***********************************************************************
158 * WIN_CreateDesktopWindow
160 * Create the desktop window.
162 BOOL WIN_CreateDesktopWindow()
164 WND *wndPtr;
165 HCLASS hclass;
166 CLASS *classPtr;
168 if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_NAME, &classPtr )))
169 return FALSE;
171 hwndDesktop = USER_HEAP_ALLOC( GMEM_MOVEABLE,
172 sizeof(WND)+classPtr->wc.cbWndExtra );
173 if (!hwndDesktop) return FALSE;
174 wndPtr = (WND *) USER_HEAP_ADDR( hwndDesktop );
176 wndPtr->hwndNext = 0;
177 wndPtr->hwndChild = 0;
178 wndPtr->dwMagic = WND_MAGIC;
179 wndPtr->hwndParent = 0;
180 wndPtr->hwndOwner = 0;
181 wndPtr->hClass = hclass;
182 wndPtr->hInstance = 0;
183 wndPtr->rectWindow.left = 0;
184 wndPtr->rectWindow.top = 0;
185 wndPtr->rectWindow.right = SYSMETRICS_CXSCREEN;
186 wndPtr->rectWindow.bottom = SYSMETRICS_CYSCREEN;
187 wndPtr->rectClient = wndPtr->rectWindow;
188 wndPtr->rectNormal = wndPtr->rectWindow;
189 wndPtr->ptIconPos.x = -1;
190 wndPtr->ptIconPos.y = -1;
191 wndPtr->ptMaxPos.x = -1;
192 wndPtr->ptMaxPos.y = -1;
193 wndPtr->hmemTaskQ = 0; /* Desktop does not belong to a task */
194 wndPtr->hrgnUpdate = 0;
195 wndPtr->hwndLastActive = 0;
196 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
197 wndPtr->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
198 wndPtr->dwExStyle = 0;
199 wndPtr->hdce = 0;
200 wndPtr->hmenuSystem = 0;
201 wndPtr->VScroll = NULL;
202 wndPtr->HScroll = NULL;
203 wndPtr->wIDmenu = 0;
204 wndPtr->hText = 0;
205 wndPtr->flags = 0;
206 wndPtr->window = rootWindow;
207 wndPtr->hSysMenu = 0;
209 /* Send dummy WM_NCCREATE message */
210 SendMessage( hwndDesktop, WM_NCCREATE, 0, 0 );
211 EVENT_RegisterWindow( wndPtr->window, hwndDesktop );
212 RedrawWindow( hwndDesktop, NULL, 0,
213 RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW );
214 return TRUE;
218 /***********************************************************************
219 * CreateWindow (USER.41)
221 HWND CreateWindow( LPSTR className, LPSTR windowName,
222 DWORD style, short x, short y, short width, short height,
223 HWND parent, HMENU menu, HANDLE instance, LPSTR data )
225 return CreateWindowEx( 0, className, windowName, style,
226 x, y, width, height, parent, menu, instance, data );
230 /***********************************************************************
231 * CreateWindowEx (USER.452)
233 HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
234 DWORD style, short x, short y, short width, short height,
235 HWND parent, HMENU menu, HANDLE instance, LPSTR data )
237 HANDLE class, hwnd;
238 CLASS *classPtr;
239 WND *wndPtr, *parentPtr = NULL;
240 CREATESTRUCT *createStruct;
241 HANDLE hcreateStruct;
242 int wmcreate;
243 XSetWindowAttributes win_attr;
245 #ifdef DEBUG_WIN
246 printf( "CreateWindowEx: %d '%s' '%s' %d,%d %dx%d %08x %x\n",
247 exStyle, className, windowName, x, y, width, height, style, parent);
248 #endif
250 if (x == CW_USEDEFAULT) x = y = 0;
251 if (width == CW_USEDEFAULT)
253 width = 600;
254 height = 400;
256 if (width == 0) width = 1;
257 if (height == 0) height = 1;
259 /* Find the parent and class */
261 if (parent)
263 /* Check if parent is valid */
264 if (!(parentPtr = WIN_FindWndPtr( parent ))) return 0;
266 else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */
268 if (!(class = CLASS_FindClassByName( className, &classPtr ))) {
269 printf("CreateWindow BAD CLASSNAME '%s' !\n", className);
270 return 0;
273 /* Correct the window style */
275 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
276 style |= WS_CAPTION | WS_CLIPSIBLINGS;
277 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
279 /* Create the window structure */
281 hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra);
282 if (!hwnd) return 0;
284 /* Fill the structure */
286 wndPtr = (WND *) USER_HEAP_ADDR( hwnd );
287 wndPtr->hwndNext = 0;
288 wndPtr->hwndChild = 0;
289 wndPtr->dwMagic = WND_MAGIC;
290 wndPtr->hwndParent = (style & WS_CHILD) ? parent : hwndDesktop;
291 wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : parent;
292 wndPtr->hClass = class;
293 wndPtr->hInstance = instance;
294 wndPtr->rectWindow.left = x;
295 wndPtr->rectWindow.top = y;
296 wndPtr->rectWindow.right = x + width;
297 wndPtr->rectWindow.bottom = y + height;
298 wndPtr->rectClient = wndPtr->rectWindow;
299 wndPtr->rectNormal = wndPtr->rectWindow;
300 wndPtr->ptIconPos.x = -1;
301 wndPtr->ptIconPos.y = -1;
302 wndPtr->ptMaxPos.x = -1;
303 wndPtr->ptMaxPos.y = -1;
304 wndPtr->hmemTaskQ = GetTaskQueue(0);
305 wndPtr->hrgnUpdate = 0;
306 wndPtr->hwndLastActive = 0;
307 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
308 wndPtr->dwStyle = style;
309 wndPtr->dwExStyle = exStyle;
310 wndPtr->hmenuSystem = 0;
311 #ifdef DEBUG_MENU
312 printf("CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n",
313 menu, instance, classPtr->wc.lpszMenuName);
314 #endif
315 if (menu != 0)
316 wndPtr->wIDmenu = menu;
317 else {
318 if (classPtr->wc.lpszMenuName != NULL)
319 wndPtr->wIDmenu = LoadMenu(instance, classPtr->wc.lpszMenuName);
320 else
321 wndPtr->wIDmenu = 0;
323 wndPtr->hText = 0;
324 wndPtr->flags = 0;
325 wndPtr->VScroll = NULL;
326 wndPtr->HScroll = NULL;
327 wndPtr->hSysMenu = 0;
329 if (classPtr->wc.cbWndExtra)
330 memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
331 if (classPtr->wc.style & CS_DBLCLKS) wndPtr->flags |= WIN_DOUBLE_CLICKS;
332 classPtr->cWindows++;
334 /* Get class or window DC if needed */
335 if (classPtr->wc.style & CS_OWNDC)
337 wndPtr->flags |= WIN_OWN_DC;
338 wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC );
340 else if (classPtr->wc.style & CS_CLASSDC)
342 wndPtr->flags |= WIN_CLASS_DC;
343 wndPtr->hdce = classPtr->hdce;
345 else wndPtr->hdce = 0;
347 /* Insert the window in the linked list */
349 WIN_LinkWindow( hwnd, HWND_TOP );
351 /* Create the X window */
353 win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
354 PointerMotionMask | ButtonPressMask |
355 ButtonReleaseMask | EnterWindowMask;
356 win_attr.override_redirect = (rootWindow == DefaultRootWindow(display));
357 win_attr.colormap = COLOR_WinColormap;
358 if (!(style & WS_CHILD))
360 parentPtr = WIN_FindWndPtr( hwndDesktop );
361 /* Only select focus events on top-level override-redirect windows */
362 if (win_attr.override_redirect) win_attr.event_mask |= FocusChangeMask;
364 wndPtr->window = XCreateWindow( display, parentPtr->window,
365 x + parentPtr->rectClient.left - parentPtr->rectWindow.left,
366 y + parentPtr->rectClient.top - parentPtr->rectWindow.top,
367 width, height, 0,
368 CopyFromParent, InputOutput, CopyFromParent,
369 CWEventMask | CWOverrideRedirect | CWColormap, &win_attr );
370 XStoreName( display, wndPtr->window, windowName );
372 /* Send the WM_CREATE message */
374 hcreateStruct = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CREATESTRUCT) );
375 createStruct = (CREATESTRUCT *) USER_HEAP_ADDR( hcreateStruct );
376 createStruct->lpCreateParams = data;
377 createStruct->hInstance = instance;
378 createStruct->hMenu = menu;
379 createStruct->hwndParent = parent;
380 createStruct->cx = width;
381 createStruct->cy = height;
382 createStruct->x = x;
383 createStruct->y = y;
384 createStruct->style = style;
385 createStruct->lpszName = windowName;
386 createStruct->lpszClass = className;
387 createStruct->dwExStyle = 0;
389 wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LONG)createStruct );
390 if (!wmcreate) wmcreate = -1;
391 else
393 /* Send WM_NCCALCSIZE message */
394 NCCALCSIZE_PARAMS *params;
395 HANDLE hparams;
396 hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) );
397 if (hparams)
399 params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams );
400 params->rgrc[0] = wndPtr->rectWindow;
401 params->lppos = NULL;
402 SendMessage( hwnd, WM_NCCALCSIZE, FALSE, (LONG)params );
403 wndPtr->rectClient = params->rgrc[0];
404 USER_HEAP_FREE( hparams );
406 wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct );
409 USER_HEAP_FREE( hcreateStruct );
411 if (wmcreate == -1)
413 /* Abort window creation */
415 WIN_UnlinkWindow( hwnd );
416 XDestroyWindow( display, wndPtr->window );
417 if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
418 classPtr->cWindows--;
419 USER_HEAP_FREE( hwnd );
420 return 0;
423 /* Create a copy of SysMenu */
424 if (style & WS_SYSMENU) wndPtr->hSysMenu = CopySysMenu();
426 /* Set window cursor */
427 if (classPtr->wc.hCursor) CURSOR_SetWinCursor( hwnd, classPtr->wc.hCursor);
428 else CURSOR_SetWinCursor( hwnd, LoadCursor( 0, IDC_ARROW ));
430 EVENT_RegisterWindow( wndPtr->window, hwnd );
432 WIN_SendParentNotify( hwnd, WM_CREATE, MAKELONG( hwnd, wndPtr->wIDmenu ) );
434 if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
435 return hwnd;
439 /***********************************************************************
440 * DestroyWindow (USER.53)
442 BOOL DestroyWindow( HWND hwnd )
444 WND * wndPtr;
445 CLASS * classPtr;
447 /* Initialisation */
449 if (hwnd == hwndDesktop) return FALSE; /* Can't destroy desktop */
450 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
451 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return FALSE;
452 if (hwnd == GetActiveWindow()) WINPOS_ChangeActiveWindow( 0, FALSE );
453 if (hwnd == GetFocus()) SetFocus( 0 );
454 WIN_SendParentNotify( hwnd, WM_DESTROY, MAKELONG(hwnd, wndPtr->wIDmenu) );
456 /* Send destroy messages and destroy children */
458 SendMessage( hwnd, WM_DESTROY, 0, 0 );
459 while (wndPtr->hwndChild) /* The child removes itself from the list */
460 DestroyWindow( wndPtr->hwndChild );
461 SendMessage( hwnd, WM_NCDESTROY, 0, 0 );
463 /* Remove the window from the linked list */
465 WIN_UnlinkWindow( hwnd );
467 /* Destroy the window */
469 wndPtr->dwMagic = 0; /* Mark it as invalid */
470 XDestroyWindow( display, wndPtr->window );
471 if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
472 classPtr->cWindows--;
473 USER_HEAP_FREE( hwnd );
475 printf("End of DestroyWindow // hwnd=%04X !\n", hwnd);
477 return TRUE;
481 /***********************************************************************
482 * CloseWindow (USER.43)
484 void CloseWindow(HWND hWnd)
486 WND * wndPtr = WIN_FindWndPtr(hWnd);
487 if (wndPtr->dwStyle & WS_CHILD) return;
488 ShowWindow(hWnd, SW_MINIMIZE);
493 /***********************************************************************
494 * OpenIcon (USER.44)
496 BOOL OpenIcon(HWND hWnd)
498 if (!IsIconic(hWnd)) return FALSE;
499 ShowWindow(hWnd, SW_SHOWNORMAL);
500 return(TRUE);
505 /***********************************************************************
506 * FindWindow (USER.50)
508 HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch)
510 HCLASS hclass;
511 CLASS *classPtr;
512 HWND hwnd;
514 if (ClassMatch)
516 hclass = CLASS_FindClassByName( ClassMatch, &classPtr );
517 if (!hclass) return 0;
519 else hclass = 0;
521 hwnd = GetTopWindow( hwndDesktop );
522 while(hwnd)
524 WND *wndPtr = WIN_FindWndPtr( hwnd );
525 if (!hclass || (wndPtr->hClass == hclass))
527 /* Found matching class */
528 if (!TitleMatch) return hwnd;
529 if (wndPtr->hText)
531 char *textPtr = (char *) USER_HEAP_ADDR( wndPtr->hText );
532 if (!strcmp( textPtr, TitleMatch )) return hwnd;
535 hwnd = wndPtr->hwndNext;
537 return 0;
541 /**********************************************************************
542 * GetDesktopWindow (USER.286)
544 HWND GetDesktopWindow()
546 return hwndDesktop;
550 /*******************************************************************
551 * EnableWindow (USER.34)
553 BOOL EnableWindow( HWND hwnd, BOOL enable )
555 WND *wndPtr;
557 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
558 if (enable && (wndPtr->dwStyle & WS_DISABLED))
560 /* Enable window */
561 wndPtr->dwStyle &= ~WS_DISABLED;
562 SendMessage( hwnd, WM_ENABLE, TRUE, 0 );
563 return TRUE;
565 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
567 /* Disable window */
568 wndPtr->dwStyle |= WS_DISABLED;
569 if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
570 SetFocus( 0 ); /* A disabled window can't have the focus */
571 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
572 ReleaseCapture(); /* A disabled window can't capture the mouse */
573 SendMessage( hwnd, WM_ENABLE, FALSE, 0 );
574 return FALSE;
576 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
580 /***********************************************************************
581 * IsWindowEnabled (USER.35)
583 BOOL IsWindowEnabled(HWND hWnd)
585 WND * wndPtr;
587 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
588 return !(wndPtr->dwStyle & WS_DISABLED);
592 /**********************************************************************
593 * GetWindowWord (USER.133)
595 WORD GetWindowWord( HWND hwnd, short offset )
597 WND * wndPtr = WIN_FindWndPtr( hwnd );
598 if (!wndPtr) return 0;
599 if (offset >= 0) return *(WORD *)(((char *)wndPtr->wExtra) + offset);
600 switch(offset)
602 case GWW_ID: return wndPtr->wIDmenu;
603 case GWW_HWNDPARENT: return wndPtr->hwndParent;
604 case GWW_HINSTANCE: return wndPtr->hInstance;
606 return 0;
610 /**********************************************************************
611 * SetWindowWord (USER.134)
613 WORD SetWindowWord( HWND hwnd, short offset, WORD newval )
615 WORD *ptr, retval;
616 WND * wndPtr = WIN_FindWndPtr( hwnd );
617 if (!wndPtr) return 0;
618 if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
619 else switch(offset)
621 case GWW_ID: ptr = &wndPtr->wIDmenu;
622 case GWW_HINSTANCE: ptr = &wndPtr->hInstance;
623 default: return 0;
625 retval = *ptr;
626 *ptr = newval;
627 return retval;
631 /**********************************************************************
632 * GetWindowLong (USER.135)
634 LONG GetWindowLong( HWND hwnd, short offset )
636 WND * wndPtr = WIN_FindWndPtr( hwnd );
637 if (!wndPtr) return 0;
638 if (offset >= 0) return *(LONG *)(((char *)wndPtr->wExtra) + offset);
639 switch(offset)
641 case GWL_STYLE: return wndPtr->dwStyle;
642 case GWL_EXSTYLE: return wndPtr->dwExStyle;
643 case GWL_WNDPROC: return (LONG)wndPtr->lpfnWndProc;
645 return 0;
649 /**********************************************************************
650 * SetWindowLong (USER.136)
652 LONG SetWindowLong( HWND hwnd, short offset, LONG newval )
654 LONG *ptr, retval;
655 WND * wndPtr = WIN_FindWndPtr( hwnd );
656 if (!wndPtr) return 0;
657 if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
658 else switch(offset)
660 case GWL_STYLE: ptr = &wndPtr->dwStyle;
661 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle;
662 case GWL_WNDPROC: ptr = (LONG *)(&wndPtr->lpfnWndProc);
663 default: return 0;
665 retval = *ptr;
666 *ptr = newval;
667 return retval;
671 /*******************************************************************
672 * GetWindowText (USER.36)
674 int GetWindowText(HWND hwnd, LPSTR lpString, int nMaxCount)
676 return (int)SendMessage(hwnd, WM_GETTEXT, (WORD)nMaxCount,
677 (DWORD)lpString);
680 /*******************************************************************
681 * SetWindowText (USER.37)
683 void SetWindowText(HWND hwnd, LPSTR lpString)
685 SendMessage(hwnd, WM_SETTEXT, (WORD)NULL, (DWORD)lpString);
688 /*******************************************************************
689 * GetWindowTextLength (USER.38)
691 int GetWindowTextLength(HWND hwnd)
693 return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, (WORD)NULL,
694 (DWORD)NULL);
698 /*******************************************************************
699 * IsWindow (USER.47)
701 BOOL IsWindow( HWND hwnd )
703 WND * wndPtr = WIN_FindWndPtr( hwnd );
704 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
708 /*****************************************************************
709 * GetParent (USER.46)
711 HWND GetParent(HWND hwnd)
713 WND *wndPtr = WIN_FindWndPtr(hwnd);
714 if (!wndPtr || !(wndPtr->dwStyle & WS_CHILD)) return 0;
715 return wndPtr->hwndParent;
719 /*******************************************************************
720 * IsChild (USER.48)
722 BOOL IsChild( HWND parent, HWND child )
724 WND * wndPtr = WIN_FindWndPtr( child );
725 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
727 if (wndPtr->hwndParent == parent) return TRUE;
728 wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
730 return FALSE;
734 /***********************************************************************
735 * IsWindowVisible (USER.49)
737 BOOL IsWindowVisible(HWND hWnd)
739 WND * wndPtr = WIN_FindWndPtr(hWnd);
740 if (wndPtr == 0) return(FALSE);
741 else return ((wndPtr->dwStyle & WS_VISIBLE) != 0);
746 /*******************************************************************
747 * GetTopWindow (USER.229)
749 HWND GetTopWindow( HWND hwnd )
751 WND * wndPtr = WIN_FindWndPtr( hwnd );
752 if (wndPtr) return wndPtr->hwndChild;
753 else return 0;
757 /*******************************************************************
758 * GetWindow (USER.262)
760 HWND GetWindow( HWND hwnd, WORD rel )
762 WND * wndPtr = WIN_FindWndPtr( hwnd );
763 if (!wndPtr) return 0;
764 switch(rel)
766 case GW_HWNDFIRST:
767 if (wndPtr->hwndParent)
769 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
770 return parentPtr->hwndChild;
772 else return 0;
774 case GW_HWNDLAST:
775 if (!wndPtr->hwndParent) return 0; /* Desktop window */
776 while (wndPtr->hwndNext)
778 hwnd = wndPtr->hwndNext;
779 wndPtr = WIN_FindWndPtr( hwnd );
781 return hwnd;
783 case GW_HWNDNEXT:
784 return wndPtr->hwndNext;
786 case GW_HWNDPREV:
788 HWND hwndPrev;
790 if (wndPtr->hwndParent)
792 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
793 hwndPrev = parentPtr->hwndChild;
795 else return 0; /* Desktop window */
796 if (hwndPrev == hwnd) return 0;
797 while (hwndPrev)
799 wndPtr = WIN_FindWndPtr( hwndPrev );
800 if (wndPtr->hwndNext == hwnd) break;
801 hwndPrev = wndPtr->hwndNext;
803 return hwndPrev;
806 case GW_OWNER:
807 return wndPtr->hwndOwner;
809 case GW_CHILD:
810 return wndPtr->hwndChild;
812 return 0;
816 /*******************************************************************
817 * GetNextWindow (USER.230)
819 HWND GetNextWindow( HWND hwnd, WORD flag )
821 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
822 return GetWindow( hwnd, flag );
828 /*******************************************************************
829 * EnumWindows (USER.54)
831 * o gets the desktop window and iterates over all the windows
832 * which are direct decendents of the desktop * by iterating over
833 * the desktop's child window and all the child windows next
834 * pointers
836 * o call wndenumprc for every child window the desktop has
837 * (parameters to Callback16 passed backwards so they are
838 * put in in pascal calling order)
840 * o if wndenumprc returns 0 exit
843 BOOL EnumWindows(FARPROC wndenumprc, LPARAM lParam)
845 HWND hwnd = GetTopWindow( GetDesktopWindow() );
846 WND *wndPtr;
847 int result;
849 #ifdef DEBUG_ENUM
850 printf("EnumWindows\n");
851 #endif
853 while (hwnd) {
854 char *ptr;
856 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
857 return 0;
859 #ifdef DEBUG_ENUM
860 if (XFetchName(display, wndPtr->window, &ptr) && ptr)
861 printf("found a window (%s)\n", ptr);
862 else
863 printf("found nameless parent window\n");
864 #endif
865 #ifdef WINELIB
866 (*wndenumprc)(hwnd, lParam);
867 #else
868 result = CallBack16(wndenumprc, 2, lParam, (int) hwnd);
869 #endif
870 if ( ! result ) {
871 return 0;
873 hwnd=wndPtr->hwndNext;
875 return 1; /* for now */
878 /*******************************************************************
879 * WIN_EnumChildWin
881 * o hwnd is the first child to use, loop until all next windows
882 * are processed
884 * o call wdnenumprc with parameters in inverse order (pascal)
886 * o call ourselves with the next child window
889 static BOOL WIN_EnumChildWin(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
891 WND *wndPtr;
892 int result;
895 while (hwnd) {
896 char *ptr;
897 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
898 return 0;
900 #ifdef DEBUG_ENUM
901 if (XFetchName(display, wndPtr->window, &ptr) && ptr)
902 printf("EnumChild: found a child window (%s)\n", ptr);
903 else
904 printf("EnumChild: nameless child\n");
906 if (!(wndPtr->dwStyle & WS_CHILD)) {
907 printf("this is not a child window! What is it doing here?\n");
908 return 0;
910 #endif
911 #ifdef WINELIB
912 if (!(*wndenumprc, 2, lParam, (int) hwnd)) {
913 #else
914 if (!CallBack16(wndenumprc, 2, lParam, (int) hwnd)) {
915 #endif
916 return 0;
918 if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) {
919 return 0;
921 hwnd=wndPtr->hwndNext;
923 return 1;
926 /*******************************************************************
927 * EnumChildWindows (USER.55)
929 * o gets the first child of hwnd
931 * o calls WIN_EnumChildWin to do a recursive decent of child windows
933 BOOL EnumChildWindows(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
935 WND *wndPtr;
937 #ifdef DEBUG_ENUM
938 printf("EnumChildWindows\n");
939 #endif
941 if (hwnd == 0) return 0;
942 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
943 hwnd = wndPtr->hwndChild;
944 return WIN_EnumChildWin(hwnd, wndenumprc, lParam);