Release 941122
[wine/multimedia.git] / windows / win.c
blob142e2794a798f747e0270b30b2e92ac97760074b
1 /*
2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993, 1994";
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 "icon.h"
20 #include "cursor.h"
21 #include "stddebug.h"
22 #include "callback.h"
23 /* #define DEBUG_WIN /* */
24 /* #undef DEBUG_WIN /* */
25 /* #define DEBUG_MENU /* */
26 /* #undef DEBUG_MENU /* */
27 #include "debug.h"
29 extern Colormap COLOR_WinColormap;
31 extern void EVENT_RegisterWindow( Window w, HWND hwnd ); /* event.c */
32 extern void WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); /*winpos.c*/
33 extern LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect,
34 RECT *newWindowRect, RECT *oldWindowRect,
35 RECT *oldClientRect, WINDOWPOS *winpos,
36 RECT *newClientRect ); /* winpos.c */
38 extern HMENU CopySysMenu(); /* menu.c */
39 extern LONG MDIClientWndProc(HWND hwnd, WORD message,
40 WORD wParam, LONG lParam); /* mdi.c */
42 static HWND hwndDesktop = 0;
43 static HWND hWndSysModal = 0;
45 /***********************************************************************
46 * WIN_FindWndPtr
48 * Return a pointer to the WND structure corresponding to a HWND.
50 WND * WIN_FindWndPtr( HWND hwnd )
52 WND * ptr;
54 if (!hwnd) return NULL;
55 ptr = (WND *) USER_HEAP_ADDR( hwnd );
56 if (IsBadReadPtr(ptr, sizeof *ptr)) return NULL;
57 if (ptr->dwMagic != WND_MAGIC) return NULL;
58 return ptr;
62 /***********************************************************************
63 * WIN_GetXWindow
65 * Return the X window associated to a window.
67 Window WIN_GetXWindow( HWND hwnd )
69 WND *wndPtr = WIN_FindWndPtr( hwnd );
70 while (wndPtr && !wndPtr->window)
72 wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
74 return wndPtr ? wndPtr->window : 0;
78 /***********************************************************************
79 * WIN_UnlinkWindow
81 * Remove a window from the siblings linked list.
83 BOOL WIN_UnlinkWindow( HWND hwnd )
85 HWND * curWndPtr;
86 WND *parentPtr, *wndPtr;
88 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
89 if (!(parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ))) return FALSE;
91 curWndPtr = &parentPtr->hwndChild;
93 while (*curWndPtr != hwnd)
95 WND * curPtr = WIN_FindWndPtr( *curWndPtr );
96 curWndPtr = &curPtr->hwndNext;
98 *curWndPtr = wndPtr->hwndNext;
99 return TRUE;
103 /***********************************************************************
104 * WIN_LinkWindow
106 * Insert a window into the siblings linked list.
107 * The window is inserted after the specified window, which can also
108 * be specified as HWND_TOP or HWND_BOTTOM.
110 BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
112 HWND * hwndPtr = NULL; /* pointer to hwnd to change */
113 WND *wndPtr, *parentPtr;
115 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
116 if (!(parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ))) return FALSE;
118 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
120 hwndPtr = &parentPtr->hwndChild; /* Point to first sibling hwnd */
121 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
122 while (*hwndPtr)
124 WND * nextPtr = WIN_FindWndPtr( *hwndPtr );
125 hwndPtr = &nextPtr->hwndNext;
128 else /* Normal case */
130 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
131 if (afterPtr) hwndPtr = &afterPtr->hwndNext;
133 if (!hwndPtr) return FALSE;
134 wndPtr->hwndNext = *hwndPtr;
135 *hwndPtr = hwnd;
136 return TRUE;
140 /***********************************************************************
141 * WIN_FindWinToRepaint
143 * Find a window that needs repaint.
145 HWND WIN_FindWinToRepaint( HWND hwnd )
147 WND * wndPtr;
149 /* Note: the desktop window never gets WM_PAINT messages */
150 if (!hwnd) hwnd = GetTopWindow( hwndDesktop );
151 for ( ; hwnd != 0; hwnd = wndPtr->hwndNext )
153 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
154 if (!(wndPtr->dwStyle & WS_VISIBLE) || (wndPtr->flags & WIN_NO_REDRAW))
155 continue;
156 if ((wndPtr->dwStyle & WS_MINIMIZE) && (WIN_CLASS_INFO(wndPtr).hIcon))
157 continue;
158 if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT))
159 return hwnd;
160 if (wndPtr->hwndChild)
162 HWND child;
163 if ((child = WIN_FindWinToRepaint( wndPtr->hwndChild )))
164 return child;
167 return 0;
171 /***********************************************************************
172 * WIN_SendParentNotify
174 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
175 * the window has the WS_EX_NOPARENTNOTIFY style.
177 void WIN_SendParentNotify( HWND hwnd, WORD event, LONG lParam )
179 HWND current = GetParent( hwnd );
180 WND *wndPtr = WIN_FindWndPtr( hwnd );
182 if (!wndPtr || (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY)) return;
183 while (current)
185 SendMessage( current, WM_PARENTNOTIFY, event, lParam );
186 current = GetParent( current );
191 /***********************************************************************
192 * WIN_DestroyWindow
194 * Destroy storage associated to a window
196 static void WIN_DestroyWindow( HWND hwnd )
198 WND *wndPtr = WIN_FindWndPtr( hwnd );
199 CLASS *classPtr = CLASS_FindClassPtr( wndPtr->hClass );
201 if (!wndPtr || !classPtr) return;
202 WIN_UnlinkWindow( hwnd ); /* Remove the window from the linked list */
203 wndPtr->dwMagic = 0; /* Mark it as invalid */
204 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
206 if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
207 MSG_DecPaintCount( wndPtr->hmemTaskQ );
209 if (!(wndPtr->dwStyle & WS_CHILD))
211 if (wndPtr->wIDmenu) DestroyMenu( wndPtr->wIDmenu );
213 if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
214 if (wndPtr->window) XDestroyWindow( display, wndPtr->window );
215 if (classPtr->wc.style & CS_OWNDC) DCE_FreeDCE( wndPtr->hdce );
216 classPtr->cWindows--;
217 USER_HEAP_FREE( hwnd );
221 /***********************************************************************
222 * WIN_CreateDesktopWindow
224 * Create the desktop window.
226 BOOL WIN_CreateDesktopWindow()
228 WND *wndPtr;
229 HCLASS hclass;
230 CLASS *classPtr;
232 if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_NAME, 0, &classPtr )))
233 return FALSE;
235 hwndDesktop = USER_HEAP_ALLOC( GMEM_MOVEABLE,
236 sizeof(WND)+classPtr->wc.cbWndExtra );
237 if (!hwndDesktop) return FALSE;
238 wndPtr = (WND *) USER_HEAP_ADDR( hwndDesktop );
240 wndPtr->hwndNext = 0;
241 wndPtr->hwndChild = 0;
242 wndPtr->dwMagic = WND_MAGIC;
243 wndPtr->hwndParent = 0;
244 wndPtr->hwndOwner = 0;
245 wndPtr->hClass = hclass;
246 wndPtr->hInstance = 0;
247 wndPtr->rectWindow.left = 0;
248 wndPtr->rectWindow.top = 0;
249 wndPtr->rectWindow.right = SYSMETRICS_CXSCREEN;
250 wndPtr->rectWindow.bottom = SYSMETRICS_CYSCREEN;
251 wndPtr->rectClient = wndPtr->rectWindow;
252 wndPtr->rectNormal = wndPtr->rectWindow;
253 wndPtr->ptIconPos.x = -1;
254 wndPtr->ptIconPos.y = -1;
255 wndPtr->ptMaxPos.x = -1;
256 wndPtr->ptMaxPos.y = -1;
257 wndPtr->hmemTaskQ = 0; /* Desktop does not belong to a task */
258 wndPtr->hrgnUpdate = 0;
259 wndPtr->hwndLastActive = hwndDesktop;
260 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
261 wndPtr->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
262 wndPtr->dwExStyle = 0;
263 wndPtr->hdce = 0;
264 wndPtr->hVScroll = 0;
265 wndPtr->hHScroll = 0;
266 wndPtr->wIDmenu = 0;
267 wndPtr->hText = 0;
268 wndPtr->flags = 0;
269 wndPtr->window = rootWindow;
270 wndPtr->hSysMenu = 0;
271 wndPtr->hProp = 0;
272 wndPtr->hTask = 0;
274 /* Send dummy WM_NCCREATE message */
275 SendMessage( hwndDesktop, WM_NCCREATE, 0, 0 );
276 EVENT_RegisterWindow( wndPtr->window, hwndDesktop );
277 RedrawWindow( hwndDesktop, NULL, 0,
278 RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW );
279 return TRUE;
283 /***********************************************************************
284 * CreateWindow (USER.41)
286 HWND CreateWindow( LPSTR className, LPSTR windowName,
287 DWORD style, short x, short y, short width, short height,
288 HWND parent, HMENU menu, HANDLE instance, LPSTR data )
290 return CreateWindowEx( 0, className, windowName, style,
291 x, y, width, height, parent, menu, instance, data );
295 /***********************************************************************
296 * CreateWindowEx (USER.452)
298 HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
299 DWORD style, short x, short y, short width, short height,
300 HWND parent, HMENU menu, HANDLE instance, LPSTR data )
302 HANDLE class, hwnd;
303 CLASS *classPtr;
304 WND *wndPtr;
305 POINT maxSize, maxPos, minTrack, maxTrack;
306 CREATESTRUCT *createStruct;
307 HANDLE hcreateStruct;
308 int wmcreate;
309 XSetWindowAttributes win_attr;
311 dprintf_win(stddeb, "CreateWindowEx: %04X '%s' '%s' %04X %d,%d %dx%d %04X %04X %04X %08X\n",
312 exStyle, className, windowName, style, x, y, width, height,
313 parent, menu, instance, data);
314 /* 'soundrec.exe' has negative position !
315 Why ? For now, here a patch : */
316 if (!strcmp(className, "SoundRec"))
318 if (x < 0) x = 0;
319 if (y < 0) y = 0;
321 if (x == CW_USEDEFAULT) x = y = 0;
322 if (width == CW_USEDEFAULT)
324 width = 600;
325 height = 400;
327 if (width == 0) width = 1;
328 if (height == 0) height = 1;
330 /* Find the parent and class */
332 if (parent)
334 /* Make sure parent is valid */
335 if (!IsWindow( parent )) return 0;
337 else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */
339 if (!(class = CLASS_FindClassByName( className, instance, &classPtr ))) {
340 fprintf(stderr,"CreateWindow BAD CLASSNAME '%s' !\n", className);
341 return 0;
344 /* Correct the window style */
346 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
347 style |= WS_CAPTION | WS_CLIPSIBLINGS;
348 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
350 /* Create the window structure */
352 hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra);
353 if (!hwnd) return 0;
355 /* Fill the structure */
357 wndPtr = (WND *) USER_HEAP_ADDR( hwnd );
358 wndPtr->hwndNext = 0;
359 wndPtr->hwndChild = 0;
360 wndPtr->window = 0;
361 wndPtr->dwMagic = WND_MAGIC;
362 wndPtr->hwndParent = (style & WS_CHILD) ? parent : hwndDesktop;
363 wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : parent;
364 wndPtr->hClass = class;
365 wndPtr->hInstance = instance;
366 wndPtr->rectWindow.left = x;
367 wndPtr->rectWindow.top = y;
368 wndPtr->rectWindow.right = x + width;
369 wndPtr->rectWindow.bottom = y + height;
370 wndPtr->rectClient = wndPtr->rectWindow;
371 wndPtr->rectNormal = wndPtr->rectWindow;
372 wndPtr->ptIconPos.x = -1;
373 wndPtr->ptIconPos.y = -1;
374 wndPtr->ptMaxPos.x = -1;
375 wndPtr->ptMaxPos.y = -1;
376 wndPtr->hmemTaskQ = GetTaskQueue(0);
377 wndPtr->hrgnUpdate = 0;
378 wndPtr->hwndPrevActive = 0;
379 wndPtr->hwndLastActive = hwnd;
380 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
381 wndPtr->dwStyle = style;
382 wndPtr->dwExStyle = exStyle;
383 wndPtr->wIDmenu = 0;
384 wndPtr->hText = 0;
385 wndPtr->flags = 0;
386 wndPtr->hVScroll = 0;
387 wndPtr->hHScroll = 0;
388 wndPtr->hSysMenu = 0;
389 wndPtr->hProp = 0;
390 wndPtr->hTask = 0;
392 if (classPtr->wc.cbWndExtra)
393 memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
394 classPtr->cWindows++;
396 /* Make sure owner is a top-level window */
398 while (wndPtr->hwndOwner && GetParent(wndPtr->hwndOwner))
399 wndPtr->hwndOwner = GetParent(wndPtr->hwndOwner);
401 /* Get class or window DC if needed */
403 if (classPtr->wc.style & CS_OWNDC)
404 wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC );
405 else if (classPtr->wc.style & CS_CLASSDC)
406 wndPtr->hdce = classPtr->hdce;
407 else
408 wndPtr->hdce = 0;
410 /* Insert the window in the linked list */
412 WIN_LinkWindow( hwnd, HWND_TOP );
414 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
416 WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
418 if ( maxSize.x < width)
420 width = maxSize.x;
421 wndPtr->rectWindow.right = x + width;
423 if ( maxSize.y < height)
425 height = maxSize.y;
426 wndPtr->rectWindow.bottom = y + height;
429 /* Create the X window (only for top-level windows, and then only */
430 /* when there's no desktop window) */
432 if (!(style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
434 CURSORALLOC *cursor;
435 HCURSOR hCursor = classPtr->wc.hCursor;
436 if (!hCursor) hCursor = LoadCursor( 0, IDC_ARROW );
437 cursor = (CURSORALLOC *) GlobalLock(hCursor);
439 win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
440 PointerMotionMask | ButtonPressMask |
441 ButtonReleaseMask | FocusChangeMask;
442 win_attr.override_redirect = TRUE;
443 win_attr.colormap = COLOR_WinColormap;
444 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
445 win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0);
446 win_attr.cursor = cursor ? cursor->xcursor : None;
447 wndPtr->window = XCreateWindow( display, rootWindow, x, y,
448 width, height, 0, CopyFromParent,
449 InputOutput, CopyFromParent,
450 CWEventMask | CWOverrideRedirect |
451 CWColormap | CWCursor | CWSaveUnder |
452 CWBackingStore, &win_attr );
453 XStoreName( display, wndPtr->window, windowName );
454 EVENT_RegisterWindow( wndPtr->window, hwnd );
455 GlobalUnlock( hCursor );
458 dprintf_menu(stddeb,"CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n",
459 menu, instance, classPtr->wc.lpszMenuName);
461 if ((style & WS_CAPTION) && (style & WS_CHILD) == 0) {
462 if (menu != 0)
463 SetMenu(hwnd, menu);
464 else {
465 if (classPtr->wc.lpszMenuName != NULL)
466 SetMenu(hwnd, LoadMenu(instance, classPtr->wc.lpszMenuName));
469 else
470 wndPtr->wIDmenu = menu;
472 /* Send the WM_CREATE message */
474 hcreateStruct = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CREATESTRUCT) );
475 createStruct = (CREATESTRUCT *) USER_HEAP_ADDR( hcreateStruct );
476 createStruct->lpCreateParams = data;
477 createStruct->hInstance = instance;
478 createStruct->hMenu = menu;
479 createStruct->hwndParent = parent;
480 createStruct->cx = width;
481 createStruct->cy = height;
482 createStruct->x = x;
483 createStruct->y = y;
484 createStruct->style = style;
485 createStruct->lpszName = windowName;
486 createStruct->lpszClass = className;
487 createStruct->dwExStyle = 0;
489 wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LONG)createStruct );
490 if (!wmcreate) wmcreate = -1;
491 else
493 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
494 NULL, NULL, NULL, &wndPtr->rectClient );
495 wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct );
498 USER_HEAP_FREE( hcreateStruct );
500 if (wmcreate == -1)
502 /* Abort window creation */
503 WIN_DestroyWindow( hwnd );
504 return 0;
507 /* Create a copy of SysMenu */
508 if (style & WS_SYSMENU) wndPtr->hSysMenu = CopySysMenu();
510 /* Register window in current task windows list */
511 AddWindowToTask(GetCurrentTask(), hwnd);
513 WIN_SendParentNotify( hwnd, WM_CREATE, MAKELONG( hwnd, wndPtr->wIDmenu ) );
515 if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
516 /* if (style & WS_MINIMIZE) ShowWindow( hwnd, SW_MINIMIZE ); */
518 dprintf_win(stddeb, "CreateWindowEx: return %04X \n", hwnd);
519 return hwnd;
523 /***********************************************************************
524 * DestroyWindow (USER.53)
526 BOOL DestroyWindow( HWND hwnd )
528 WND * wndPtr;
529 CLASS * classPtr;
531 dprintf_win(stddeb, "DestroyWindow (%04x)\n", hwnd);
533 /* Initialisation */
535 if (hwnd == hwndDesktop) return FALSE; /* Can't destroy desktop */
536 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
537 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return FALSE;
539 /* Hide the window */
541 if (wndPtr->dwStyle & WS_VISIBLE)
542 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE |
543 SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
544 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
545 ReleaseCapture();
546 WIN_SendParentNotify( hwnd, WM_DESTROY, MAKELONG(hwnd, wndPtr->wIDmenu) );
548 /* Send destroy messages and destroy children */
550 SendMessage( hwnd, WM_DESTROY, 0, 0 );
551 while (wndPtr->hwndChild) /* The child removes itself from the list */
552 DestroyWindow( wndPtr->hwndChild );
553 SendMessage( hwnd, WM_NCDESTROY, 0, 0 );
555 /* Remove the window from current task windows list */
556 RemoveWindowFromTask(GetCurrentTask(), hwnd);
558 /* Destroy the window */
560 WIN_DestroyWindow( hwnd );
561 return TRUE;
565 /***********************************************************************
566 * CloseWindow (USER.43)
568 void CloseWindow(HWND hWnd)
570 WND * wndPtr = WIN_FindWndPtr(hWnd);
571 if (wndPtr->dwStyle & WS_CHILD) return;
572 ShowWindow(hWnd, SW_MINIMIZE);
577 /***********************************************************************
578 * OpenIcon (USER.44)
580 BOOL OpenIcon(HWND hWnd)
582 if (!IsIconic(hWnd)) return FALSE;
583 ShowWindow(hWnd, SW_SHOWNORMAL);
584 return(TRUE);
589 /***********************************************************************
590 * FindWindow (USER.50)
592 HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch)
594 HCLASS hclass;
595 CLASS *classPtr;
596 HWND hwnd;
598 if (ClassMatch)
600 hclass = CLASS_FindClassByName( ClassMatch, 0xffff, &classPtr );
601 if (!hclass) return 0;
603 else hclass = 0;
605 hwnd = GetTopWindow( hwndDesktop );
606 while(hwnd)
608 WND *wndPtr = WIN_FindWndPtr( hwnd );
609 if (!hclass || (wndPtr->hClass == hclass))
611 /* Found matching class */
612 if (!TitleMatch) return hwnd;
613 if (wndPtr->hText)
615 char *textPtr = (char *) USER_HEAP_ADDR( wndPtr->hText );
616 if (!strcmp( textPtr, TitleMatch )) return hwnd;
619 hwnd = wndPtr->hwndNext;
621 return 0;
625 /**********************************************************************
626 * GetDesktopWindow (USER.286)
627 * GetDeskTopHwnd (USER.278)
629 HWND GetDesktopWindow(void)
631 return hwndDesktop;
635 /*******************************************************************
636 * EnableWindow (USER.34)
638 BOOL EnableWindow( HWND hwnd, BOOL enable )
640 WND *wndPtr;
642 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
643 if (enable && (wndPtr->dwStyle & WS_DISABLED))
645 /* Enable window */
646 wndPtr->dwStyle &= ~WS_DISABLED;
647 SendMessage( hwnd, WM_ENABLE, TRUE, 0 );
648 return TRUE;
650 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
652 /* Disable window */
653 wndPtr->dwStyle |= WS_DISABLED;
654 if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
655 SetFocus( 0 ); /* A disabled window can't have the focus */
656 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
657 ReleaseCapture(); /* A disabled window can't capture the mouse */
658 SendMessage( hwnd, WM_ENABLE, FALSE, 0 );
659 return FALSE;
661 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
665 /***********************************************************************
666 * IsWindowEnabled (USER.35)
668 BOOL IsWindowEnabled(HWND hWnd)
670 WND * wndPtr;
672 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
673 return !(wndPtr->dwStyle & WS_DISABLED);
677 /**********************************************************************
678 * GetWindowWord (USER.133)
680 WORD GetWindowWord( HWND hwnd, short offset )
682 WND * wndPtr = WIN_FindWndPtr( hwnd );
683 if (!wndPtr) return 0;
684 if (offset >= 0) return *(WORD *)(((char *)wndPtr->wExtra) + offset);
685 switch(offset)
687 case GWW_ID: return wndPtr->wIDmenu;
688 case GWW_HWNDPARENT: return wndPtr->hwndParent;
689 case GWW_HINSTANCE: return wndPtr->hInstance;
691 return 0;
695 /**********************************************************************
696 * SetWindowWord (USER.134)
698 WORD SetWindowWord( HWND hwnd, short offset, WORD newval )
700 WORD *ptr, retval;
701 WND * wndPtr = WIN_FindWndPtr( hwnd );
702 if (!wndPtr) return 0;
703 if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
704 else switch(offset)
706 case GWW_ID: ptr = &wndPtr->wIDmenu;
707 case GWW_HINSTANCE: ptr = &wndPtr->hInstance;
708 default: return 0;
710 retval = *ptr;
711 *ptr = newval;
712 return retval;
716 /**********************************************************************
717 * GetWindowLong (USER.135)
719 LONG GetWindowLong( HWND hwnd, short offset )
721 WND * wndPtr = WIN_FindWndPtr( hwnd );
722 if (!wndPtr) return 0;
723 if (offset >= 0) return *(LONG *)(((char *)wndPtr->wExtra) + offset);
724 switch(offset)
726 case GWL_STYLE: return wndPtr->dwStyle;
727 case GWL_EXSTYLE: return wndPtr->dwExStyle;
728 case GWL_WNDPROC:
729 if (!IS_16_BIT_ADDRESS(wndPtr->lpfnWndProc))
731 /* The window procedure is part of Wine.
732 Unfortunately, MS-Windows programs can't access these
733 adresses.
734 FIXME: There should be a jump table somewhere in if1632
736 long x=Stack16Frame[11]<<16 | 0x0010;
737 /* Just to make Borland's OWL happy */
738 return x;
740 else return (LONG)wndPtr->lpfnWndProc;
742 return 0;
746 /**********************************************************************
747 * SetWindowLong (USER.136)
749 LONG SetWindowLong( HWND hwnd, short offset, LONG newval )
751 LONG *ptr, retval;
752 WND * wndPtr = WIN_FindWndPtr( hwnd );
753 if (!wndPtr) return 0;
754 if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
755 else switch(offset)
757 case GWL_STYLE: ptr = &wndPtr->dwStyle;
758 break;
759 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle;
760 break;
761 case GWL_WNDPROC: ptr = (LONG *)(&wndPtr->lpfnWndProc);
762 break;
763 default: return 0;
765 retval = *ptr;
766 *ptr = newval;
767 return retval;
771 /*******************************************************************
772 * GetWindowText (USER.36)
774 int GetWindowText(HWND hwnd, LPSTR lpString, int nMaxCount)
776 return (int)SendMessage(hwnd, WM_GETTEXT, (WORD)nMaxCount,
777 (DWORD)lpString);
780 /*******************************************************************
781 * SetWindowText (USER.37)
783 void SetWindowText(HWND hwnd, LPSTR lpString)
785 SendMessage(hwnd, WM_SETTEXT, (WORD)NULL, (DWORD)lpString);
788 /*******************************************************************
789 * GetWindowTextLength (USER.38)
791 int GetWindowTextLength(HWND hwnd)
793 return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, (WORD)NULL,
794 (DWORD)NULL);
798 /*******************************************************************
799 * IsWindow (USER.47)
801 BOOL IsWindow( HWND hwnd )
803 WND * wndPtr = WIN_FindWndPtr( hwnd );
804 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
808 /*****************************************************************
809 * GetParent (USER.46)
811 HWND GetParent(HWND hwnd)
813 WND *wndPtr = WIN_FindWndPtr(hwnd);
814 if (!wndPtr || !(wndPtr->dwStyle & WS_CHILD)) return 0;
815 return wndPtr->hwndParent;
818 /*****************************************************************
819 * SetParent (USER.233)
821 HWND SetParent(HWND hwndChild, HWND hwndNewParent)
823 HWND temp;
825 WND *wndPtr = WIN_FindWndPtr(hwndChild);
826 if (!wndPtr || !(wndPtr->dwStyle & WS_CHILD)) return 0;
828 temp = wndPtr->hwndParent;
830 if (hwndNewParent)
831 wndPtr->hwndParent = hwndNewParent;
832 else
833 wndPtr->hwndParent = GetDesktopWindow();
835 return temp;
840 /*******************************************************************
841 * IsChild (USER.48)
843 BOOL IsChild( HWND parent, HWND child )
845 WND * wndPtr = WIN_FindWndPtr( child );
846 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
848 if (wndPtr->hwndParent == parent) return TRUE;
849 wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
851 return FALSE;
855 /***********************************************************************
856 * IsWindowVisible (USER.49)
858 BOOL IsWindowVisible(HWND hWnd)
860 WND * wndPtr = WIN_FindWndPtr(hWnd);
861 if (wndPtr == 0) return(FALSE);
862 else return ((wndPtr->dwStyle & WS_VISIBLE) != 0);
867 /*******************************************************************
868 * GetTopWindow (USER.229)
870 HWND GetTopWindow( HWND hwnd )
872 WND * wndPtr = WIN_FindWndPtr( hwnd );
873 if (wndPtr) return wndPtr->hwndChild;
874 else return 0;
878 /*******************************************************************
879 * GetWindow (USER.262)
881 HWND GetWindow( HWND hwnd, WORD rel )
883 WND * wndPtr = WIN_FindWndPtr( hwnd );
884 if (!wndPtr) return 0;
885 switch(rel)
887 case GW_HWNDFIRST:
888 if (wndPtr->hwndParent)
890 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
891 return parentPtr->hwndChild;
893 else return 0;
895 case GW_HWNDLAST:
896 if (!wndPtr->hwndParent) return 0; /* Desktop window */
897 while (wndPtr->hwndNext)
899 hwnd = wndPtr->hwndNext;
900 wndPtr = WIN_FindWndPtr( hwnd );
902 return hwnd;
904 case GW_HWNDNEXT:
905 return wndPtr->hwndNext;
907 case GW_HWNDPREV:
909 HWND hwndPrev;
911 if (wndPtr->hwndParent)
913 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
914 hwndPrev = parentPtr->hwndChild;
916 else return 0; /* Desktop window */
917 if (hwndPrev == hwnd) return 0;
918 while (hwndPrev)
920 wndPtr = WIN_FindWndPtr( hwndPrev );
921 if (wndPtr->hwndNext == hwnd) break;
922 hwndPrev = wndPtr->hwndNext;
924 return hwndPrev;
927 case GW_OWNER:
928 return wndPtr->hwndOwner;
930 case GW_CHILD:
931 return wndPtr->hwndChild;
933 return 0;
937 /*******************************************************************
938 * GetNextWindow (USER.230)
940 HWND GetNextWindow( HWND hwnd, WORD flag )
942 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
943 return GetWindow( hwnd, flag );
948 /*******************************************************************
949 * GetLastActivePopup (USER.287)
951 HWND GetLastActivePopup(HWND hwnd)
953 WND *wndPtr;
954 wndPtr = WIN_FindWndPtr(hwnd);
955 if (wndPtr == NULL) return hwnd;
956 return wndPtr->hwndLastActive;
960 /*******************************************************************
961 * EnumWindows (USER.54)
963 * o gets the desktop window and iterates over all the windows
964 * which are direct decendents of the desktop * by iterating over
965 * the desktop's child window and all the child windows next
966 * pointers
968 * o call wndenumprc for every child window the desktop has
969 * (parameters to Callback16 passed backwards so they are
970 * put in in pascal calling order)
972 * o if wndenumprc returns 0 exit
975 BOOL EnumWindows(FARPROC wndenumprc, LPARAM lParam)
977 HWND hwnd = GetTopWindow( GetDesktopWindow() );
978 WND *wndPtr;
979 int result;
981 dprintf_enum(stddeb,"EnumWindows\n");
983 while (hwnd) {
984 char *ptr;
986 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
987 return 0;
989 #ifdef WINELIB
990 (*wndenumprc)(hwnd, lParam);
991 #else
992 result = CallBack16(wndenumprc, 2,
993 CALLBACK_SIZE_WORD, (int) hwnd,
994 CALLBACK_SIZE_LONG, lParam);
995 #endif
996 if ( ! result ) {
997 return 0;
999 hwnd=wndPtr->hwndNext;
1001 return 1; /* for now */
1004 /*******************************************************************
1005 * WIN_EnumChildWin
1007 * o hwnd is the first child to use, loop until all next windows
1008 * are processed
1010 * o call wdnenumprc with parameters in inverse order (pascal)
1012 * o call ourselves with the next child window
1015 static BOOL WIN_EnumChildWin(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
1017 WND *wndPtr;
1018 int result;
1021 while (hwnd) {
1022 char *ptr;
1023 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
1024 return 0;
1026 #ifdef WINELIB
1027 if (!(*wndenumprc)( 2, lParam, (int) hwnd)) {
1028 #else
1029 if (!CallBack16(wndenumprc, 2,
1030 CALLBACK_SIZE_WORD, (int) hwnd,
1031 CALLBACK_SIZE_LONG, lParam)) {
1032 #endif
1033 return 0;
1035 if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) {
1036 return 0;
1038 hwnd=wndPtr->hwndNext;
1040 return 1;
1043 /*******************************************************************
1044 * EnumChildWindows (USER.55)
1046 * o gets the first child of hwnd
1048 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1050 BOOL EnumChildWindows(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
1052 WND *wndPtr;
1054 dprintf_enum(stddeb,"EnumChildWindows\n");
1056 if (hwnd == 0) return 0;
1057 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1058 hwnd = wndPtr->hwndChild;
1059 return WIN_EnumChildWin(hwnd, wndenumprc, lParam);
1062 /*******************************************************************
1063 * AnyPopup [USER.52]
1065 BOOL AnyPopup()
1067 dprintf_win(stdnimp,"EMPTY STUB !! AnyPopup !\n");
1068 return FALSE;
1071 /*******************************************************************
1072 * FlashWindow [USER.105]
1074 BOOL FlashWindow(HWND hWnd, BOOL bInvert)
1076 dprintf_win(stdnimp,"EMPTY STUB !! FlashWindow !\n");
1077 return FALSE;
1081 /*******************************************************************
1082 * SetSysModalWindow [USER.188]
1084 HWND SetSysModalWindow(HWND hWnd)
1086 HWND hWndOldModal = hWndSysModal;
1087 hWndSysModal = hWnd;
1088 dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd);
1089 return hWndOldModal;
1093 /*******************************************************************
1094 * GetSysModalWindow [USER.189]
1096 HWND GetSysModalWindow(void)
1098 return hWndSysModal;