/* * Window related functions * * Copyright 1993 Alexandre Julliard */ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include #include #include #include #include #include "class.h" #include "win.h" #include "heap.h" extern Display * XT_display; static HWND firstWindow = 0; /*********************************************************************** * WIN_FindWndPtr * * Return a pointer to the WND structure corresponding to a HWND. * The caller must GlobalUnlock the pointer. */ WND * WIN_FindWndPtr( HWND hwnd ) { WND * ptr; if (!hwnd) return NULL; ptr = (WND *) GlobalLock( hwnd ); if (ptr->dwMagic != WND_MAGIC) { GlobalUnlock( hwnd ); return NULL; } return ptr; } /*********************************************************************** * WIN_FindWinToRepaint * * Find a window that needs repaint. */ HWND WIN_FindWinToRepaint( HWND hwnd ) { WND * wndPtr; if (!hwnd) hwnd = firstWindow; while (hwnd) { if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0; if (wndPtr->hrgnUpdate) return hwnd; if (wndPtr->hwndChild) { HWND child; if ((child = WIN_FindWinToRepaint( wndPtr->hwndChild ))) return child; } hwnd = wndPtr->hwndNext; } return 0; } /*********************************************************************** * CreateWindow (USER.41) */ HWND CreateWindow( LPSTR className, LPSTR windowName, DWORD style, short x, short y, short width, short height, HWND parent, HMENU menu, HANDLE instance, LPSTR data ) { HANDLE class, hwnd; CLASS *classPtr; WND *wndPtr, *parentPtr = NULL; CREATESTRUCT *createStruct; HANDLE hcreateStruct; int wmcreate; Widget parentWidget = 0; #ifdef DEBUG_WIN printf( "CreateWindow: %s %s %d,%d %dx%d\n", className, windowName, x, y, width, height ); #endif if (x == CW_USEDEFAULT) x = 0; if (y == CW_USEDEFAULT) y = 0; if (width == CW_USEDEFAULT) width = 600; if (height == CW_USEDEFAULT) height = 400; /* Find the parent and class */ if (parent) { /* Check if parent is valid */ parentPtr = WIN_FindWndPtr( parent ); if (!parentPtr) return 0; } else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */ if (!(class = CLASS_FindClassByName( className, &classPtr ))) { GlobalUnlock( parent ); return 0; } /* Create the window structure */ hwnd = GlobalAlloc( GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra ); if (!hwnd) { GlobalUnlock( parent ); return 0; } /* Fill the structure */ wndPtr = (WND *) GlobalLock( hwnd ); wndPtr->hwndNext = 0; wndPtr->hwndChild = 0; wndPtr->dwMagic = WND_MAGIC; wndPtr->hwndParent = parent; wndPtr->hwndOwner = parent; /* What else? */ wndPtr->hClass = class; wndPtr->hInstance = instance; wndPtr->rectClient.left = x; wndPtr->rectClient.top = y; wndPtr->rectClient.right = x + width; wndPtr->rectClient.bottom = y + height; wndPtr->rectWindow = wndPtr->rectClient; wndPtr->hrgnUpdate = 0; wndPtr->hwndLastActive = 0; wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc; wndPtr->dwStyle = style; wndPtr->hDCE = 0; wndPtr->hmenuSystem = 0; wndPtr->wIDmenu = menu; wndPtr->flags = 0; if (classPtr->wc.cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra ); classPtr->cWindows++; /* Insert the window in the linked list */ if (parent) { wndPtr->hwndNext = parentPtr->hwndChild; parentPtr->hwndChild = hwnd; } else /* Top-level window */ { wndPtr->hwndNext = firstWindow; firstWindow = hwnd; } /* Create the widgets */ if (style & WS_CHILD) { wndPtr->shellWidget = 0; wndPtr->winWidget = XtVaCreateManagedWidget(className, coreWidgetClass, parentPtr->winWidget, XtNx, x, XtNy, y, XtNwidth, width, XtNheight, height, NULL ); } else { wndPtr->shellWidget = XtVaAppCreateShell(className, windowName, topLevelShellWidgetClass, XT_display, XtNx, x, XtNy, y, NULL ); wndPtr->compositeWidget = XtVaCreateManagedWidget(className, formWidgetClass, wndPtr->shellWidget, NULL ); if (wndPtr->wIDmenu == 0) { wndPtr->menuBarPtr = MENU_CreateMenuBar(wndPtr->compositeWidget, instance, hwnd, classPtr->wc.lpszMenuName, width); wndPtr->wIDmenu = GlobalHandleFromPointer(wndPtr->menuBarPtr->firstItem); } else { wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, instance, hwnd, wndPtr->wIDmenu, width); } if (wndPtr->menuBarPtr != NULL) { wndPtr->winWidget = XtVaCreateManagedWidget(className, compositeWidgetClass, wndPtr->compositeWidget, XtNwidth, width, XtNheight, height, XtNfromVert, wndPtr->menuBarPtr->menuBarWidget, XtNvertDistance, 4, NULL ); } else { wndPtr->winWidget = XtVaCreateManagedWidget(className, compositeWidgetClass, wndPtr->compositeWidget, XtNwidth, width, XtNheight, height, NULL ); } } /* Send the WM_CREATE message */ hcreateStruct = GlobalAlloc( GMEM_MOVEABLE, sizeof(CREATESTRUCT) ); createStruct = (CREATESTRUCT *) GlobalLock( hcreateStruct ); createStruct->lpCreateParams = data; createStruct->hInstance = instance; createStruct->hMenu = menu; createStruct->hwndParent = parent; createStruct->cx = width; createStruct->cy = height; createStruct->x = x; createStruct->y = y; createStruct->style = style; createStruct->lpszName = windowName; createStruct->lpszClass = className; createStruct->dwExStyle = 0; wmcreate = CallWindowProc( wndPtr->lpfnWndProc, hwnd, WM_CREATE, 0, (LONG) createStruct ); GlobalUnlock( hcreateStruct ); GlobalFree( hcreateStruct ); if (wmcreate == -1) { /* Abort window creation */ if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); else XtDestroyWidget( wndPtr->winWidget ); GlobalUnlock( parent ); GlobalUnlock( hwnd ); GlobalFree( hwnd ); return 0; } EVENT_AddHandlers( wndPtr->winWidget, hwnd ); if (style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW ); GlobalUnlock( parent ); GlobalUnlock( hwnd ); return hwnd; } /*********************************************************************** * DestroyWindow (USER.53) */ BOOL DestroyWindow( HWND hwnd ) { WND *wndPtr, *parentPtr; CLASS * classPtr; wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return FALSE; if (wndPtr->hwndParent) { parentPtr = WIN_FindWndPtr( wndPtr->hwndParent ); printf( "INTERNAL ERROR: DestroyWindow: Invalid window parent\n" ); return FALSE; } classPtr = CLASS_FindClassPtr( wndPtr->hClass ); if (!classPtr) { printf( "INTERNAL ERROR: DestroyWindow: Invalid window class\n" ); return FALSE; } SendMessage( hwnd, WM_DESTROY, 0, 0 ); /* Destroy all children */ /* ........... */ /* Remove the window from the linked list */ /* ........... */ /* Destroy the window */ if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget ); else XtDestroyWidget( wndPtr->winWidget ); classPtr->cWindows--; if (wndPtr->hwndParent) GlobalUnlock( wndPtr->hwndParent ); GlobalUnlock( hwnd ); GlobalFree( hwnd ); return TRUE; } /*********************************************************************** * GetClientRect (USER.33) */ void GetClientRect( HWND hwnd, LPRECT rect ) { int width, height; WND * wndPtr = WIN_FindWndPtr( hwnd ); rect->left = rect->top = rect->right = rect->bottom = 0; if (wndPtr) { XtVaGetValues(wndPtr->winWidget, XtNwidth, &width, XtNheight, &height, NULL ); GlobalUnlock( hwnd ); rect->right = width & 0xffff; rect->bottom = height & 0xffff; } } /*********************************************************************** * ShowWindow (USER.42) */ BOOL ShowWindow( HWND hwnd, int cmd ) { int width, height; WND * wndPtr = WIN_FindWndPtr( hwnd ); if (wndPtr) { if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget ); GlobalUnlock( hwnd ); XtVaGetValues(wndPtr->winWidget, XtNwidth, &width, XtNheight, &height, NULL ); SendMessage( hwnd, WM_SIZE, SIZE_RESTORED, (width & 0xffff) | (height << 16) ); SendMessage( hwnd, WM_SHOWWINDOW, TRUE, 0 ); } return TRUE; } /*********************************************************************** * UpdateWindow (USER.124) */ void UpdateWindow( HWND hwnd ) { if (GetUpdateRect( hwnd, NULL, FALSE )) SendMessage( hwnd, WM_PAINT, 0, 0 ); } /********************************************************************** * GetMenu (USER.157) */ HMENU GetMenu( HWND hwnd ) { WND *wndPtr; HMENU hmenu; wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr == NULL) return 0; hmenu = wndPtr->wIDmenu; GlobalUnlock(hwnd); return hmenu; } /********************************************************************** * SetMenu (USER.158) */ BOOL SetMenu(HWND hwnd, HMENU hmenu) { WND *wndPtr; wndPtr = WIN_FindWndPtr(hwnd); if (wndPtr == NULL) return FALSE; if (wndPtr->dwStyle & WS_CHILD) { GlobalUnlock(hwnd); return FALSE; } if (wndPtr->menuBarPtr != NULL) { XtVaSetValues(wndPtr->winWidget, XtNfromVert, NULL, NULL); MENU_CollapseMenu(wndPtr->menuBarPtr); } wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, wndPtr->hInstance, hwnd, hmenu, wndPtr->rectClient.right - wndPtr->rectClient.left); if (wndPtr->menuBarPtr != NULL) { XtVaSetValues(wndPtr->winWidget, XtNfromVert, wndPtr->menuBarPtr->menuBarWidget, XtNvertDistance, 4, NULL); } else { if (wndPtr->wIDmenu != 0) { wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, wndPtr->hInstance, hwnd, wndPtr->wIDmenu, wndPtr->rectClient.right - wndPtr->rectClient.left); } GlobalUnlock(hwnd); return FALSE; } GlobalUnlock(hwnd); return TRUE; }