Ignore:
Timestamp:
Aug 31, 1999, 12:36:24 PM (26 years ago)
Author:
sandervl
Message:

Added MDI class + ChildWindowFromPointEx by Rene Pronk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/user32/new/win32wmdiclient.cpp

    r743 r750  
    1 /* $Id: win32wmdiclient.cpp,v 1.1 1999-08-30 14:21:50 sandervl Exp $ */
     1/* $Id: win32wmdiclient.cpp,v 1.2 1999-08-31 10:36:23 sandervl Exp $ */
    22/*
    3  * Win32 Window Class for OS/2
     3 * Win32 MDI Client Window Class for OS/2
    44 *
    55 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
     
    2222#include <misc.h>
    2323#include <heapstring.h>
     24#include <win32wnd.h>
    2425#include <win32wmdiclient.h>
    25 #include <win32wnd.h>
    2626#include <spy.h>
    2727#include "wndmsg.h"
     
    4343                : Win32BaseWindow(lpCreateStructA, classAtom, isUnicode)
    4444{
    45    memset(&ci, 0, sizeof(ci));
     45    maximizedChild     = 0;
     46    activeChild        = 0;
     47    nActiveChildren    = 0;
     48    nTotalCreated      = 0;
     49    frameTitle         = NULL;
     50    mdiFlags           = 0;
     51    idFirstChild       = 0;
     52    hWindowMenu        = 0;
    4653}
    4754//******************************************************************************
     
    5461LRESULT Win32MDIClientWindow::MDIClientWndProc(UINT message, WPARAM wParam, LPARAM lParam)
    5562{
    56   LPCREATESTRUCTA  cs;
    57   RECT             rect;
    58   INT              nItems;
    59   LRESULT          retvalue;
    60   Win32Window     *frameWnd;
     63  LPCREATESTRUCTA   cs;
     64  LPCLIENTCREATESTRUCT ccs;
     65  RECT              rect;
     66  INT               nItems;
     67  LRESULT           retvalue;
     68  Win32Window       *frameWnd;
     69  Win32MDIChildWindow *mdichild;
    6170
    6271    frameWnd = (Win32Window *)getParent();
     
    6574    }
    6675
     76    switch (message)
     77    {
     78    case WM_CREATE:
     79        cs = (LPCREATESTRUCTA)lParam;
     80        ccs = (LPCLIENTCREATESTRUCT)cs->lpCreateParams;
     81
     82        hWindowMenu     = ccs->hWindowMenu;
     83        idFirstChild    = ccs->idFirstChild;
     84
     85        maximizedChild  = 0;
     86        activeChild     = 0;
     87        nActiveChildren = 0;
     88        nTotalCreated   = 0;
     89        frameTitle      = NULL;
     90        mdiFlags        = 0;
     91
     92        setStyle(getStyle() | WS_CLIPCHILDREN);
     93
     94//        MDI_UpdateFrameText(frameWnd, hwnd, MDI_NOFRAMEREPAINT,frameWnd->text);
     95
     96        AppendMenuA( hWindowMenu, MF_SEPARATOR, 0, NULL );
     97
     98        setClientRect(frameWnd->getClientRect());
     99
     100        dprintf(("MDIClient created - hwnd = %04x, idFirst = %u\n", getWindowHandle(), idFirstChild ));
     101
     102        retvalue = 0;
     103        goto END;
     104
     105    case WM_DESTROY:
     106//        if( maximizedChild ) MDI_RestoreFrameMenu(w, frameWnd->hwndSelf);
     107
     108        if((nItems = GetMenuItemCount(hWindowMenu)) > 0)
     109        {
     110            idFirstChild = nItems - 1;
     111            nActiveChildren++;      /* to delete a separator */
     112            while( nActiveChildren-- )
     113                DeleteMenu(hWindowMenu,MF_BYPOSITION,idFirstChild--);
     114        }
     115        retvalue = 0;
     116        goto END;
     117
     118    case WM_MDIACTIVATE:
     119        if( activeChild && activeChild->getWindowHandle() != (HWND)wParam )
     120
     121        mdichild = (Win32MDIChildWindow *)GetWindowFromHandle((HWND)wParam);
     122        if(mdichild) {
     123            mdichild->SetWindowPos(0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
     124        }
     125        retvalue = 0;
     126        goto END;
     127
    67128#if 0
    68     switch (message)
    69     {
    70       case WM_CREATE:
    71         cs = (LPCREATESTRUCTA)lParam;
    72 
    73         ci->hWindowMenu         = cs->lpCreateParams->hWindowMenu;
    74         ci->idFirstChild        = cs->lpCreateParams->idFirstChild;
    75 
    76         ci->hwndChildMaximized  = 0;
    77         ci->nActiveChildren     = 0;
    78         ci->nTotalCreated       = 0;
    79         ci->frameTitle          = NULL;
    80         ci->mdiFlags            = 0;
    81         ci->self                = hwnd;
    82         w->dwStyle             |= WS_CLIPCHILDREN;
    83 
    84         MDI_UpdateFrameText(frameWnd, hwnd, MDI_NOFRAMEREPAINT,frameWnd->text);
    85 
    86         AppendMenuA( ci->hWindowMenu, MF_SEPARATOR, 0, NULL );
    87 
    88         GetClientRect(frameWnd->hwndSelf, &rect);
    89         w->rectClient = rect;
    90 
    91         dprintf(("MDIClient created - hwnd = %04x, idFirst = %u\n",
    92                            hwnd, ci->idFirstChild ));
    93 
    94         retvalue = 0;
    95         goto END;
    96      
    97       case WM_DESTROY:
    98         if( ci->hwndChildMaximized ) MDI_RestoreFrameMenu(w, frameWnd->hwndSelf);
    99         if((nItems = GetMenuItemCount(ci->hWindowMenu)) > 0)
    100         {
    101             ci->idFirstChild = nItems - 1;
    102             ci->nActiveChildren++;              /* to delete a separator */
    103             while( ci->nActiveChildren-- )
    104                 DeleteMenu(ci->hWindowMenu,MF_BYPOSITION,ci->idFirstChild--);
    105         }
    106         retvalue = 0;
    107         goto END;
    108 
    109       case WM_MDIACTIVATE:
    110         if( ci->hwndActiveChild != (HWND)wParam )
    111             SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE);
    112         retvalue = 0;
    113         goto END;
    114 
    115       case WM_MDICASCADE:
     129    case WM_MDICASCADE:
    116130        retvalue = MDICascade(w, ci);
    117131        goto END;
    118 
    119       case WM_MDICREATE:
    120         if (lParam) retvalue = MDICreateChild( w, ci, hwnd,
    121                                            (MDICREATESTRUCTA*)lParam );
    122         else retvalue = 0;
    123         goto END;
    124 
    125       case WM_MDIDESTROY:
    126         retvalue = MDIDestroyChild( w, ci, hwnd, (HWND)wParam, TRUE );
    127         goto END;
    128 
    129       case WM_MDIGETACTIVE:
    130           if (lParam) *(BOOL *)lParam = (ci->hwndChildMaximized > 0);
    131           retvalue = ci->hwndActiveChild;
    132           goto END;
    133 
    134       case WM_MDIICONARRANGE:
    135         ci->mdiFlags |= MDIF_NEEDUPDATE;
     132#endif
     133
     134    case WM_MDICREATE:
     135        if (lParam) {
     136                retvalue = Win32MDIChildWindow::createChild( this, (MDICREATESTRUCTA*)lParam );
     137        }
     138        else    retvalue = 0;
     139        goto END;
     140
     141    case WM_MDIDESTROY:
     142//        retvalue = MDIDestroyChild( w, ci, hwnd, (HWND)wParam, TRUE );
     143        goto END;
     144
     145    case WM_MDIGETACTIVE:
     146        if (lParam)
     147            *(BOOL *)lParam = (maximizedChild != 0);
     148
     149        retvalue = (activeChild) ? activeChild->getWindowHandle() : 0;
     150        goto END;
     151
     152#if 0
     153    case WM_MDIICONARRANGE:
     154        mdiFlags |= MDIF_NEEDUPDATE;
    136155        ArrangeIconicWindows(hwnd);
    137         ci->sbRecalc = SB_BOTH+1;
    138         SendMessageA(hwnd, WM_MDICALCCHILDSCROLL, 0, 0L);
    139         retvalue = 0;
    140         goto END;
    141        
    142       case WM_MDIMAXIMIZE:
    143         ShowWindow( (HWND)wParam, SW_MAXIMIZE );
    144         retvalue = 0;
    145         goto END;
    146 
    147       case WM_MDINEXT: /* lParam != 0 means previous window */
    148         MDI_SwitchActiveChild(hwnd, (HWND)wParam, (lParam)? FALSE : TRUE );
    149         break;
    150        
    151       case WM_MDIRESTORE:
    152         SendMessageA( (HWND)wParam, WM_SYSCOMMAND, SC_RESTORE, 0);
    153         retvalue = 0;
    154         goto END;
    155 
    156       case WM_MDISETMENU:
    157           retvalue = MDISetMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
    158           goto END;
    159       case WM_MDIREFRESHMENU:
    160           retvalue = MDIRefreshMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
    161           goto END;
    162 
    163       case WM_MDITILE:
    164         ci->mdiFlags |= MDIF_NEEDUPDATE;
    165         ShowScrollBar(hwnd,SB_BOTH,FALSE);
    166         MDITile(w, ci, wParam);
    167         ci->mdiFlags &= ~MDIF_NEEDUPDATE;
    168         retvalue = 0;
    169         goto END;
    170 
    171       case WM_VSCROLL:
    172       case WM_HSCROLL:
    173         ci->mdiFlags |= MDIF_NEEDUPDATE;
     156        sbRecalc = SB_BOTH+1;
     157        SendMessageA(hwnd, WM_MDICALCCHILDSCROLL, 0, 0L);
     158        retvalue = 0;
     159        goto END;
     160#endif
     161
     162    case WM_MDIMAXIMIZE:
     163        ::ShowWindow( (HWND)wParam, SW_MAXIMIZE );
     164        retvalue = 0;
     165        goto END;
     166
     167    case WM_MDINEXT: /* lParam != 0 means previous window */
     168//        MDI_SwitchActiveChild(hwnd, (HWND)wParam, (lParam)? FALSE : TRUE );
     169        break;
     170
     171    case WM_MDIRESTORE:
     172        ::SendMessageA( (HWND)wParam, WM_SYSCOMMAND, SC_RESTORE, 0);
     173        retvalue = 0;
     174        goto END;
     175#if 0
     176    case WM_MDISETMENU:
     177        retvalue = MDISetMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
     178        goto END;
     179
     180    case WM_MDIREFRESHMENU:
     181        retvalue = MDIRefreshMenu( hwnd, (HMENU)wParam, (HMENU)lParam );
     182        goto END;
     183
     184    case WM_MDITILE:
     185        mdiFlags |= MDIF_NEEDUPDATE;
     186        ShowScrollBar(hwnd,SB_BOTH,FALSE);
     187        MDITile(w, ci, wParam);
     188        mdiFlags &= ~MDIF_NEEDUPDATE;
     189        retvalue = 0;
     190        goto END;
     191
     192    case WM_VSCROLL:
     193    case WM_HSCROLL:
     194        mdiFlags |= MDIF_NEEDUPDATE;
    174195        ScrollChildren(hwnd, message, wParam, lParam);
    175         ci->mdiFlags &= ~MDIF_NEEDUPDATE;
    176         retvalue = 0;
    177         goto END;
    178 
    179       case WM_SETFOCUS:
    180         if( ci->hwndActiveChild )
    181         {
    182            WND* pw = WIN_FindWndPtr( ci->hwndActiveChild );
    183            if( !(pw->dwStyle & WS_MINIMIZE) )
    184                SetFocus( ci->hwndActiveChild );
    185            WIN_ReleaseWndPtr(pw);
    186         }
    187         retvalue = 0;
    188         goto END;
    189        
    190       case WM_NCACTIVATE:
    191         if( ci->hwndActiveChild )
    192              SendMessageA(ci->hwndActiveChild, message, wParam, lParam);
    193         break;
    194        
    195       case WM_PARENTNOTIFY:
     196        mdiFlags &= ~MDIF_NEEDUPDATE;
     197        retvalue = 0;
     198        goto END;
     199#endif
     200
     201    case WM_SETFOCUS:
     202        if( activeChild )
     203        {
     204            if( !(activeChild->getStyle() & WS_MINIMIZE) )
     205                ::SetFocus(activeChild->getWindowHandle());
     206        }
     207        retvalue = 0;
     208        goto END;
     209
     210    case WM_NCACTIVATE:
     211        if( activeChild )
     212            activeChild->SendMessageA(message, wParam, lParam);
     213        break;
     214
     215    case WM_PARENTNOTIFY:
    196216        if (LOWORD(wParam) == WM_LBUTTONDOWN)
    197217        {
    198             POINT  pt = MAKEPOINT(lParam);
    199             HWND child = ChildWindowFromPoint(hwnd, pt);
    200 
    201             if( child && child != hwnd && child != ci->hwndActiveChild )
    202                 SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
    203         }
    204         retvalue = 0;
    205         goto END;
    206 
    207       case WM_SIZE:
    208         if( IsWindow(ci->hwndChildMaximized) )
    209         {
    210             WND*        child = WIN_FindWndPtr(ci->hwndChildMaximized);
    211             RECT        rect;
    212 
    213             rect.left = 0;
    214             rect.top = 0;
    215             rect.right = LOWORD(lParam);
    216             rect.bottom = HIWORD(lParam);
    217 
    218             AdjustWindowRectEx(&rect, child->dwStyle, 0, child->dwExStyle);
    219             MoveWindow(ci->hwndChildMaximized, rect.left, rect.top,
    220                          rect.right - rect.left, rect.bottom - rect.top, 1);
    221             WIN_ReleaseWndPtr(child);
    222         }
    223         else
    224             MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
    225 
    226         break;
    227 
    228       case WM_MDICALCCHILDSCROLL:
    229         if( (ci->mdiFlags & MDIF_NEEDUPDATE) && ci->sbRecalc )
    230         {
    231             CalcChildScroll(hwnd, ci->sbRecalc-1);
    232             ci->sbRecalc = 0;
    233             ci->mdiFlags &= ~MDIF_NEEDUPDATE;
    234         }
    235         retvalue = 0;
    236         goto END;
    237     }
    238 #endif   
     218            POINTS pt = MAKEPOINTS(lParam);
     219            POINT point;
     220
     221            point.x = pt.x;
     222            point.y = pt.y;
     223
     224            HWND child = ChildWindowFromPoint(getWindowHandle(), point);
     225
     226            if( child && child != getWindowHandle() && (!activeChild || activeChild->getWindowHandle() != child) )
     227                ::SetWindowPos(child, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE );
     228        }
     229        retvalue = 0;
     230        goto END;
     231
     232    case WM_SIZE:
     233        if( maximizedChild && maximizedChild->IsWindow() )
     234        {
     235            RECT    rect;
     236
     237            rect.left = 0;
     238            rect.top = 0;
     239            rect.right = LOWORD(lParam);
     240            rect.bottom = HIWORD(lParam);
     241
     242            AdjustWindowRectEx(&rect, maximizedChild->getStyle(), 0, maximizedChild->getExStyle());
     243            ::MoveWindow(maximizedChild->getWindowHandle(), rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 1);
     244        }
     245#if 0
     246        else
     247            MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
     248#endif
     249        break;
     250
     251#if 0
     252    case WM_MDICALCCHILDSCROLL:
     253        if( (mdiFlags & MDIF_NEEDUPDATE) && sbRecalc )
     254        {
     255            CalcChildScroll(hwnd, sbRecalc-1);
     256            sbRecalc = 0;
     257            mdiFlags &= ~MDIF_NEEDUPDATE;
     258        }
     259        retvalue = 0;
     260        goto END;
     261#endif
     262    }
    239263    retvalue = DefWindowProcA(message, wParam, lParam );
    240264END:
     
    242266}
    243267/**********************************************************************
    244  *                                      MDIClientWndProc
     268 *                  MDIClientWndProc
    245269 *
    246270 * This function handles all MDI requests.
     
    257281    }
    258282    return window->MDIClientWndProc(message, wParam, lParam);
     283}
     284/**********************************************************************
     285 *                  MDI_ChildActivate
     286 *
     287 * Note: hWndChild is NULL when last child is being destroyed
     288 */
     289LONG Win32MDIClientWindow::childActivate(Win32MDIChildWindow *child)
     290{
     291    BOOL                  isActiveFrameWnd = 0;
     292    LONG                  retvalue;
     293    Win32MDIChildWindow  *prevActive = activeChild;
     294
     295    if( child && child->getStyle() & WS_DISABLED )
     296    {
     297        return 0;
     298    }
     299
     300    if( GetActiveWindow() == getParent()->getWindowHandle())
     301        isActiveFrameWnd = TRUE;
     302
     303    /* deactivate prev. active child */
     304    if( prevActive )
     305    {
     306        prevActive->setStyle(prevActive->getStyle() | WS_SYSMENU);
     307        prevActive->SendMessageA( WM_NCACTIVATE, FALSE, 0L );
     308        prevActive->SendMessageA( WM_MDIACTIVATE, (WPARAM)prevActive->getWindowHandle(), (LPARAM)(child) ? child->getWindowHandle() : 0);
     309
     310        /* uncheck menu item */
     311        if( getMDIMenu() )
     312                CheckMenuItem(getMDIMenu(), prevActive->getWindowId(), 0);
     313    }
     314
     315    /* set appearance */
     316    if( maximizedChild)
     317    {
     318        if( maximizedChild != child) {
     319            if( child ) {
     320                activeChild = child;
     321                child->ShowWindow(SW_SHOWMAXIMIZED);
     322            }
     323            else
     324            if(activeChild) activeChild->ShowWindow( SW_SHOWNORMAL );
     325        }
     326    }
     327
     328    activeChild = child;
     329
     330    /* check if we have any children left */
     331    if( !activeChild )
     332    {
     333        if( isActiveFrameWnd )
     334            SetFocus(getWindowHandle());
     335
     336        return 0;
     337    }
     338
     339    /* check menu item */
     340    if( getMDIMenu() )
     341        CheckMenuItem(getMDIMenu(), child->getWindowId(), MF_CHECKED);
     342
     343    /* bring active child to the top */
     344    child->SetWindowPos( 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
     345
     346    if( isActiveFrameWnd )
     347    {
     348        child->SendMessageA( WM_NCACTIVATE, TRUE, 0L);
     349        if( GetFocus() == getWindowHandle())
     350            SendMessageA( WM_SETFOCUS, (WPARAM)getWindowHandle(), 0L );
     351        else
     352            SetFocus( getWindowHandle() );
     353    }
     354    child->SendMessageA( WM_MDIACTIVATE, (WPARAM)prevActive->getWindowHandle(), (LPARAM)child->getWindowHandle());
     355
     356    return TRUE;
     357}
     358/**********************************************************************
     359 *          MDI_SwitchActiveChild
     360 *
     361 * Note: SetWindowPos sends WM_CHILDACTIVATE to the child window that is
     362 *       being activated
     363 */
     364void Win32MDIClientWindow::switchActiveChild(Win32MDIChildWindow *nextActiveChild, BOOL bNextWindow )
     365{
     366    Win32MDIChildWindow *prevActiveChild  = 0;
     367
     368    if ( !nextActiveChild) return; /* no window to switch to */
     369
     370    prevActiveChild = getActiveChild();
     371
     372    if ( prevActiveChild !=  nextActiveChild)
     373    {
     374        BOOL bOptimize = 0;
     375
     376        if( getMaximizedChild() )
     377        {
     378            bOptimize = 1;
     379            nextActiveChild->setStyle(nextActiveChild->getStyle()& ~WS_VISIBLE);
     380        }
     381
     382        nextActiveChild->SetWindowPos(HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
     383
     384        if( bNextWindow && prevActiveChild )
     385            prevActiveChild->SetWindowPos(HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE );
     386
     387        if( bOptimize )
     388            ShowWindow(SW_SHOW );
     389    }
     390}
     391
     392
     393/**********************************************************************
     394 *                                      MDIDestroyChild
     395 */
     396LRESULT Win32MDIClientWindow::destroyChild(Win32MDIChildWindow *child, BOOL flagDestroy )
     397{
     398    if( child == getActiveChild())
     399    {
     400        switchActiveChild(child, TRUE);
     401
     402        if( child == getActiveChild() )
     403        {
     404            ShowWindow(SW_HIDE);
     405            if( child == getMaximizedChild() )
     406            {
     407//                MDI_RestoreFrameMenu(w_parent->parent, child);
     408                  setMaximizedChild(NULL);
     409//                MDI_UpdateFrameText(w_parent->parent,parent,TRUE,NULL);
     410            }
     411            childActivate(0);
     412        }
     413    }
     414    child->menuDeleteItem();
     415
     416    decNrActiveChildren();
     417
     418    dprintf(("child destroyed - %04x\n", child->getWindowHandle()));
     419
     420    if (flagDestroy)
     421    {
     422//        MDI_PostUpdate(GetParent(child), ci, SB_BOTH+1);
     423        ::DestroyWindow(child->getWindowHandle());
     424    }
     425
     426    return 0;
     427}
     428/* -------- Miscellaneous service functions ----------
     429 *
     430 *                      MDI_GetChildByID
     431 */
     432Win32MDIChildWindow *Win32MDIClientWindow::getChildByID(INT id)
     433{
     434 Win32MDIChildWindow *child;
     435
     436    for (child = (Win32MDIChildWindow *)getFirstChild() ; child; child = (Win32MDIChildWindow *)child->getNextChild())
     437        if (child->getWindowId() == id) return child;
     438
     439    return 0;
    259440}
    260441//******************************************************************************
     
    282463{
    283464    if (GlobalFindAtomA(MDICLIENTCLASSNAME))
    284         return UnregisterClassA(MDICLIENTCLASSNAME,(HINSTANCE)NULL);
    285     else return FALSE;
    286 }
    287 //******************************************************************************
    288 //******************************************************************************
     465            return UnregisterClassA(MDICLIENTCLASSNAME,(HINSTANCE)NULL);
     466    else    return FALSE;
     467}
     468//******************************************************************************
     469//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.