Release 940815
[wine/gsoc-2012-control.git] / windows / win.c
blob392490890928bb7fb15d7a5031d795fff5f60e80
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, icon_attr;
255 int iconWidth, iconHeight;
257 #ifdef DEBUG_WIN
258 printf( "CreateWindowEx: %04X '%s' '%s' %04X %d,%d %dx%d %04X %04X %04X %08X\n",
259 exStyle, className, windowName, style, x, y, width, height,
260 parent, menu, instance, data);
261 #endif
262 /* 'soundrec.exe' has negative position !
263 Why ? For now, here a patch : */
264 if (!strcmp(className, "SoundRec"))
266 if (x < 0) x = 0;
267 if (y < 0) y = 0;
269 if (x == CW_USEDEFAULT) x = y = 0;
270 if (width == CW_USEDEFAULT)
272 width = 600;
273 height = 400;
275 if (width == 0) width = 1;
276 if (height == 0) height = 1;
278 /* Find the parent and class */
280 if (parent)
282 /* Check if parent is valid */
283 if (!(parentPtr = WIN_FindWndPtr( parent ))) return 0;
285 else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */
287 if (!(class = CLASS_FindClassByName( className, &classPtr ))) {
288 printf("CreateWindow BAD CLASSNAME '%s' !\n", className);
289 return 0;
292 /* Correct the window style */
294 if (!(style & (WS_POPUP | WS_CHILD))) /* Overlapped window */
295 style |= WS_CAPTION | WS_CLIPSIBLINGS;
296 if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
298 /* Create the window structure */
300 hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra);
301 if (!hwnd) return 0;
303 /* Fill the structure */
305 wndPtr = (WND *) USER_HEAP_ADDR( hwnd );
306 wndPtr->hwndNext = 0;
307 wndPtr->hwndChild = 0;
308 wndPtr->window = 0;
309 wndPtr->dwMagic = WND_MAGIC;
310 wndPtr->hwndParent = (style & WS_CHILD) ? parent : hwndDesktop;
311 wndPtr->hwndOwner = (style & WS_CHILD) ? 0 : parent;
312 wndPtr->hClass = class;
313 wndPtr->hInstance = instance;
314 wndPtr->rectWindow.left = x;
315 wndPtr->rectWindow.top = y;
316 wndPtr->rectWindow.right = x + width;
317 wndPtr->rectWindow.bottom = y + height;
318 wndPtr->rectClient = wndPtr->rectWindow;
319 wndPtr->rectNormal = wndPtr->rectWindow;
320 wndPtr->ptIconPos.x = -1;
321 wndPtr->ptIconPos.y = -1;
322 wndPtr->ptMaxPos.x = -1;
323 wndPtr->ptMaxPos.y = -1;
324 wndPtr->hmemTaskQ = GetTaskQueue(0);
325 wndPtr->hrgnUpdate = 0;
326 wndPtr->hwndPrevActive = 0;
327 wndPtr->hwndLastActive = 0;
328 wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc;
329 wndPtr->dwStyle = style;
330 wndPtr->dwExStyle = exStyle;
331 wndPtr->wIDmenu = 0;
332 wndPtr->hText = 0;
333 wndPtr->flags = 0;
334 wndPtr->VScroll = NULL;
335 wndPtr->HScroll = NULL;
336 wndPtr->scroll_flags = 0;
337 wndPtr->hSysMenu = 0;
338 wndPtr->hProp = 0;
339 wndPtr->hTask = 0;
341 if (classPtr->wc.cbWndExtra)
342 memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
343 if (classPtr->wc.style & CS_DBLCLKS) wndPtr->flags |= WIN_DOUBLE_CLICKS;
344 classPtr->cWindows++;
346 /* Get class or window DC if needed */
347 if (classPtr->wc.style & CS_OWNDC)
349 wndPtr->flags |= WIN_OWN_DC;
350 wndPtr->hdce = DCE_AllocDCE( DCE_WINDOW_DC );
352 else if (classPtr->wc.style & CS_CLASSDC)
354 wndPtr->flags |= WIN_CLASS_DC;
355 wndPtr->hdce = classPtr->hdce;
357 else wndPtr->hdce = 0;
359 /* Insert the window in the linked list */
361 WIN_LinkWindow( hwnd, HWND_TOP );
363 /* Create the X window */
365 win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
366 PointerMotionMask | ButtonPressMask |
367 ButtonReleaseMask | EnterWindowMask;
368 win_attr.override_redirect = (rootWindow == DefaultRootWindow(display));
369 win_attr.colormap = COLOR_WinColormap;
370 if (!(style & WS_CHILD))
372 parentPtr = WIN_FindWndPtr( hwndDesktop );
373 /* Only select focus events on top-level override-redirect windows */
374 if (win_attr.override_redirect) win_attr.event_mask |= FocusChangeMask;
376 if (Options.nobackingstore)
377 win_attr.backing_store = NotUseful;
378 else
379 win_attr.backing_store = Always;
381 win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0);
383 WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
385 if ( maxSize.x < width)
387 width = maxSize.x;
388 wndPtr->rectWindow.right = x + width;
390 if ( maxSize.y < height)
392 height = maxSize.y;
393 wndPtr->rectWindow.bottom = y + height;
396 wndPtr->window = XCreateWindow( display, parentPtr->window,
397 x + parentPtr->rectClient.left - parentPtr->rectWindow.left,
398 y + parentPtr->rectClient.top - parentPtr->rectWindow.top,
399 width, height, 0,
400 CopyFromParent, InputOutput, CopyFromParent,
401 CWEventMask | CWOverrideRedirect | CWColormap |
402 CWSaveUnder | CWBackingStore, &win_attr );
403 XStoreName( display, wndPtr->window, windowName );
406 /* create icon window */
408 icon_attr.override_redirect = rootWindow==DefaultRootWindow(display);
409 icon_attr.background_pixel = WhitePixelOfScreen(screen);
410 icon_attr.event_mask = ExposureMask | KeyPressMask |
411 ButtonPressMask | ButtonReleaseMask;
413 wndPtr->hIcon = classPtr->wc.hIcon;
414 if (wndPtr->hIcon != (HICON)NULL) {
415 ICONALLOC *lpico;
416 lpico = (ICONALLOC *)GlobalLock(wndPtr->hIcon);
417 printf("icon is %d x %d\n",
418 (int)lpico->descriptor.Width,
419 (int)lpico->descriptor.Height);
420 iconWidth = (int)lpico->descriptor.Width;
421 iconHeight = (int)lpico->descriptor.Height;
422 } else {
423 printf("icon was NULL\n");
424 iconWidth = 64;
425 iconHeight = 64;
428 wndPtr->icon = XCreateWindow(display, parentPtr->window,
429 10, 10, 100, iconHeight+20,
430 0, CopyFromParent,
431 InputOutput, CopyFromParent,
432 CWBorderPixel | CWEventMask | CWOverrideRedirect,
433 &icon_attr);
435 if (style & WS_MINIMIZE)
437 style &= ~WS_MINIMIZE;
442 #ifdef DEBUG_MENU
443 printf("CreateWindowEx // menu=%04X instance=%04X classmenu=%08X !\n",
444 menu, instance, classPtr->wc.lpszMenuName);
445 #endif
446 if ((style & WS_CAPTION) && (style & WS_CHILD) == 0) {
447 if (menu != 0)
448 SetMenu(hwnd, menu);
449 else {
450 if (classPtr->wc.lpszMenuName != NULL)
451 SetMenu(hwnd, LoadMenu(instance, classPtr->wc.lpszMenuName));
454 else
455 wndPtr->wIDmenu = menu;
457 /* Send the WM_CREATE message */
459 hcreateStruct = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CREATESTRUCT) );
460 createStruct = (CREATESTRUCT *) USER_HEAP_ADDR( hcreateStruct );
461 createStruct->lpCreateParams = data;
462 createStruct->hInstance = instance;
463 createStruct->hMenu = menu;
464 createStruct->hwndParent = parent;
465 createStruct->cx = width;
466 createStruct->cy = height;
467 createStruct->x = x;
468 createStruct->y = y;
469 createStruct->style = style;
470 createStruct->lpszName = windowName;
471 createStruct->lpszClass = className;
472 createStruct->dwExStyle = 0;
474 wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LONG)createStruct );
475 if (!wmcreate) wmcreate = -1;
476 else
478 WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
479 NULL, NULL, NULL, &wndPtr->rectClient );
480 wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct );
483 USER_HEAP_FREE( hcreateStruct );
485 if (wmcreate == -1)
487 /* Abort window creation */
489 WIN_UnlinkWindow( hwnd );
490 XDestroyWindow( display, wndPtr->window );
491 if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
492 classPtr->cWindows--;
493 USER_HEAP_FREE( hwnd );
494 return 0;
497 /* Create a copy of SysMenu */
498 if (style & WS_SYSMENU) wndPtr->hSysMenu = CopySysMenu();
500 /* Register window in current task windows list */
501 AddWindowToTask(GetCurrentTask(), hwnd);
503 /* Set window cursor */
504 if (classPtr->wc.hCursor) CURSOR_SetWinCursor( hwnd, classPtr->wc.hCursor);
505 else CURSOR_SetWinCursor( hwnd, LoadCursor( 0, IDC_ARROW ));
507 EVENT_RegisterWindow( wndPtr->window, hwnd );
508 EVENT_RegisterWindow( wndPtr->icon, hwnd );
510 WIN_SendParentNotify( hwnd, WM_CREATE, MAKELONG( hwnd, wndPtr->wIDmenu ) );
512 if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
513 #ifdef DEBUG_WIN
514 printf( "CreateWindowEx: return %04X \n", hwnd);
515 #endif
516 return hwnd;
520 /***********************************************************************
521 * DestroyWindow (USER.53)
523 BOOL DestroyWindow( HWND hwnd )
525 WND * wndPtr;
526 CLASS * classPtr;
528 /* Initialisation */
530 if (hwnd == hwndDesktop) return FALSE; /* Can't destroy desktop */
531 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
532 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return FALSE;
534 /* Hide the window */
536 if (wndPtr->dwStyle & WS_VISIBLE)
537 SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_HIDEWINDOW | SWP_NOACTIVATE |
538 SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
539 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
540 ReleaseCapture();
541 WIN_SendParentNotify( hwnd, WM_DESTROY, MAKELONG(hwnd, wndPtr->wIDmenu) );
543 /* Send destroy messages and destroy children */
545 SendMessage( hwnd, WM_DESTROY, 0, 0 );
546 while (wndPtr->hwndChild) /* The child removes itself from the list */
547 DestroyWindow( wndPtr->hwndChild );
548 SendMessage( hwnd, WM_NCDESTROY, 0, 0 );
550 /* Remove the window from current task windows list */
551 RemoveWindowFromTask(GetCurrentTask(), hwnd);
553 /* Remove the window from the linked list */
554 WIN_UnlinkWindow( hwnd );
556 /* Destroy the window */
558 wndPtr->dwMagic = 0; /* Mark it as invalid */
559 XDestroyWindow( display, wndPtr->window );
560 if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
561 classPtr->cWindows--;
562 USER_HEAP_FREE( 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);
579 /***********************************************************************
580 * OpenIcon (USER.44)
582 BOOL OpenIcon(HWND hWnd)
584 if (!IsIconic(hWnd)) return FALSE;
585 ShowWindow(hWnd, SW_SHOWNORMAL);
586 return(TRUE);
591 /***********************************************************************
592 * FindWindow (USER.50)
594 HWND FindWindow(LPSTR ClassMatch, LPSTR TitleMatch)
596 HCLASS hclass;
597 CLASS *classPtr;
598 HWND hwnd;
600 if (ClassMatch)
602 hclass = CLASS_FindClassByName( ClassMatch, &classPtr );
603 if (!hclass) return 0;
605 else hclass = 0;
607 hwnd = GetTopWindow( hwndDesktop );
608 while(hwnd)
610 WND *wndPtr = WIN_FindWndPtr( hwnd );
611 if (!hclass || (wndPtr->hClass == hclass))
613 /* Found matching class */
614 if (!TitleMatch) return hwnd;
615 if (wndPtr->hText)
617 char *textPtr = (char *) USER_HEAP_ADDR( wndPtr->hText );
618 if (!strcmp( textPtr, TitleMatch )) return hwnd;
621 hwnd = wndPtr->hwndNext;
623 return 0;
627 /**********************************************************************
628 * GetDesktopWindow (USER.286)
629 * GetDeskTopHwnd (USER.278)
631 HWND GetDesktopWindow(void)
633 return hwndDesktop;
637 /*******************************************************************
638 * EnableWindow (USER.34)
640 BOOL EnableWindow( HWND hwnd, BOOL enable )
642 WND *wndPtr;
644 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
645 if (enable && (wndPtr->dwStyle & WS_DISABLED))
647 /* Enable window */
648 wndPtr->dwStyle &= ~WS_DISABLED;
649 SendMessage( hwnd, WM_ENABLE, TRUE, 0 );
650 return TRUE;
652 else if (!enable && !(wndPtr->dwStyle & WS_DISABLED))
654 /* Disable window */
655 wndPtr->dwStyle |= WS_DISABLED;
656 if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
657 SetFocus( 0 ); /* A disabled window can't have the focus */
658 if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
659 ReleaseCapture(); /* A disabled window can't capture the mouse */
660 SendMessage( hwnd, WM_ENABLE, FALSE, 0 );
661 return FALSE;
663 return ((wndPtr->dwStyle & WS_DISABLED) != 0);
667 /***********************************************************************
668 * IsWindowEnabled (USER.35)
670 BOOL IsWindowEnabled(HWND hWnd)
672 WND * wndPtr;
674 if (!(wndPtr = WIN_FindWndPtr(hWnd))) return FALSE;
675 return !(wndPtr->dwStyle & WS_DISABLED);
679 /**********************************************************************
680 * GetWindowWord (USER.133)
682 WORD GetWindowWord( HWND hwnd, short offset )
684 WND * wndPtr = WIN_FindWndPtr( hwnd );
685 if (!wndPtr) return 0;
686 if (offset >= 0) return *(WORD *)(((char *)wndPtr->wExtra) + offset);
687 switch(offset)
689 case GWW_ID: return wndPtr->wIDmenu;
690 case GWW_HWNDPARENT: return wndPtr->hwndParent;
691 case GWW_HINSTANCE: return wndPtr->hInstance;
693 return 0;
697 /**********************************************************************
698 * SetWindowWord (USER.134)
700 WORD SetWindowWord( HWND hwnd, short offset, WORD newval )
702 WORD *ptr, retval;
703 WND * wndPtr = WIN_FindWndPtr( hwnd );
704 if (!wndPtr) return 0;
705 if (offset >= 0) ptr = (WORD *)(((char *)wndPtr->wExtra) + offset);
706 else switch(offset)
708 case GWW_ID: ptr = &wndPtr->wIDmenu;
709 case GWW_HINSTANCE: ptr = &wndPtr->hInstance;
710 default: return 0;
712 retval = *ptr;
713 *ptr = newval;
714 return retval;
718 /**********************************************************************
719 * GetWindowLong (USER.135)
721 LONG GetWindowLong( HWND hwnd, short offset )
723 WND * wndPtr = WIN_FindWndPtr( hwnd );
724 if (!wndPtr) return 0;
725 if (offset >= 0) return *(LONG *)(((char *)wndPtr->wExtra) + offset);
726 switch(offset)
728 case GWL_STYLE: return wndPtr->dwStyle;
729 case GWL_EXSTYLE: return wndPtr->dwExStyle;
730 case GWL_WNDPROC: return (LONG)wndPtr->lpfnWndProc;
732 return 0;
736 /**********************************************************************
737 * SetWindowLong (USER.136)
739 LONG SetWindowLong( HWND hwnd, short offset, LONG newval )
741 LONG *ptr, retval;
742 WND * wndPtr = WIN_FindWndPtr( hwnd );
743 if (!wndPtr) return 0;
744 if (offset >= 0) ptr = (LONG *)(((char *)wndPtr->wExtra) + offset);
745 else switch(offset)
747 case GWL_STYLE: ptr = &wndPtr->dwStyle;
748 break;
749 case GWL_EXSTYLE: ptr = &wndPtr->dwExStyle;
750 break;
751 case GWL_WNDPROC: ptr = (LONG *)(&wndPtr->lpfnWndProc);
752 break;
753 default: return 0;
755 retval = *ptr;
756 *ptr = newval;
757 return retval;
761 /*******************************************************************
762 * GetWindowText (USER.36)
764 int GetWindowText(HWND hwnd, LPSTR lpString, int nMaxCount)
766 return (int)SendMessage(hwnd, WM_GETTEXT, (WORD)nMaxCount,
767 (DWORD)lpString);
770 /*******************************************************************
771 * SetWindowText (USER.37)
773 void SetWindowText(HWND hwnd, LPSTR lpString)
775 SendMessage(hwnd, WM_SETTEXT, (WORD)NULL, (DWORD)lpString);
778 /*******************************************************************
779 * GetWindowTextLength (USER.38)
781 int GetWindowTextLength(HWND hwnd)
783 return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, (WORD)NULL,
784 (DWORD)NULL);
788 /*******************************************************************
789 * IsWindow (USER.47)
791 BOOL IsWindow( HWND hwnd )
793 WND * wndPtr = WIN_FindWndPtr( hwnd );
794 return ((wndPtr != NULL) && (wndPtr->dwMagic == WND_MAGIC));
798 /*****************************************************************
799 * GetParent (USER.46)
801 HWND GetParent(HWND hwnd)
803 WND *wndPtr = WIN_FindWndPtr(hwnd);
804 if (!wndPtr || !(wndPtr->dwStyle & WS_CHILD)) return 0;
805 return wndPtr->hwndParent;
809 /*******************************************************************
810 * IsChild (USER.48)
812 BOOL IsChild( HWND parent, HWND child )
814 WND * wndPtr = WIN_FindWndPtr( child );
815 while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
817 if (wndPtr->hwndParent == parent) return TRUE;
818 wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
820 return FALSE;
824 /***********************************************************************
825 * IsWindowVisible (USER.49)
827 BOOL IsWindowVisible(HWND hWnd)
829 WND * wndPtr = WIN_FindWndPtr(hWnd);
830 if (wndPtr == 0) return(FALSE);
831 else return ((wndPtr->dwStyle & WS_VISIBLE) != 0);
836 /*******************************************************************
837 * GetTopWindow (USER.229)
839 HWND GetTopWindow( HWND hwnd )
841 WND * wndPtr = WIN_FindWndPtr( hwnd );
842 if (wndPtr) return wndPtr->hwndChild;
843 else return 0;
847 /*******************************************************************
848 * GetWindow (USER.262)
850 HWND GetWindow( HWND hwnd, WORD rel )
852 WND * wndPtr = WIN_FindWndPtr( hwnd );
853 if (!wndPtr) return 0;
854 switch(rel)
856 case GW_HWNDFIRST:
857 if (wndPtr->hwndParent)
859 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
860 return parentPtr->hwndChild;
862 else return 0;
864 case GW_HWNDLAST:
865 if (!wndPtr->hwndParent) return 0; /* Desktop window */
866 while (wndPtr->hwndNext)
868 hwnd = wndPtr->hwndNext;
869 wndPtr = WIN_FindWndPtr( hwnd );
871 return hwnd;
873 case GW_HWNDNEXT:
874 return wndPtr->hwndNext;
876 case GW_HWNDPREV:
878 HWND hwndPrev;
880 if (wndPtr->hwndParent)
882 WND * parentPtr = WIN_FindWndPtr( wndPtr->hwndParent );
883 hwndPrev = parentPtr->hwndChild;
885 else return 0; /* Desktop window */
886 if (hwndPrev == hwnd) return 0;
887 while (hwndPrev)
889 wndPtr = WIN_FindWndPtr( hwndPrev );
890 if (wndPtr->hwndNext == hwnd) break;
891 hwndPrev = wndPtr->hwndNext;
893 return hwndPrev;
896 case GW_OWNER:
897 return wndPtr->hwndOwner;
899 case GW_CHILD:
900 return wndPtr->hwndChild;
902 return 0;
906 /*******************************************************************
907 * GetNextWindow (USER.230)
909 HWND GetNextWindow( HWND hwnd, WORD flag )
911 if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0;
912 return GetWindow( hwnd, flag );
918 /*******************************************************************
919 * EnumWindows (USER.54)
921 * o gets the desktop window and iterates over all the windows
922 * which are direct decendents of the desktop * by iterating over
923 * the desktop's child window and all the child windows next
924 * pointers
926 * o call wndenumprc for every child window the desktop has
927 * (parameters to Callback16 passed backwards so they are
928 * put in in pascal calling order)
930 * o if wndenumprc returns 0 exit
933 BOOL EnumWindows(FARPROC wndenumprc, LPARAM lParam)
935 HWND hwnd = GetTopWindow( GetDesktopWindow() );
936 WND *wndPtr;
937 int result;
939 #ifdef DEBUG_ENUM
940 printf("EnumWindows\n");
941 #endif
943 while (hwnd) {
944 char *ptr;
946 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
947 return 0;
949 #ifdef DEBUG_ENUM
950 if (XFetchName(display, wndPtr->window, &ptr) && ptr)
951 printf("found a window (%s)\n", ptr);
952 else
953 printf("found nameless parent window\n");
954 #endif
955 #ifdef WINELIB
956 (*wndenumprc)(hwnd, lParam);
957 #else
958 result = CallBack16(wndenumprc, 2, lParam, (int) hwnd);
959 #endif
960 if ( ! result ) {
961 return 0;
963 hwnd=wndPtr->hwndNext;
965 return 1; /* for now */
968 /*******************************************************************
969 * WIN_EnumChildWin
971 * o hwnd is the first child to use, loop until all next windows
972 * are processed
974 * o call wdnenumprc with parameters in inverse order (pascal)
976 * o call ourselves with the next child window
979 static BOOL WIN_EnumChildWin(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
981 WND *wndPtr;
982 int result;
985 while (hwnd) {
986 char *ptr;
987 if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) {
988 return 0;
990 #ifdef DEBUG_ENUM
991 if (XFetchName(display, wndPtr->window, &ptr) && ptr)
992 printf("EnumChild: found a child window (%s)\n", ptr);
993 else
994 printf("EnumChild: nameless child\n");
996 if (!(wndPtr->dwStyle & WS_CHILD)) {
997 printf("this is not a child window! What is it doing here?\n");
998 return 0;
1000 #endif
1001 #ifdef WINELIB
1002 if (!(*wndenumprc, 2, lParam, (int) hwnd)) {
1003 #else
1004 if (!CallBack16(wndenumprc, 2, lParam, (int) hwnd)) {
1005 #endif
1006 return 0;
1008 if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) {
1009 return 0;
1011 hwnd=wndPtr->hwndNext;
1013 return 1;
1016 /*******************************************************************
1017 * EnumChildWindows (USER.55)
1019 * o gets the first child of hwnd
1021 * o calls WIN_EnumChildWin to do a recursive decent of child windows
1023 BOOL EnumChildWindows(HWND hwnd, FARPROC wndenumprc, LPARAM lParam)
1025 WND *wndPtr;
1027 #ifdef DEBUG_ENUM
1028 printf("EnumChildWindows\n");
1029 #endif
1031 if (hwnd == 0) return 0;
1032 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1033 hwnd = wndPtr->hwndChild;
1034 return WIN_EnumChildWin(hwnd, wndenumprc, lParam);
1037 /*******************************************************************
1038 * AnyPopup [USER.52]
1040 BOOL AnyPopup()
1042 printf("EMPTY STUB !! AnyPopup !\n");
1043 return FALSE;
1046 /*******************************************************************
1047 * FlashWindow [USER.105]
1049 BOOL FlashWindow(HWND hWnd, BOOL bInvert)
1051 printf("EMPTY STUB !! FlashWindow !\n");
1052 return FALSE;
1056 /*******************************************************************
1057 * SetSysModalWindow [USER.188]
1059 HWND SetSysModalWindow(HWND hWnd)
1061 HWND hWndOldModal = hWndSysModal;
1062 hWndSysModal = hWnd;
1063 printf("EMPTY STUB !! SetSysModalWindow(%04X) !\n", hWnd);
1064 return hWndOldModal;
1068 /*******************************************************************
1069 * GetSysModalWindow [USER.189]
1071 HWND GetSysModalWindow(void)
1073 return hWndSysModal;