Release 940714
[wine/multimedia.git] / windows / win.c
blobf03902d18c9a27da3c94db3a72d6018cabd629f1
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 CREATESTRUCT *createStruct;
251 HANDLE hcreateStruct;
252 int wmcreate;
253 XSetWindowAttributes win_attr, icon_attr;
254 int iconWidth, iconHeight;
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 (x < 0) x = 0;
264 if (y < 0) y = 0;
265 if (x == CW_USEDEFAULT) x = y = 0;
266 if (width == CW_USEDEFAULT)
268 width = 600;
269 height = 400;
271 if (width == 0) width = 1;
272 if (height == 0) height = 1;
274 /* Find the parent and class */
276 if (parent)
278 /* Check if parent is valid */
279 if (!(parentPtr = WIN_FindWndPtr( parent ))) return 0;
281 else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */
283 if (!(class = CLASS_FindClassByName( className, &classPtr ))) {
284 printf("CreateWindow BAD CLASSNAME '%s' !\n", className);
285 return 0;
288 /* Correct the window style */
290 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
291 style |= WS_CAPTION | WS_CLIPSIBLINGS;
292 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
294 /* Create the window structure */
296 hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra);
297 if (!hwnd) return 0;
299 /* Fill the structure */
301 wndPtr = (WND *) USER_HEAP_ADDR( hwnd );
302 wndPtr->hwndNext = 0;
303 wndPtr->hwndChild = 0;
304 wndPtr->window = 0;
305 wndPtr->dwMagic = WND_MAGIC;
306 wndPtr->hwndParent = (style & WS_CHILD) ? parent : hwndDesktop;
307 wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : parent;
308 wndPtr->hClass = class;
309 wndPtr->hInstance = instance;
310 wndPtr->rectWindow.left = x;
311 wndPtr->rectWindow.top = y;
312 wndPtr->rectWindow.right = x + width;
313 wndPtr->rectWindow.bottom = y + height;
314 wndPtr->rectClient = wndPtr->rectWindow;
315 wndPtr->rectNormal = wndPtr->rectWindow;
316 wndPtr->ptIconPos.x = -1;
317 wndPtr->ptIconPos.y = -1;
318 wndPtr->ptMaxPos.x = -1;
319 wndPtr->ptMaxPos.y = -1;
320 wndPtr->hmemTaskQ = GetTaskQueue(0);
321 wndPtr->hrgnUpdate = 0;
322 wndPtr->hwndPrevActive = 0;
323 wndPtr->hwndLastActive = 0;
324 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
325 wndPtr->dwStyle = style;
326 wndPtr->dwExStyle = exStyle;
327 wndPtr->wIDmenu = 0;
328 wndPtr->hText = 0;
329 wndPtr->flags = 0;
330 wndPtr->VScroll = NULL;
331 wndPtr->HScroll = NULL;
332 wndPtr->scroll_flags = 0;
333 wndPtr->hSysMenu = 0;
334 wndPtr->hProp = 0;
335 wndPtr->hTask = 0;
337 if (classPtr->wc.cbWndExtra)
338 memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
339 if (classPtr->wc.style & CS_DBLCLKS) wndPtr->flags |= WIN_DOUBLE_CLICKS;
340 classPtr->cWindows++;
342 /* Get class or window DC if needed */
343 if (classPtr->wc.style & CS_OWNDC)
345 wndPtr->flags |= WIN_OWN_DC;
346 wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC );
348 else if (classPtr->wc.style & CS_CLASSDC)
350 wndPtr->flags |= WIN_CLASS_DC;
351 wndPtr->hdce = classPtr->hdce;
353 else wndPtr->hdce = 0;
355 /* Insert the window in the linked list */
357 WIN_LinkWindow( hwnd, HWND_TOP );
359 /* Create the X window */
361 win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
362 PointerMotionMask | ButtonPressMask |
363 ButtonReleaseMask | EnterWindowMask;
364 win_attr.override_redirect = (rootWindow == DefaultRootWindow(display));
365 win_attr.colormap = COLOR_WinColormap;
366 if (!(style & WS_CHILD))
368 parentPtr = WIN_FindWndPtr( hwndDesktop );
369 /* Only select focus events on top-level override-redirect windows */
370 if (win_attr.override_redirect) win_attr.event_mask |= FocusChangeMask;
372 if (Options.nobackingstore)
373 win_attr.backing_store = NotUseful;
374 else
375 win_attr.backing_store = Always;
377 win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0);
379 wndPtr->window = XCreateWindow( display, parentPtr->window,
380 x + parentPtr->rectClient.left - parentPtr->rectWindow.left,
381 y + parentPtr->rectClient.top - parentPtr->rectWindow.top,
382 width, height, 0,
383 CopyFromParent, InputOutput, CopyFromParent,
384 CWEventMask | CWOverrideRedirect | CWColormap |
385 CWSaveUnder | CWBackingStore, &win_attr );
386 XStoreName( display, wndPtr->window, windowName );
389 /* create icon window */
391 icon_attr.override_redirect = rootWindow==DefaultRootWindow(display);
392 icon_attr.background_pixel = WhitePixelOfScreen(screen);
393 icon_attr.event_mask = ExposureMask | KeyPressMask |
394 ButtonPressMask | ButtonReleaseMask;
396 wndPtr->hIcon = classPtr->wc.hIcon;
397 if (wndPtr->hIcon != (HICON)NULL) {
398 ICONALLOC *lpico;
399 lpico = (ICONALLOC *)GlobalLock(wndPtr->hIcon);
400 printf("icon is %d x %d\n",
401 (int)lpico->descriptor.Width,
402 (int)lpico->descriptor.Height);
403 iconWidth = (int)lpico->descriptor.Width;
404 iconHeight = (int)lpico->descriptor.Height;
405 } else {
406 printf("icon was NULL\n");
407 iconWidth = 64;
408 iconHeight = 64;
411 wndPtr->icon = XCreateWindow(display, parentPtr->window,
412 10, 10, 100, iconHeight+20,
413 0, CopyFromParent,
414 InputOutput, CopyFromParent,
415 CWBorderPixel | CWEventMask | CWOverrideRedirect,
416 &icon_attr);
418 if (style & WS_MINIMIZE)
420 style &= ~WS_MINIMIZE;
425 #ifdef DEBUG_MENU
426 printf("CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n",
427 menu, instance, classPtr->wc.lpszMenuName);
428 #endif
429 if ((style & WS_CAPTION) && (style & WS_CHILD) == 0) {
430 if (menu != 0)
431 SetMenu(hwnd, menu);
432 else {
433 if (classPtr->wc.lpszMenuName != NULL)
434 SetMenu(hwnd, LoadMenu(instance, classPtr->wc.lpszMenuName));
437 else
438 wndPtr->wIDmenu = menu;
440 /* Send the WM_CREATE message */
442 hcreateStruct = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CREATESTRUCT) );
443 createStruct = (CREATESTRUCT *) USER_HEAP_ADDR( hcreateStruct );
444 createStruct->lpCreateParams = data;
445 createStruct->hInstance = instance;
446 createStruct->hMenu = menu;
447 createStruct->hwndParent = parent;
448 createStruct->cx = width;
449 createStruct->cy = height;
450 createStruct->x = x;
451 createStruct->y = y;
452 createStruct->style = style;
453 createStruct->lpszName = windowName;
454 createStruct->lpszClass = className;
455 createStruct->dwExStyle = 0;
457 wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LONG)createStruct );
458 if (!wmcreate) wmcreate = -1;
459 else
461 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
462 NULL, NULL, NULL, &wndPtr->rectClient );
463 wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct );
466 USER_HEAP_FREE( hcreateStruct );
468 if (wmcreate == -1)
470 /* Abort window creation */
472 WIN_UnlinkWindow( hwnd );
473 XDestroyWindow( display, wndPtr->window );
474 if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
475 classPtr->cWindows--;
476 USER_HEAP_FREE( hwnd );
477 return 0;
480 /* Create a copy of SysMenu */
481 if (style & WS_SYSMENU) wndPtr->hSysMenu = CopySysMenu();
483 /* Register window in current task windows list */
484 AddWindowToTask(GetCurrentTask(), hwnd);
486 /* Set window cursor */
487 if (classPtr->wc.hCursor) CURSOR_SetWinCursor( hwnd, classPtr->wc.hCursor);
488 else CURSOR_SetWinCursor( hwnd, LoadCursor( 0, IDC_ARROW ));
490 EVENT_RegisterWindow( wndPtr->window, hwnd );
491 EVENT_RegisterWindow( wndPtr->icon, hwnd );
493 WIN_SendParentNotify( hwnd, WM_CREATE, MAKELONG( hwnd, wndPtr->wIDmenu ) );
495 if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
496 #ifdef DEBUG_WIN
497 printf( "CreateWindowEx: return %04X \n", hwnd);
498 #endif
499 return hwnd;
503 /***********************************************************************
504 * DestroyWindow (USER.53)
506 BOOL DestroyWindow( HWND hwnd )
508 WND * wndPtr;
509 CLASS * classPtr;
511 /* Initialisation */
513 if (hwnd == hwndDesktop) return FALSE; /* Can't destroy desktop */
514 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
515 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return FALSE;
517 /* Hide the window */
519 if (wndPtr->dwStyle & WS_VISIBLE)
520 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE |
521 SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
522 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
523 ReleaseCapture();
524 WIN_SendParentNotify( hwnd, WM_DESTROY, MAKELONG(hwnd, wndPtr->wIDmenu) );
526 /* Send destroy messages and destroy children */
528 SendMessage( hwnd, WM_DESTROY, 0, 0 );
529 while (wndPtr->hwndChild) /* The child removes itself from the list */
530 DestroyWindow( wndPtr->hwndChild );
531 SendMessage( hwnd, WM_NCDESTROY, 0, 0 );
533 /* Remove the window from current task windows list */
534 RemoveWindowFromTask(GetCurrentTask(), hwnd);
536 /* Remove the window from the linked list */
537 WIN_UnlinkWindow( hwnd );
539 /* Destroy the window */
541 wndPtr->dwMagic = 0; /* Mark it as invalid */
542 XDestroyWindow( display, wndPtr->window );
543 if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
544 classPtr->cWindows--;
545 USER_HEAP_FREE( hwnd );
546 return TRUE;
550 /***********************************************************************
551 * CloseWindow (USER.43)
553 void CloseWindow(HWND hWnd)
555 WND * wndPtr = WIN_FindWndPtr(hWnd);
556 if (wndPtr->dwStyle & WS_CHILD) return;
557 ShowWindow(hWnd, SW_MINIMIZE);
562 /***********************************************************************
563 * OpenIcon (USER.44)
565 BOOL OpenIcon(HWND hWnd)
567 if (!IsIconic(hWnd)) return FALSE;
568 ShowWindow(hWnd, SW_SHOWNORMAL);
569 return(TRUE);
574 /***********************************************************************
575 * FindWindow (USER.50)
577 HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch)
579 HCLASS hclass;
580 CLASS *classPtr;
581 HWND hwnd;
583 if (ClassMatch)
585 hclass = CLASS_FindClassByName( ClassMatch, &classPtr );
586 if (!hclass) return 0;
588 else hclass = 0;
590 hwnd = GetTopWindow( hwndDesktop );
591 while(hwnd)
593 WND *wndPtr = WIN_FindWndPtr( hwnd );
594 if (!hclass || (wndPtr->hClass == hclass))
596 /* Found matching class */
597 if (!TitleMatch) return hwnd;
598 if (wndPtr->hText)
600 char *textPtr = (char *) USER_HEAP_ADDR( wndPtr->hText );
601 if (!strcmp( textPtr, TitleMatch )) return hwnd;
604 hwnd = wndPtr->hwndNext;
606 return 0;
610 /**********************************************************************
611 * GetDesktopWindow (USER.286)
612 * GetDeskTopHwnd (USER.278)
614 HWND GetDesktopWindow(void)
616 return hwndDesktop;
620 /*******************************************************************
621 * EnableWindow (USER.34)
623 BOOL EnableWindow( HWND hwnd, BOOL enable )
625 WND *wndPtr;
627 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
628 if (enable && (wndPtr->dwStyle & WS_DISABLED))
630 /* Enable window */
631 wndPtr->dwStyle &= ~WS_DISABLED;
632 SendMessage( hwnd, WM_ENABLE, TRUE, 0 );
633 return TRUE;
635 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
637 /* Disable window */
638 wndPtr->dwStyle |= WS_DISABLED;
639 if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
640 SetFocus( 0 ); /* A disabled window can't have the focus */
641 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
642 ReleaseCapture(); /* A disabled window can't capture the mouse */
643 SendMessage( hwnd, WM_ENABLE, FALSE, 0 );
644 return FALSE;
646 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
650 /***********************************************************************
651 * IsWindowEnabled (USER.35)
653 BOOL IsWindowEnabled(HWND hWnd)
655 WND * wndPtr;
657 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
658 return !(wndPtr->dwStyle & WS_DISABLED);
662 /**********************************************************************
663 * GetWindowWord (USER.133)
665 WORD GetWindowWord( HWND hwnd, short offset )
667 WND * wndPtr = WIN_FindWndPtr( hwnd );
668 if (!wndPtr) return 0;
669 if (offset >= 0) return *(WORD *)(((char *)wndPtr->wExtra) + offset);
670 switch(offset)
672 case GWW_ID: return wndPtr->wIDmenu;
673 case GWW_HWNDPARENT: return wndPtr->hwndParent;
674 case GWW_HINSTANCE: return wndPtr->hInstance;
676 return 0;
680 /**********************************************************************
681 * SetWindowWord (USER.134)
683 WORD SetWindowWord( HWND hwnd, short offset, WORD newval )
685 WORD *ptr, retval;
686 WND * wndPtr = WIN_FindWndPtr( hwnd );
687 if (!wndPtr) return 0;
688 if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
689 else switch(offset)
691 case GWW_ID: ptr = &wndPtr->wIDmenu;
692 case GWW_HINSTANCE: ptr = &wndPtr->hInstance;
693 default: return 0;
695 retval = *ptr;
696 *ptr = newval;
697 return retval;
701 /**********************************************************************
702 * GetWindowLong (USER.135)
704 LONG GetWindowLong( HWND hwnd, short offset )
706 WND * wndPtr = WIN_FindWndPtr( hwnd );
707 if (!wndPtr) return 0;
708 if (offset >= 0) return *(LONG *)(((char *)wndPtr->wExtra) + offset);
709 switch(offset)
711 case GWL_STYLE: return wndPtr->dwStyle;
712 case GWL_EXSTYLE: return wndPtr->dwExStyle;
713 case GWL_WNDPROC: return (LONG)wndPtr->lpfnWndProc;
715 return 0;
719 /**********************************************************************
720 * SetWindowLong (USER.136)
722 LONG SetWindowLong( HWND hwnd, short offset, LONG newval )
724 LONG *ptr, retval;
725 WND * wndPtr = WIN_FindWndPtr( hwnd );
726 if (!wndPtr) return 0;
727 if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
728 else switch(offset)
730 case GWL_STYLE: ptr = &wndPtr->dwStyle;
731 break;
732 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle;
733 break;
734 case GWL_WNDPROC: ptr = (LONG *)(&wndPtr->lpfnWndProc);
735 break;
736 default: return 0;
738 retval = *ptr;
739 *ptr = newval;
740 return retval;
744 /*******************************************************************
745 * GetWindowText (USER.36)
747 int GetWindowText(HWND hwnd, LPSTR lpString, int nMaxCount)
749 return (int)SendMessage(hwnd, WM_GETTEXT, (WORD)nMaxCount,
750 (DWORD)lpString);
753 /*******************************************************************
754 * SetWindowText (USER.37)
756 void SetWindowText(HWND hwnd, LPSTR lpString)
758 SendMessage(hwnd, WM_SETTEXT, (WORD)NULL, (DWORD)lpString);
761 /*******************************************************************
762 * GetWindowTextLength (USER.38)
764 int GetWindowTextLength(HWND hwnd)
766 return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, (WORD)NULL,
767 (DWORD)NULL);
771 /*******************************************************************
772 * IsWindow (USER.47)
774 BOOL IsWindow( HWND hwnd )
776 WND * wndPtr = WIN_FindWndPtr( hwnd );
777 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
781 /*****************************************************************
782 * GetParent (USER.46)
784 HWND GetParent(HWND hwnd)
786 WND *wndPtr = WIN_FindWndPtr(hwnd);
787 if (!wndPtr || !(wndPtr->dwStyle & WS_CHILD)) return 0;
788 return wndPtr->hwndParent;
792 /*******************************************************************
793 * IsChild (USER.48)
795 BOOL IsChild( HWND parent, HWND child )
797 WND * wndPtr = WIN_FindWndPtr( child );
798 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
800 if (wndPtr->hwndParent == parent) return TRUE;
801 wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
803 return FALSE;
807 /***********************************************************************
808 * IsWindowVisible (USER.49)
810 BOOL IsWindowVisible(HWND hWnd)
812 WND * wndPtr = WIN_FindWndPtr(hWnd);
813 if (wndPtr == 0) return(FALSE);
814 else return ((wndPtr->dwStyle & WS_VISIBLE) != 0);
819 /*******************************************************************
820 * GetTopWindow (USER.229)
822 HWND GetTopWindow( HWND hwnd )
824 WND * wndPtr = WIN_FindWndPtr( hwnd );
825 if (wndPtr) return wndPtr->hwndChild;
826 else return 0;
830 /*******************************************************************
831 * GetWindow (USER.262)
833 HWND GetWindow( HWND hwnd, WORD rel )
835 WND * wndPtr = WIN_FindWndPtr( hwnd );
836 if (!wndPtr) return 0;
837 switch(rel)
839 case GW_HWNDFIRST:
840 if (wndPtr->hwndParent)
842 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
843 return parentPtr->hwndChild;
845 else return 0;
847 case GW_HWNDLAST:
848 if (!wndPtr->hwndParent) return 0; /* Desktop window */
849 while (wndPtr->hwndNext)
851 hwnd = wndPtr->hwndNext;
852 wndPtr = WIN_FindWndPtr( hwnd );
854 return hwnd;
856 case GW_HWNDNEXT:
857 return wndPtr->hwndNext;
859 case GW_HWNDPREV:
861 HWND hwndPrev;
863 if (wndPtr->hwndParent)
865 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
866 hwndPrev = parentPtr->hwndChild;
868 else return 0; /* Desktop window */
869 if (hwndPrev == hwnd) return 0;
870 while (hwndPrev)
872 wndPtr = WIN_FindWndPtr( hwndPrev );
873 if (wndPtr->hwndNext == hwnd) break;
874 hwndPrev = wndPtr->hwndNext;
876 return hwndPrev;
879 case GW_OWNER:
880 return wndPtr->hwndOwner;
882 case GW_CHILD:
883 return wndPtr->hwndChild;
885 return 0;
889 /*******************************************************************
890 * GetNextWindow (USER.230)
892 HWND GetNextWindow( HWND hwnd, WORD flag )
894 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
895 return GetWindow( hwnd, flag );
901 /*******************************************************************
902 * EnumWindows (USER.54)
904 * o gets the desktop window and iterates over all the windows
905 * which are direct decendents of the desktop * by iterating over
906 * the desktop's child window and all the child windows next
907 * pointers
909 * o call wndenumprc for every child window the desktop has
910 * (parameters to Callback16 passed backwards so they are
911 * put in in pascal calling order)
913 * o if wndenumprc returns 0 exit
916 BOOL EnumWindows(FARPROC wndenumprc, LPARAM lParam)
918 HWND hwnd = GetTopWindow( GetDesktopWindow() );
919 WND *wndPtr;
920 int result;
922 #ifdef DEBUG_ENUM
923 printf("EnumWindows\n");
924 #endif
926 while (hwnd) {
927 char *ptr;
929 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
930 return 0;
932 #ifdef DEBUG_ENUM
933 if (XFetchName(display, wndPtr->window, &ptr) && ptr)
934 printf("found a window (%s)\n", ptr);
935 else
936 printf("found nameless parent window\n");
937 #endif
938 #ifdef WINELIB
939 (*wndenumprc)(hwnd, lParam);
940 #else
941 result = CallBack16(wndenumprc, 2, lParam, (int) hwnd);
942 #endif
943 if ( ! result ) {
944 return 0;
946 hwnd=wndPtr->hwndNext;
948 return 1; /* for now */
951 /*******************************************************************
952 * WIN_EnumChildWin
954 * o hwnd is the first child to use, loop until all next windows
955 * are processed
957 * o call wdnenumprc with parameters in inverse order (pascal)
959 * o call ourselves with the next child window
962 static BOOL WIN_EnumChildWin(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
964 WND *wndPtr;
965 int result;
968 while (hwnd) {
969 char *ptr;
970 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
971 return 0;
973 #ifdef DEBUG_ENUM
974 if (XFetchName(display, wndPtr->window, &ptr) && ptr)
975 printf("EnumChild: found a child window (%s)\n", ptr);
976 else
977 printf("EnumChild: nameless child\n");
979 if (!(wndPtr->dwStyle & WS_CHILD)) {
980 printf("this is not a child window! What is it doing here?\n");
981 return 0;
983 #endif
984 #ifdef WINELIB
985 if (!(*wndenumprc, 2, lParam, (int) hwnd)) {
986 #else
987 if (!CallBack16(wndenumprc, 2, lParam, (int) hwnd)) {
988 #endif
989 return 0;
991 if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) {
992 return 0;
994 hwnd=wndPtr->hwndNext;
996 return 1;
999 /*******************************************************************
1000 * EnumChildWindows (USER.55)
1002 * o gets the first child of hwnd
1004 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1006 BOOL EnumChildWindows(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
1008 WND *wndPtr;
1010 #ifdef DEBUG_ENUM
1011 printf("EnumChildWindows\n");
1012 #endif
1014 if (hwnd == 0) return 0;
1015 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1016 hwnd = wndPtr->hwndChild;
1017 return WIN_EnumChildWin(hwnd, wndenumprc, lParam);
1020 /*******************************************************************
1021 * AnyPopup [USER.52]
1023 BOOL AnyPopup()
1025 printf("EMPTY STUB !! AnyPopup !\n");
1026 return FALSE;
1029 /*******************************************************************
1030 * FlashWindow [USER.105]
1032 BOOL FlashWindow(HWND hWnd, BOOL bInvert)
1034 printf("EMPTY STUB !! FlashWindow !\n");
1035 return FALSE;
1039 /*******************************************************************
1040 * SetSysModalWindow [USER.188]
1042 HWND SetSysModalWindow(HWND hWnd)
1044 HWND hWndOldModal = hWndSysModal;
1045 hWndSysModal = hWnd;
1046 printf("EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd);
1047 return hWndOldModal;
1051 /*******************************************************************
1052 * GetSysModalWindow [USER.189]
1054 HWND GetSysModalWindow(void)
1056 return hWndSysModal;