Release 950216
[wine.git] / windows / win.c
blob3d9e49a5bf618a1a9888455ce8795bf4be70592b
1 /*
2 * Window related functions
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <string.h>
10 #include "options.h"
11 #include "class.h"
12 #include "win.h"
13 #include "user.h"
14 #include "dce.h"
15 #include "sysmetrics.h"
16 #include "menu.h"
17 #include "icon.h"
18 #include "cursor.h"
19 #include "event.h"
20 #include "message.h"
21 #include "winpos.h"
22 #include "color.h"
23 #include "stddebug.h"
24 #include "callback.h"
25 /* #define DEBUG_WIN */
26 /* #define DEBUG_MENU */
27 #include "debug.h"
29 static HWND hwndDesktop = 0;
30 static HWND hWndSysModal = 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 (IsBadReadPtr(ptr, sizeof *ptr)) return NULL;
44 if (ptr->dwMagic != WND_MAGIC) return NULL;
45 return ptr;
49 /***********************************************************************
50 * WIN_GetXWindow
52 * Return the X window associated to a window.
54 Window WIN_GetXWindow( HWND hwnd )
56 WND *wndPtr = WIN_FindWndPtr( hwnd );
57 while (wndPtr && !wndPtr->window)
59 wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
61 return wndPtr ? wndPtr->window : 0;
65 /***********************************************************************
66 * WIN_UnlinkWindow
68 * Remove a window from the siblings linked list.
70 BOOL WIN_UnlinkWindow( HWND hwnd )
72 HWND * curWndPtr;
73 WND *parentPtr, *wndPtr;
75 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
76 if (!(parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ))) return FALSE;
78 curWndPtr = &parentPtr->hwndChild;
80 while (*curWndPtr != hwnd)
82 WND * curPtr = WIN_FindWndPtr( *curWndPtr );
83 curWndPtr = &curPtr->hwndNext;
85 *curWndPtr = wndPtr->hwndNext;
86 return TRUE;
90 /***********************************************************************
91 * WIN_LinkWindow
93 * Insert a window into the siblings linked list.
94 * The window is inserted after the specified window, which can also
95 * be specified as HWND_TOP or HWND_BOTTOM.
97 BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
99 HWND * hwndPtr = NULL; /* pointer to hwnd to change */
100 WND *wndPtr, *parentPtr;
102 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
103 if (!(parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ))) return FALSE;
105 if ((hwndInsertAfter == HWND_TOP) || (hwndInsertAfter == HWND_BOTTOM))
107 hwndPtr = &parentPtr->hwndChild; /* Point to first sibling hwnd */
108 if (hwndInsertAfter == HWND_BOTTOM) /* Find last sibling hwnd */
109 while (*hwndPtr)
111 WND * nextPtr = WIN_FindWndPtr( *hwndPtr );
112 hwndPtr = &nextPtr->hwndNext;
115 else /* Normal case */
117 WND * afterPtr = WIN_FindWndPtr( hwndInsertAfter );
118 if (afterPtr) hwndPtr = &afterPtr->hwndNext;
120 if (!hwndPtr) return FALSE;
121 wndPtr->hwndNext = *hwndPtr;
122 *hwndPtr = hwnd;
123 return TRUE;
127 /***********************************************************************
128 * WIN_FindWinToRepaint
130 * Find a window that needs repaint.
132 HWND WIN_FindWinToRepaint( HWND hwnd )
134 WND * wndPtr;
136 /* Note: the desktop window never gets WM_PAINT messages */
137 if (!hwnd) hwnd = GetTopWindow( hwndDesktop );
138 for ( ; hwnd != 0; hwnd = wndPtr->hwndNext )
140 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
141 if (!(wndPtr->dwStyle & WS_VISIBLE) || (wndPtr->flags & WIN_NO_REDRAW))
142 continue;
143 if ((wndPtr->dwStyle & WS_MINIMIZE) && (WIN_CLASS_INFO(wndPtr).hIcon))
144 continue;
145 if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT))
146 return hwnd;
147 if (wndPtr->hwndChild)
149 HWND child;
150 if ((child = WIN_FindWinToRepaint( wndPtr->hwndChild )))
151 return child;
154 return 0;
158 /***********************************************************************
159 * WIN_SendParentNotify
161 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
162 * the window has the WS_EX_NOPARENTNOTIFY style.
164 void WIN_SendParentNotify( HWND hwnd, WORD event, LONG lParam )
166 HWND current = GetParent( hwnd );
167 WND *wndPtr = WIN_FindWndPtr( hwnd );
169 if (!wndPtr || (wndPtr->dwExStyle & WS_EX_NOPARENTNOTIFY)) return;
170 while (current)
172 SendMessage( current, WM_PARENTNOTIFY, event, lParam );
173 current = GetParent( current );
178 /***********************************************************************
179 * WIN_DestroyWindow
181 * Destroy storage associated to a window
183 static void WIN_DestroyWindow( HWND hwnd )
185 WND *wndPtr = WIN_FindWndPtr( hwnd );
186 CLASS *classPtr = CLASS_FindClassPtr( wndPtr->hClass );
188 if (!wndPtr || !classPtr) return;
189 WIN_UnlinkWindow( hwnd ); /* Remove the window from the linked list */
190 wndPtr->dwMagic = 0; /* Mark it as invalid */
191 if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
193 if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
194 MSG_DecPaintCount( wndPtr->hmemTaskQ );
196 if (!(wndPtr->dwStyle & WS_CHILD))
198 if (wndPtr->wIDmenu) DestroyMenu( wndPtr->wIDmenu );
200 if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
201 if (wndPtr->window) XDestroyWindow( display, wndPtr->window );
202 if (classPtr->wc.style & CS_OWNDC) DCE_FreeDCE( wndPtr->hdce );
203 classPtr->cWindows--;
204 USER_HEAP_FREE( hwnd );
208 /***********************************************************************
209 * WIN_CreateDesktopWindow
211 * Create the desktop window.
213 BOOL WIN_CreateDesktopWindow()
215 WND *wndPtr;
216 HCLASS hclass;
217 CLASS *classPtr;
219 if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_NAME, 0, &classPtr )))
220 return FALSE;
222 hwndDesktop = USER_HEAP_ALLOC( GMEM_MOVEABLE,
223 sizeof(WND)+classPtr->wc.cbWndExtra );
224 if (!hwndDesktop) return FALSE;
225 wndPtr = (WND *) USER_HEAP_ADDR( hwndDesktop );
227 wndPtr->hwndNext = 0;
228 wndPtr->hwndChild = 0;
229 wndPtr->dwMagic = WND_MAGIC;
230 wndPtr->hwndParent = 0;
231 wndPtr->hwndOwner = 0;
232 wndPtr->hClass = hclass;
233 wndPtr->hInstance = 0;
234 wndPtr->rectWindow.left = 0;
235 wndPtr->rectWindow.top = 0;
236 wndPtr->rectWindow.right = SYSMETRICS_CXSCREEN;
237 wndPtr->rectWindow.bottom = SYSMETRICS_CYSCREEN;
238 wndPtr->rectClient = wndPtr->rectWindow;
239 wndPtr->rectNormal = wndPtr->rectWindow;
240 wndPtr->ptIconPos.x = -1;
241 wndPtr->ptIconPos.y = -1;
242 wndPtr->ptMaxPos.x = -1;
243 wndPtr->ptMaxPos.y = -1;
244 wndPtr->hmemTaskQ = 0; /* Desktop does not belong to a task */
245 wndPtr->hrgnUpdate = 0;
246 wndPtr->hwndLastActive = hwndDesktop;
247 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
248 wndPtr->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
249 wndPtr->dwExStyle = 0;
250 wndPtr->hdce = 0;
251 wndPtr->hVScroll = 0;
252 wndPtr->hHScroll = 0;
253 wndPtr->wIDmenu = 0;
254 wndPtr->hText = 0;
255 wndPtr->flags = 0;
256 wndPtr->window = rootWindow;
257 wndPtr->hSysMenu = 0;
258 wndPtr->hProp = 0;
259 wndPtr->hTask = 0;
261 /* Send dummy WM_NCCREATE message */
262 SendMessage( hwndDesktop, WM_NCCREATE, 0, 0 );
263 EVENT_RegisterWindow( wndPtr->window, hwndDesktop );
264 RedrawWindow( hwndDesktop, NULL, 0,
265 RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW );
266 return TRUE;
270 /***********************************************************************
271 * CreateWindow (USER.41)
273 HWND CreateWindow( LPSTR className, LPSTR windowName,
274 DWORD style, short x, short y, short width, short height,
275 HWND parent, HMENU menu, HANDLE instance, LPSTR data )
277 return CreateWindowEx( 0, className, windowName, style,
278 x, y, width, height, parent, menu, instance, data );
282 /***********************************************************************
283 * CreateWindowEx (USER.452)
285 HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
286 DWORD style, short x, short y, short width, short height,
287 HWND parent, HMENU menu, HANDLE instance, LPSTR data )
289 HANDLE class, hwnd;
290 CLASS *classPtr;
291 WND *wndPtr;
292 POINT maxSize, maxPos, minTrack, maxTrack;
293 CREATESTRUCT *createStruct;
294 HANDLE hcreateStruct;
295 int wmcreate;
296 XSetWindowAttributes win_attr;
298 dprintf_win(stddeb, "CreateWindowEx: %08lX '%s' '%s' %08lX %d,%d %dx%d %04X %04X %04X %p\n",
299 exStyle, className, windowName, style, x, y, width, height,
300 parent, menu, instance, data);
301 /* 'soundrec.exe' has negative position !
302 Why ? For now, here a patch : */
303 if (!strcmp(className, "SoundRec"))
305 if (x < 0) x = 0;
306 if (y < 0) y = 0;
308 if (x == CW_USEDEFAULT) x = y = 0;
309 if (width == CW_USEDEFAULT)
311 width = 600;
312 height = 400;
314 if (width == 0) width = 1;
315 if (height == 0) height = 1;
317 /* Find the parent and class */
319 if (parent)
321 /* Make sure parent is valid */
322 if (!IsWindow( parent )) return 0;
324 else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */
326 if (!(class = CLASS_FindClassByName( className, instance, &classPtr ))) {
327 fprintf(stderr,"CreateWindow BAD CLASSNAME '%s' !\n", className);
328 return 0;
331 /* Correct the window style */
333 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
334 style |= WS_CAPTION | WS_CLIPSIBLINGS;
335 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
337 /* Create the window structure */
339 hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra);
340 if (!hwnd) return 0;
342 /* Fill the structure */
344 wndPtr = (WND *) USER_HEAP_ADDR( hwnd );
345 wndPtr->hwndNext = 0;
346 wndPtr->hwndChild = 0;
347 wndPtr->window = 0;
348 wndPtr->dwMagic = WND_MAGIC;
349 wndPtr->hwndParent = (style & WS_CHILD) ? parent : hwndDesktop;
350 wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : parent;
351 wndPtr->hClass = class;
352 wndPtr->hInstance = instance;
353 wndPtr->rectWindow.left = x;
354 wndPtr->rectWindow.top = y;
355 wndPtr->rectWindow.right = x + width;
356 wndPtr->rectWindow.bottom = y + height;
357 wndPtr->rectClient = wndPtr->rectWindow;
358 wndPtr->rectNormal = wndPtr->rectWindow;
359 wndPtr->ptIconPos.x = -1;
360 wndPtr->ptIconPos.y = -1;
361 wndPtr->ptMaxPos.x = -1;
362 wndPtr->ptMaxPos.y = -1;
363 wndPtr->hmemTaskQ = GetTaskQueue(0);
364 wndPtr->hrgnUpdate = 0;
365 wndPtr->hwndPrevActive = 0;
366 wndPtr->hwndLastActive = hwnd;
367 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
368 wndPtr->dwStyle = style;
369 wndPtr->dwExStyle = exStyle;
370 wndPtr->wIDmenu = 0;
371 wndPtr->hText = 0;
372 wndPtr->flags = 0;
373 wndPtr->hVScroll = 0;
374 wndPtr->hHScroll = 0;
375 wndPtr->hSysMenu = 0;
376 wndPtr->hProp = 0;
377 wndPtr->hTask = 0;
379 if (classPtr->wc.cbWndExtra)
380 memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
381 classPtr->cWindows++;
383 /* Make sure owner is a top-level window */
385 while (wndPtr->hwndOwner && GetParent(wndPtr->hwndOwner))
386 wndPtr->hwndOwner = GetParent(wndPtr->hwndOwner);
388 /* Get class or window DC if needed */
390 if (classPtr->wc.style & CS_OWNDC)
391 wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC );
392 else if (classPtr->wc.style & CS_CLASSDC)
393 wndPtr->hdce = classPtr->hdce;
394 else
395 wndPtr->hdce = 0;
397 /* Insert the window in the linked list */
399 WIN_LinkWindow( hwnd, HWND_TOP );
401 /* Send the WM_GETMINMAXINFO message and fix the size if needed */
403 NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
405 if ( maxSize.x < width)
407 width = maxSize.x;
408 wndPtr->rectWindow.right = x + width;
410 if ( maxSize.y < height)
412 height = maxSize.y;
413 wndPtr->rectWindow.bottom = y + height;
416 /* Create the X window (only for top-level windows, and then only */
417 /* when there's no desktop window) */
419 if (!(style & WS_CHILD) && (rootWindow == DefaultRootWindow(display)))
421 CURSORALLOC *cursor;
422 HCURSOR hCursor = classPtr->wc.hCursor;
423 if (!hCursor) hCursor = LoadCursor( 0, IDC_ARROW );
424 cursor = (CURSORALLOC *) GlobalLock(hCursor);
426 win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
427 PointerMotionMask | ButtonPressMask |
428 ButtonReleaseMask | FocusChangeMask;
429 win_attr.override_redirect = TRUE;
430 win_attr.colormap = COLOR_WinColormap;
431 win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
432 win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0);
433 win_attr.cursor = cursor ? cursor->xcursor : None;
434 wndPtr->window = XCreateWindow( display, rootWindow, x, y,
435 width, height, 0, CopyFromParent,
436 InputOutput, CopyFromParent,
437 CWEventMask | CWOverrideRedirect |
438 CWColormap | CWCursor | CWSaveUnder |
439 CWBackingStore, &win_attr );
440 XStoreName( display, wndPtr->window, windowName );
441 EVENT_RegisterWindow( wndPtr->window, hwnd );
442 GlobalUnlock( hCursor );
445 dprintf_menu(stddeb,"CreateWindowEx // menu=%04X instance=%04X classmenu=%p !\n",
446 menu, instance, classPtr->wc.lpszMenuName);
448 if ((style & WS_CAPTION) && (style & WS_CHILD) == 0) {
449 if (menu != 0)
450 SetMenu(hwnd, menu);
451 else {
452 if (classPtr->wc.lpszMenuName != NULL)
453 SetMenu(hwnd, LoadMenu(instance, classPtr->wc.lpszMenuName));
456 else
457 wndPtr->wIDmenu = menu;
459 /* Send the WM_CREATE message */
461 hcreateStruct = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CREATESTRUCT) );
462 createStruct = (CREATESTRUCT *) USER_HEAP_ADDR( hcreateStruct );
463 createStruct->lpCreateParams = data;
464 createStruct->hInstance = instance;
465 createStruct->hMenu = menu;
466 createStruct->hwndParent = parent;
467 createStruct->cx = width;
468 createStruct->cy = height;
469 createStruct->x = x;
470 createStruct->y = y;
471 createStruct->style = style;
472 createStruct->lpszName = windowName;
473 createStruct->lpszClass = className;
474 createStruct->dwExStyle = 0;
476 wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LONG)createStruct );
477 if (!wmcreate) wmcreate = -1;
478 else
480 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
481 NULL, NULL, NULL, &wndPtr->rectClient );
482 wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct );
485 USER_HEAP_FREE( hcreateStruct );
487 if (wmcreate == -1)
489 /* Abort window creation */
490 WIN_DestroyWindow( hwnd );
491 return 0;
494 /* Create a copy of SysMenu */
495 if (style & WS_SYSMENU) wndPtr->hSysMenu = CopySysMenu();
497 /* Register window in current task windows list */
498 AddWindowToTask(GetCurrentTask(), hwnd);
500 WIN_SendParentNotify( hwnd, WM_CREATE, MAKELONG( hwnd, wndPtr->wIDmenu ) );
502 if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
503 /* if (style & WS_MINIMIZE) ShowWindow( hwnd, SW_MINIMIZE ); */
505 dprintf_win(stddeb, "CreateWindowEx: return %04X \n", hwnd);
506 return hwnd;
510 /***********************************************************************
511 * DestroyWindow (USER.53)
513 BOOL DestroyWindow( HWND hwnd )
515 WND * wndPtr;
516 CLASS * classPtr;
518 dprintf_win(stddeb, "DestroyWindow (%04x)\n", hwnd);
520 /* Initialisation */
522 if (hwnd == hwndDesktop) return FALSE; /* Can't destroy desktop */
523 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
524 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return FALSE;
526 /* Hide the window */
528 if (wndPtr->dwStyle & WS_VISIBLE)
529 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE |
530 SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
531 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
532 ReleaseCapture();
533 WIN_SendParentNotify( hwnd, WM_DESTROY, MAKELONG(hwnd, wndPtr->wIDmenu) );
535 /* Recursively destroy owned windows */
537 for (;;)
539 HWND hwndSibling = GetWindow( hwnd, GW_HWNDFIRST );
540 while (hwndSibling)
542 WND *siblingPtr = WIN_FindWndPtr( hwndSibling );
543 if (siblingPtr->hwndOwner == hwnd) break;
544 hwndSibling = siblingPtr->hwndNext;
546 if (hwndSibling) DestroyWindow( hwndSibling );
547 else break;
550 /* Send destroy messages and destroy children */
552 SendMessage( hwnd, WM_DESTROY, 0, 0 );
553 while (wndPtr->hwndChild) /* The child removes itself from the list */
554 DestroyWindow( wndPtr->hwndChild );
555 SendMessage( hwnd, WM_NCDESTROY, 0, 0 );
557 /* Remove the window from current task windows list */
558 RemoveWindowFromTask(GetCurrentTask(), hwnd);
560 /* Destroy the window */
562 WIN_DestroyWindow( hwnd );
563 return TRUE;
567 /***********************************************************************
568 * CloseWindow (USER.43)
570 void CloseWindow(HWND hWnd)
572 WND * wndPtr = WIN_FindWndPtr(hWnd);
573 if (wndPtr->dwStyle & WS_CHILD) return;
574 ShowWindow(hWnd, SW_MINIMIZE);
578 /***********************************************************************
579 * OpenIcon (USER.44)
581 BOOL OpenIcon(HWND hWnd)
583 if (!IsIconic(hWnd)) return FALSE;
584 ShowWindow(hWnd, SW_SHOWNORMAL);
585 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=pStack16Frame->cs<<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 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
985 return 0;
987 #ifdef WINELIB
988 (*wndenumprc)(hwnd, lParam);
989 #else
990 result = CallBack16(wndenumprc, 2,
991 CALLBACK_SIZE_WORD, (int) hwnd,
992 CALLBACK_SIZE_LONG, lParam);
993 #endif
994 if ( ! result ) {
995 return 0;
997 hwnd=wndPtr->hwndNext;
999 return 1; /* for now */
1002 /*******************************************************************
1003 * WIN_EnumChildWin
1005 * o hwnd is the first child to use, loop until all next windows
1006 * are processed
1008 * o call wdnenumprc with parameters in inverse order (pascal)
1010 * o call ourselves with the next child window
1013 static BOOL WIN_EnumChildWin(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
1015 WND *wndPtr;
1017 while (hwnd) {
1018 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
1019 return 0;
1021 #ifdef WINELIB
1022 if (!(*wndenumprc)( 2, lParam, (int) hwnd)) {
1023 #else
1024 if (!CallBack16(wndenumprc, 2,
1025 CALLBACK_SIZE_WORD, (int) hwnd,
1026 CALLBACK_SIZE_LONG, lParam)) {
1027 #endif
1028 return 0;
1030 if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) {
1031 return 0;
1033 hwnd=wndPtr->hwndNext;
1035 return 1;
1038 /*******************************************************************
1039 * EnumChildWindows (USER.55)
1041 * o gets the first child of hwnd
1043 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1045 BOOL EnumChildWindows(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
1047 WND *wndPtr;
1049 dprintf_enum(stddeb,"EnumChildWindows\n");
1051 if (hwnd == 0) return 0;
1052 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1053 hwnd = wndPtr->hwndChild;
1054 return WIN_EnumChildWin(hwnd, wndenumprc, lParam);
1057 /*******************************************************************
1058 * AnyPopup [USER.52]
1060 BOOL AnyPopup()
1062 dprintf_win(stdnimp,"EMPTY STUB !! AnyPopup !\n");
1063 return FALSE;
1066 /*******************************************************************
1067 * FlashWindow [USER.105]
1069 BOOL FlashWindow(HWND hWnd, BOOL bInvert)
1071 dprintf_win(stdnimp,"EMPTY STUB !! FlashWindow !\n");
1072 return FALSE;
1076 /*******************************************************************
1077 * SetSysModalWindow [USER.188]
1079 HWND SetSysModalWindow(HWND hWnd)
1081 HWND hWndOldModal = hWndSysModal;
1082 hWndSysModal = hWnd;
1083 dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd);
1084 return hWndOldModal;
1088 /*******************************************************************
1089 * GetSysModalWindow [USER.189]
1091 HWND GetSysModalWindow(void)
1093 return hWndSysModal;