Release 940912
[wine/dcerpc.git] / windows / win.c
blob2c27a7665b194cc10a540e89f6c50ecfd5daed18
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 "options.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"
20 #include "icon.h"
22 extern Colormap COLOR_WinColormap;
24 extern void EVENT_RegisterWindow( Window w, HWND hwnd ); /* event.c */
25 extern void CURSOR_SetWinCursor( HWND hwnd, HCURSOR hcursor ); /* cursor.c */
26 extern void WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); /*winpos.c*/
27 extern LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect,
28 RECT *newWindowRect, RECT *oldWindowRect,
29 RECT *oldClientRect, WINDOWPOS *winpos,
30 RECT *newClientRect ); /* winpos.c */
32 extern HMENU CopySysMenu(); /* menu.c */
33 extern LONG MDIClientWndProc(HWND hwnd, WORD message,
34 WORD wParam, LONG lParam); /* mdi.c */
37 static HWND hwndDesktop = 0;
38 static HWND hWndSysModal = 0;
40 /***********************************************************************
41 * WIN_FindWndPtr
43 * Return a pointer to the WND structure corresponding to a HWND.
45 WND * WIN_FindWndPtr( HWND hwnd )
47 WND * ptr;
49 if (!hwnd) return NULL;
50 ptr = (WND *) USER_HEAP_ADDR( hwnd );
51 if (ptr->dwMagic != WND_MAGIC) return NULL;
52 return ptr;
56 /***********************************************************************
57 * WIN_UnlinkWindow
59 * Remove a window from the siblings linked list.
61 BOOL WIN_UnlinkWindow( HWND hwnd )
63 HWND * curWndPtr;
64 WND *parentPtr, *wndPtr;
66 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
67 if (!(parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ))) return FALSE;
69 curWndPtr = &parentPtr->hwndChild;
71 while (*curWndPtr != hwnd)
73 WND * curPtr = WIN_FindWndPtr( *curWndPtr );
74 curWndPtr = &curPtr->hwndNext;
76 *curWndPtr = wndPtr->hwndNext;
77 return TRUE;
81 /***********************************************************************
82 * WIN_LinkWindow
84 * Insert a window into the siblings linked list.
85 * The window is inserted after the specified window, which can also
86 * be specified as HWND_TOP or HWND_BOTTOM.
88 BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
90 HWND * hwndPtr = NULL; /* pointer to hwnd to change */
91 WND *wndPtr, *parentPtr;
93 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
94 if (!(parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ))) return FALSE;
96 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
98 hwndPtr = &parentPtr->hwndChild; /* Point to first sibling hwnd */
99 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
100 while (*hwndPtr)
102 WND * nextPtr = WIN_FindWndPtr( *hwndPtr );
103 hwndPtr = &nextPtr->hwndNext;
106 else /* Normal case */
108 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
109 if (afterPtr) hwndPtr = &afterPtr->hwndNext;
111 if (!hwndPtr) return FALSE;
112 wndPtr->hwndNext = *hwndPtr;
113 *hwndPtr = hwnd;
114 return TRUE;
118 /***********************************************************************
119 * WIN_FindWinToRepaint
121 * Find a window that needs repaint.
123 HWND WIN_FindWinToRepaint( HWND hwnd )
125 WND * wndPtr;
127 /* Note: the desktop window never gets WM_PAINT messages */
128 if (!hwnd) hwnd = GetTopWindow( hwndDesktop );
129 for ( ; hwnd != 0; hwnd = wndPtr->hwndNext )
131 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
132 if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT))
133 return hwnd;
134 if (wndPtr->hwndChild)
136 HWND child;
137 if ((child = WIN_FindWinToRepaint( wndPtr->hwndChild )))
138 return child;
141 return 0;
145 /***********************************************************************
146 * WIN_SendParentNotify
148 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
149 * the window has the WS_EX_NOPARENTNOTIFY style.
151 void WIN_SendParentNotify( HWND hwnd, WORD event, LONG lParam )
153 HWND current = GetParent( hwnd );
154 WND *wndPtr = WIN_FindWndPtr( hwnd );
156 if (!wndPtr || (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY)) return;
157 while (current)
159 SendMessage( current, WM_PARENTNOTIFY, event, lParam );
160 current = GetParent( current );
165 /***********************************************************************
166 * WIN_CreateDesktopWindow
168 * Create the desktop window.
170 BOOL WIN_CreateDesktopWindow()
172 WND *wndPtr;
173 HCLASS hclass;
174 CLASS *classPtr;
176 if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_NAME, &classPtr )))
177 return FALSE;
179 hwndDesktop = USER_HEAP_ALLOC( GMEM_MOVEABLE,
180 sizeof(WND)+classPtr->wc.cbWndExtra );
181 if (!hwndDesktop) return FALSE;
182 wndPtr = (WND *) USER_HEAP_ADDR( hwndDesktop );
184 wndPtr->hwndNext = 0;
185 wndPtr->hwndChild = 0;
186 wndPtr->dwMagic = WND_MAGIC;
187 wndPtr->hwndParent = 0;
188 wndPtr->hwndOwner = 0;
189 wndPtr->hClass = hclass;
190 wndPtr->hInstance = 0;
191 wndPtr->rectWindow.left = 0;
192 wndPtr->rectWindow.top = 0;
193 wndPtr->rectWindow.right = SYSMETRICS_CXSCREEN;
194 wndPtr->rectWindow.bottom = SYSMETRICS_CYSCREEN;
195 wndPtr->rectClient = wndPtr->rectWindow;
196 wndPtr->rectNormal = wndPtr->rectWindow;
197 wndPtr->ptIconPos.x = -1;
198 wndPtr->ptIconPos.y = -1;
199 wndPtr->ptMaxPos.x = -1;
200 wndPtr->ptMaxPos.y = -1;
201 wndPtr->hmemTaskQ = 0; /* Desktop does not belong to a task */
202 wndPtr->hrgnUpdate = 0;
203 wndPtr->hwndLastActive = 0;
204 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
205 wndPtr->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
206 wndPtr->dwExStyle = 0;
207 wndPtr->hdce = 0;
208 wndPtr->VScroll = NULL;
209 wndPtr->HScroll = NULL;
210 wndPtr->scroll_flags = 0;
211 wndPtr->wIDmenu = 0;
212 wndPtr->hText = 0;
213 wndPtr->flags = 0;
214 wndPtr->window = rootWindow;
215 wndPtr->hSysMenu = 0;
216 wndPtr->hProp = 0;
217 wndPtr->hTask = 0;
219 /* Send dummy WM_NCCREATE message */
220 SendMessage( hwndDesktop, WM_NCCREATE, 0, 0 );
221 EVENT_RegisterWindow( wndPtr->window, hwndDesktop );
222 RedrawWindow( hwndDesktop, NULL, 0,
223 RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW );
224 return TRUE;
228 /***********************************************************************
229 * CreateWindow (USER.41)
231 HWND CreateWindow( LPSTR className, LPSTR windowName,
232 DWORD style, short x, short y, short width, short height,
233 HWND parent, HMENU menu, HANDLE instance, LPSTR data )
235 return CreateWindowEx( 0, className, windowName, style,
236 x, y, width, height, parent, menu, instance, data );
240 /***********************************************************************
241 * CreateWindowEx (USER.452)
243 HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
244 DWORD style, short x, short y, short width, short height,
245 HWND parent, HMENU menu, HANDLE instance, LPSTR data )
247 HANDLE class, hwnd;
248 CLASS *classPtr;
249 WND *wndPtr, *parentPtr = NULL;
250 POINT maxSize, maxPos, minTrack, maxTrack;
251 CREATESTRUCT *createStruct;
252 HANDLE hcreateStruct;
253 int wmcreate;
254 XSetWindowAttributes win_attr;
256 #ifdef DEBUG_WIN
257 printf( "CreateWindowEx: %04X '%s' '%s' %04X %d,%d %dx%d %04X %04X %04X %08X\n",
258 exStyle, className, windowName, style, x, y, width, height,
259 parent, menu, instance, data);
260 #endif
261 /* 'soundrec.exe' has negative position !
262 Why ? For now, here a patch : */
263 if (!strcmp(className, "SoundRec"))
265 if (x < 0) x = 0;
266 if (y < 0) y = 0;
268 if (x == CW_USEDEFAULT) x = y = 0;
269 if (width == CW_USEDEFAULT)
271 width = 600;
272 height = 400;
274 if (width == 0) width = 1;
275 if (height == 0) height = 1;
277 /* Find the parent and class */
279 if (parent)
281 /* Check if parent is valid */
282 if (!(parentPtr = WIN_FindWndPtr( parent ))) return 0;
284 else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */
286 if (!(class = CLASS_FindClassByName( className, &classPtr ))) {
287 printf("CreateWindow BAD CLASSNAME '%s' !\n", className);
288 return 0;
291 /* Correct the window style */
293 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
294 style |= WS_CAPTION | WS_CLIPSIBLINGS;
295 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
297 /* Create the window structure */
299 hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra);
300 if (!hwnd) return 0;
302 /* Fill the structure */
304 wndPtr = (WND *) USER_HEAP_ADDR( hwnd );
305 wndPtr->hwndNext = 0;
306 wndPtr->hwndChild = 0;
307 wndPtr->window = 0;
308 wndPtr->dwMagic = WND_MAGIC;
309 wndPtr->hwndParent = (style & WS_CHILD) ? parent : hwndDesktop;
310 wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : parent;
311 wndPtr->hClass = class;
312 wndPtr->hInstance = instance;
313 wndPtr->rectWindow.left = x;
314 wndPtr->rectWindow.top = y;
315 wndPtr->rectWindow.right = x + width;
316 wndPtr->rectWindow.bottom = y + height;
317 wndPtr->rectClient = wndPtr->rectWindow;
318 wndPtr->rectNormal = wndPtr->rectWindow;
319 wndPtr->ptIconPos.x = -1;
320 wndPtr->ptIconPos.y = -1;
321 wndPtr->ptMaxPos.x = -1;
322 wndPtr->ptMaxPos.y = -1;
323 wndPtr->hmemTaskQ = GetTaskQueue(0);
324 wndPtr->hrgnUpdate = 0;
325 wndPtr->hwndPrevActive = 0;
326 wndPtr->hwndLastActive = 0;
327 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
328 wndPtr->dwStyle = style;
329 wndPtr->dwExStyle = exStyle;
330 wndPtr->wIDmenu = 0;
331 wndPtr->hText = 0;
332 wndPtr->flags = 0;
333 wndPtr->VScroll = NULL;
334 wndPtr->HScroll = NULL;
335 wndPtr->scroll_flags = 0;
336 wndPtr->hSysMenu = 0;
337 wndPtr->hProp = 0;
338 wndPtr->hTask = 0;
340 if (classPtr->wc.cbWndExtra)
341 memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
342 if (classPtr->wc.style & CS_DBLCLKS) wndPtr->flags |= WIN_DOUBLE_CLICKS;
343 classPtr->cWindows++;
345 /* Get class or window DC if needed */
346 if (classPtr->wc.style & CS_OWNDC)
348 wndPtr->flags |= WIN_OWN_DC;
349 wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC );
351 else if (classPtr->wc.style & CS_CLASSDC)
353 wndPtr->flags |= WIN_CLASS_DC;
354 wndPtr->hdce = classPtr->hdce;
356 else wndPtr->hdce = 0;
358 /* Insert the window in the linked list */
360 WIN_LinkWindow( hwnd, HWND_TOP );
362 /* Create the X window */
364 win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
365 PointerMotionMask | ButtonPressMask |
366 ButtonReleaseMask | EnterWindowMask;
367 win_attr.override_redirect = (rootWindow == DefaultRootWindow(display));
368 win_attr.colormap = COLOR_WinColormap;
369 if (!(style & WS_CHILD))
371 parentPtr = WIN_FindWndPtr( hwndDesktop );
372 /* Only select focus events on top-level override-redirect windows */
373 if (win_attr.override_redirect) win_attr.event_mask |= FocusChangeMask;
375 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
376 win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0);
378 WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
380 if ( maxSize.x < width)
382 width = maxSize.x;
383 wndPtr->rectWindow.right = x + width;
385 if ( maxSize.y < height)
387 height = maxSize.y;
388 wndPtr->rectWindow.bottom = y + height;
391 wndPtr->window = XCreateWindow( display, parentPtr->window,
392 x + parentPtr->rectClient.left - parentPtr->rectWindow.left,
393 y + parentPtr->rectClient.top - parentPtr->rectWindow.top,
394 width, height, 0,
395 CopyFromParent, InputOutput, CopyFromParent,
396 CWEventMask | CWOverrideRedirect | CWColormap |
397 CWSaveUnder | CWBackingStore, &win_attr );
398 XStoreName( display, wndPtr->window, windowName );
402 * store icon handle, icon handle is kept in class. If we
403 * have an icon, make the icon size the size of the icon,
404 * if we don't have an icon, just give it 64x64
406 wndPtr->hIcon = classPtr->wc.hIcon;
407 if (wndPtr->hIcon != (HICON)NULL) {
408 ICONALLOC *lpico;
409 lpico = (ICONALLOC *)GlobalLock(wndPtr->hIcon);
410 wndPtr->iconWidth = (int)lpico->descriptor.Width;
411 wndPtr->iconHeight = (int)lpico->descriptor.Height;
412 } else {
413 wndPtr->iconWidth = 64;
414 wndPtr->iconHeight = 64;
417 #ifdef DEBUG_MENU
418 printf("CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n",
419 menu, instance, classPtr->wc.lpszMenuName);
420 #endif
421 if ((style & WS_CAPTION) && (style & WS_CHILD) == 0) {
422 if (menu != 0)
423 SetMenu(hwnd, menu);
424 else {
425 if (classPtr->wc.lpszMenuName != NULL)
426 SetMenu(hwnd, LoadMenu(instance, classPtr->wc.lpszMenuName));
429 else
430 wndPtr->wIDmenu = menu;
432 /* Send the WM_CREATE message */
434 hcreateStruct = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CREATESTRUCT) );
435 createStruct = (CREATESTRUCT *) USER_HEAP_ADDR( hcreateStruct );
436 createStruct->lpCreateParams = data;
437 createStruct->hInstance = instance;
438 createStruct->hMenu = menu;
439 createStruct->hwndParent = parent;
440 createStruct->cx = width;
441 createStruct->cy = height;
442 createStruct->x = x;
443 createStruct->y = y;
444 createStruct->style = style;
445 createStruct->lpszName = windowName;
446 createStruct->lpszClass = className;
447 createStruct->dwExStyle = 0;
449 wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LONG)createStruct );
450 if (!wmcreate) wmcreate = -1;
451 else
453 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
454 NULL, NULL, NULL, &wndPtr->rectClient );
455 wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct );
458 USER_HEAP_FREE( hcreateStruct );
460 if (wmcreate == -1)
462 /* Abort window creation */
464 WIN_UnlinkWindow( hwnd );
465 XDestroyWindow( display, wndPtr->window );
466 if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
467 classPtr->cWindows--;
468 USER_HEAP_FREE( hwnd );
469 return 0;
472 /* Create a copy of SysMenu */
473 if (style & WS_SYSMENU) wndPtr->hSysMenu = CopySysMenu();
475 /* Register window in current task windows list */
476 AddWindowToTask(GetCurrentTask(), hwnd);
478 /* Set window cursor */
479 if (classPtr->wc.hCursor) CURSOR_SetWinCursor( hwnd, classPtr->wc.hCursor);
480 else CURSOR_SetWinCursor( hwnd, LoadCursor( 0, IDC_ARROW ));
482 EVENT_RegisterWindow( wndPtr->window, hwnd );
484 WIN_SendParentNotify( hwnd, WM_CREATE, MAKELONG( hwnd, wndPtr->wIDmenu ) );
486 if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
487 /* if (style & WS_MINIMIZE) ShowWindow( hwnd, SW_MINIMIZE ); */
489 #ifdef DEBUG_WIN
490 printf( "CreateWindowEx: return %04X \n", hwnd);
491 #endif
492 return hwnd;
496 /***********************************************************************
497 * DestroyWindow (USER.53)
499 BOOL DestroyWindow( HWND hwnd )
501 WND * wndPtr;
502 CLASS * classPtr;
504 /* Initialisation */
506 if (hwnd == hwndDesktop) return FALSE; /* Can't destroy desktop */
507 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
508 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return FALSE;
510 /* Hide the window */
512 if (wndPtr->dwStyle & WS_VISIBLE)
513 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE |
514 SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
515 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
516 ReleaseCapture();
517 WIN_SendParentNotify( hwnd, WM_DESTROY, MAKELONG(hwnd, wndPtr->wIDmenu) );
519 /* Send destroy messages and destroy children */
521 SendMessage( hwnd, WM_DESTROY, 0, 0 );
522 while (wndPtr->hwndChild) /* The child removes itself from the list */
523 DestroyWindow( wndPtr->hwndChild );
524 SendMessage( hwnd, WM_NCDESTROY, 0, 0 );
526 /* Remove the window from current task windows list */
527 RemoveWindowFromTask(GetCurrentTask(), hwnd);
529 /* Remove the window from the linked list */
530 WIN_UnlinkWindow( hwnd );
532 /* Destroy the window */
534 wndPtr->dwMagic = 0; /* Mark it as invalid */
535 XDestroyWindow( display, wndPtr->window );
536 if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
537 classPtr->cWindows--;
538 USER_HEAP_FREE( hwnd );
539 return TRUE;
543 /***********************************************************************
544 * CloseWindow (USER.43)
546 void CloseWindow(HWND hWnd)
548 WND * wndPtr = WIN_FindWndPtr(hWnd);
549 if (wndPtr->dwStyle & WS_CHILD) return;
550 ShowWindow(hWnd, SW_MINIMIZE);
555 /***********************************************************************
556 * OpenIcon (USER.44)
558 BOOL OpenIcon(HWND hWnd)
560 if (!IsIconic(hWnd)) return FALSE;
561 ShowWindow(hWnd, SW_SHOWNORMAL);
562 return(TRUE);
567 /***********************************************************************
568 * FindWindow (USER.50)
570 HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch)
572 HCLASS hclass;
573 CLASS *classPtr;
574 HWND hwnd;
576 if (ClassMatch)
578 hclass = CLASS_FindClassByName( ClassMatch, &classPtr );
579 if (!hclass) return 0;
581 else hclass = 0;
583 hwnd = GetTopWindow( hwndDesktop );
584 while(hwnd)
586 WND *wndPtr = WIN_FindWndPtr( hwnd );
587 if (!hclass || (wndPtr->hClass == hclass))
589 /* Found matching class */
590 if (!TitleMatch) return hwnd;
591 if (wndPtr->hText)
593 char *textPtr = (char *) USER_HEAP_ADDR( wndPtr->hText );
594 if (!strcmp( textPtr, TitleMatch )) return hwnd;
597 hwnd = wndPtr->hwndNext;
599 return 0;
603 /**********************************************************************
604 * GetDesktopWindow (USER.286)
605 * GetDeskTopHwnd (USER.278)
607 HWND GetDesktopWindow(void)
609 return hwndDesktop;
613 /*******************************************************************
614 * EnableWindow (USER.34)
616 BOOL EnableWindow( HWND hwnd, BOOL enable )
618 WND *wndPtr;
620 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
621 if (enable && (wndPtr->dwStyle & WS_DISABLED))
623 /* Enable window */
624 wndPtr->dwStyle &= ~WS_DISABLED;
625 SendMessage( hwnd, WM_ENABLE, TRUE, 0 );
626 return TRUE;
628 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
630 /* Disable window */
631 wndPtr->dwStyle |= WS_DISABLED;
632 if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
633 SetFocus( 0 ); /* A disabled window can't have the focus */
634 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
635 ReleaseCapture(); /* A disabled window can't capture the mouse */
636 SendMessage( hwnd, WM_ENABLE, FALSE, 0 );
637 return FALSE;
639 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
643 /***********************************************************************
644 * IsWindowEnabled (USER.35)
646 BOOL IsWindowEnabled(HWND hWnd)
648 WND * wndPtr;
650 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
651 return !(wndPtr->dwStyle & WS_DISABLED);
655 /**********************************************************************
656 * GetWindowWord (USER.133)
658 WORD GetWindowWord( HWND hwnd, short offset )
660 WND * wndPtr = WIN_FindWndPtr( hwnd );
661 if (!wndPtr) return 0;
662 if (offset >= 0) return *(WORD *)(((char *)wndPtr->wExtra) + offset);
663 switch(offset)
665 case GWW_ID: return wndPtr->wIDmenu;
666 case GWW_HWNDPARENT: return wndPtr->hwndParent;
667 case GWW_HINSTANCE: return wndPtr->hInstance;
669 return 0;
673 /**********************************************************************
674 * SetWindowWord (USER.134)
676 WORD SetWindowWord( HWND hwnd, short offset, WORD newval )
678 WORD *ptr, retval;
679 WND * wndPtr = WIN_FindWndPtr( hwnd );
680 if (!wndPtr) return 0;
681 if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
682 else switch(offset)
684 case GWW_ID: ptr = &wndPtr->wIDmenu;
685 case GWW_HINSTANCE: ptr = &wndPtr->hInstance;
686 default: return 0;
688 retval = *ptr;
689 *ptr = newval;
690 return retval;
694 /**********************************************************************
695 * GetWindowLong (USER.135)
697 LONG GetWindowLong( HWND hwnd, short offset )
699 WND * wndPtr = WIN_FindWndPtr( hwnd );
700 if (!wndPtr) return 0;
701 if (offset >= 0) return *(LONG *)(((char *)wndPtr->wExtra) + offset);
702 switch(offset)
704 case GWL_STYLE: return wndPtr->dwStyle;
705 case GWL_EXSTYLE: return wndPtr->dwExStyle;
706 case GWL_WNDPROC: return (LONG)wndPtr->lpfnWndProc;
708 return 0;
712 /**********************************************************************
713 * SetWindowLong (USER.136)
715 LONG SetWindowLong( HWND hwnd, short offset, LONG newval )
717 LONG *ptr, retval;
718 WND * wndPtr = WIN_FindWndPtr( hwnd );
719 if (!wndPtr) return 0;
720 if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
721 else switch(offset)
723 case GWL_STYLE: ptr = &wndPtr->dwStyle;
724 break;
725 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle;
726 break;
727 case GWL_WNDPROC: ptr = (LONG *)(&wndPtr->lpfnWndProc);
728 break;
729 default: return 0;
731 retval = *ptr;
732 *ptr = newval;
733 return retval;
737 /*******************************************************************
738 * GetWindowText (USER.36)
740 int GetWindowText(HWND hwnd, LPSTR lpString, int nMaxCount)
742 return (int)SendMessage(hwnd, WM_GETTEXT, (WORD)nMaxCount,
743 (DWORD)lpString);
746 /*******************************************************************
747 * SetWindowText (USER.37)
749 void SetWindowText(HWND hwnd, LPSTR lpString)
751 SendMessage(hwnd, WM_SETTEXT, (WORD)NULL, (DWORD)lpString);
754 /*******************************************************************
755 * GetWindowTextLength (USER.38)
757 int GetWindowTextLength(HWND hwnd)
759 return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, (WORD)NULL,
760 (DWORD)NULL);
764 /*******************************************************************
765 * IsWindow (USER.47)
767 BOOL IsWindow( HWND hwnd )
769 WND * wndPtr = WIN_FindWndPtr( hwnd );
770 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
774 /*****************************************************************
775 * GetParent (USER.46)
777 HWND GetParent(HWND hwnd)
779 WND *wndPtr = WIN_FindWndPtr(hwnd);
780 if (!wndPtr || !(wndPtr->dwStyle & WS_CHILD)) return 0;
781 return wndPtr->hwndParent;
784 /*****************************************************************
785 * SetParent (USER.233)
787 HWND SetParent(HWND hwndChild, HWND hwndNewParent)
789 HWND temp;
791 WND *wndPtr = WIN_FindWndPtr(hwndChild);
792 if (!wndPtr || !(wndPtr->dwStyle & WS_CHILD)) return 0;
794 temp = wndPtr->hwndParent;
796 if (hwndNewParent)
797 wndPtr->hwndParent = hwndNewParent;
798 else
799 wndPtr->hwndParent = GetDesktopWindow();
801 return temp;
806 /*******************************************************************
807 * IsChild (USER.48)
809 BOOL IsChild( HWND parent, HWND child )
811 WND * wndPtr = WIN_FindWndPtr( child );
812 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
814 if (wndPtr->hwndParent == parent) return TRUE;
815 wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
817 return FALSE;
821 /***********************************************************************
822 * IsWindowVisible (USER.49)
824 BOOL IsWindowVisible(HWND hWnd)
826 WND * wndPtr = WIN_FindWndPtr(hWnd);
827 if (wndPtr == 0) return(FALSE);
828 else return ((wndPtr->dwStyle & WS_VISIBLE) != 0);
833 /*******************************************************************
834 * GetTopWindow (USER.229)
836 HWND GetTopWindow( HWND hwnd )
838 WND * wndPtr = WIN_FindWndPtr( hwnd );
839 if (wndPtr) return wndPtr->hwndChild;
840 else return 0;
844 /*******************************************************************
845 * GetWindow (USER.262)
847 HWND GetWindow( HWND hwnd, WORD rel )
849 WND * wndPtr = WIN_FindWndPtr( hwnd );
850 if (!wndPtr) return 0;
851 switch(rel)
853 case GW_HWNDFIRST:
854 if (wndPtr->hwndParent)
856 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
857 return parentPtr->hwndChild;
859 else return 0;
861 case GW_HWNDLAST:
862 if (!wndPtr->hwndParent) return 0; /* Desktop window */
863 while (wndPtr->hwndNext)
865 hwnd = wndPtr->hwndNext;
866 wndPtr = WIN_FindWndPtr( hwnd );
868 return hwnd;
870 case GW_HWNDNEXT:
871 return wndPtr->hwndNext;
873 case GW_HWNDPREV:
875 HWND hwndPrev;
877 if (wndPtr->hwndParent)
879 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
880 hwndPrev = parentPtr->hwndChild;
882 else return 0; /* Desktop window */
883 if (hwndPrev == hwnd) return 0;
884 while (hwndPrev)
886 wndPtr = WIN_FindWndPtr( hwndPrev );
887 if (wndPtr->hwndNext == hwnd) break;
888 hwndPrev = wndPtr->hwndNext;
890 return hwndPrev;
893 case GW_OWNER:
894 return wndPtr->hwndOwner;
896 case GW_CHILD:
897 return wndPtr->hwndChild;
899 return 0;
903 /*******************************************************************
904 * GetNextWindow (USER.230)
906 HWND GetNextWindow( HWND hwnd, WORD flag )
908 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
909 return GetWindow( hwnd, flag );
915 /*******************************************************************
916 * EnumWindows (USER.54)
918 * o gets the desktop window and iterates over all the windows
919 * which are direct decendents of the desktop * by iterating over
920 * the desktop's child window and all the child windows next
921 * pointers
923 * o call wndenumprc for every child window the desktop has
924 * (parameters to Callback16 passed backwards so they are
925 * put in in pascal calling order)
927 * o if wndenumprc returns 0 exit
930 BOOL EnumWindows(FARPROC wndenumprc, LPARAM lParam)
932 HWND hwnd = GetTopWindow( GetDesktopWindow() );
933 WND *wndPtr;
934 int result;
936 #ifdef DEBUG_ENUM
937 printf("EnumWindows\n");
938 #endif
940 while (hwnd) {
941 char *ptr;
943 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
944 return 0;
946 #ifdef DEBUG_ENUM
947 if (XFetchName(display, wndPtr->window, &ptr) && ptr)
948 printf("found a window (%s)\n", ptr);
949 else
950 printf("found nameless parent window\n");
951 #endif
952 #ifdef WINELIB
953 (*wndenumprc)(hwnd, lParam);
954 #else
955 result = CallBack16(wndenumprc, 2, lParam, (int) hwnd);
956 #endif
957 if ( ! result ) {
958 return 0;
960 hwnd=wndPtr->hwndNext;
962 return 1; /* for now */
965 /*******************************************************************
966 * WIN_EnumChildWin
968 * o hwnd is the first child to use, loop until all next windows
969 * are processed
971 * o call wdnenumprc with parameters in inverse order (pascal)
973 * o call ourselves with the next child window
976 static BOOL WIN_EnumChildWin(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
978 WND *wndPtr;
979 int result;
982 while (hwnd) {
983 char *ptr;
984 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
985 return 0;
987 #ifdef DEBUG_ENUM
988 if (XFetchName(display, wndPtr->window, &ptr) && ptr)
989 printf("EnumChild: found a child window (%s)\n", ptr);
990 else
991 printf("EnumChild: nameless child\n");
993 if (!(wndPtr->dwStyle & WS_CHILD)) {
994 printf("this is not a child window! What is it doing here?\n");
995 return 0;
997 #endif
998 #ifdef WINELIB
999 if (!(*wndenumprc, 2, lParam, (int) hwnd)) {
1000 #else
1001 if (!CallBack16(wndenumprc, 2, lParam, (int) hwnd)) {
1002 #endif
1003 return 0;
1005 if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) {
1006 return 0;
1008 hwnd=wndPtr->hwndNext;
1010 return 1;
1013 /*******************************************************************
1014 * EnumChildWindows (USER.55)
1016 * o gets the first child of hwnd
1018 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1020 BOOL EnumChildWindows(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
1022 WND *wndPtr;
1024 #ifdef DEBUG_ENUM
1025 printf("EnumChildWindows\n");
1026 #endif
1028 if (hwnd == 0) return 0;
1029 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1030 hwnd = wndPtr->hwndChild;
1031 return WIN_EnumChildWin(hwnd, wndenumprc, lParam);
1034 /*******************************************************************
1035 * AnyPopup [USER.52]
1037 BOOL AnyPopup()
1039 printf("EMPTY STUB !! AnyPopup !\n");
1040 return FALSE;
1043 /*******************************************************************
1044 * FlashWindow [USER.105]
1046 BOOL FlashWindow(HWND hWnd, BOOL bInvert)
1048 printf("EMPTY STUB !! FlashWindow !\n");
1049 return FALSE;
1053 /*******************************************************************
1054 * SetSysModalWindow [USER.188]
1056 HWND SetSysModalWindow(HWND hWnd)
1058 HWND hWndOldModal = hWndSysModal;
1059 hWndSysModal = hWnd;
1060 printf("EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd);
1061 return hWndOldModal;
1065 /*******************************************************************
1066 * GetSysModalWindow [USER.189]
1068 HWND GetSysModalWindow(void)
1070 return hWndSysModal;