Annotation of mstools/mfc/samples/mdi/bounce.cpp, revision 1.1.1.1

1.1       root        1: // bounce.cpp : Defines the class behaviors for the Bounce child window.
                      2: //
                      3: // This is a part of the Microsoft Foundation Classes C++ library.
                      4: // Copyright (C) 1992 Microsoft Corporation
                      5: // All rights reserved.
                      6: //
                      7: // This source code is only intended as a supplement to the
                      8: // Microsoft Foundation Classes Reference and Microsoft
                      9: // QuickHelp documentation provided with the library.
                     10: // See these sources for detailed information regarding the
                     11: // Microsoft Foundation Classes product.
                     12: //
                     13: 
                     14: #include "mdi.h"
                     15: 
                     16: static COLORREF clrTextArray[] = { RGB (0,   0, 0), RGB (255, 0,   0),
                     17:                                                                   RGB (0, 255, 0), RGB (  0, 0, 255),
                     18:                                                                   RGB (255, 255, 255) };
                     19: 
                     20: #define ABS(x) ((x) < 0? -(x) : (x) > 0? (x) : 0)
                     21: 
                     22: 
                     23: /////////////////////////////////////////////////////////////////////////////
                     24: // CBounceWnd
                     25: 
                     26: BEGIN_MESSAGE_MAP(CBounceWnd, CMDIChildWnd)
                     27:        ON_WM_CREATE()
                     28:        ON_WM_DESTROY()
                     29:        ON_WM_SIZE()
                     30:        ON_WM_TIMER()
                     31:        ON_WM_MDIACTIVATE()
                     32:        ON_COMMAND(IDM_BLACK, OnColor)
                     33:        ON_COMMAND(IDM_RED,   OnColor)
                     34:        ON_COMMAND(IDM_GREEN, OnColor)
                     35:        ON_COMMAND(IDM_BLUE,  OnColor)
                     36:        ON_COMMAND(IDM_WHITE, OnColor)
                     37:        ON_COMMAND(IDM_CUSTOM, OnColor)
                     38:        ON_COMMAND(IDM_SLOW,  OnSpeed)
                     39:        ON_COMMAND(IDM_FAST,  OnSpeed)
                     40: END_MESSAGE_MAP()
                     41: 
                     42: // Create:
                     43: // Register a custom WndClass and create a window.
                     44: // This must be done because CBounceWnd has a custom cursor.
                     45: // 
                     46: BOOL CBounceWnd::Create(LPCSTR szTitle, LONG style /* = 0 */,
                     47:        const RECT& rect /* = rectDefault */,
                     48:        CMDIFrameWnd* parent /* = NULL */)
                     49: {
                     50:        const char* pszBounceClass = 
                     51:                AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
                     52:                        LoadCursor(NULL, IDC_UPARROW), 
                     53:                        (HBRUSH)(COLOR_WINDOW+1),
                     54:                        NULL);
                     55: 
                     56:        return CMDIChildWnd::Create(pszBounceClass, szTitle, style, rect, parent);
                     57: }
                     58: 
                     59: // Constructor:
                     60: // Minimum initialization
                     61: //
                     62: CBounceWnd::CBounceWnd()
                     63: {
                     64:        m_pBitmap = NULL;
                     65:        m_pMenuCurrent = NULL;
                     66:        m_bWindowActive = FALSE;
                     67: }
                     68: 
                     69: // Destructor:
                     70: // Release Windows resources
                     71: //
                     72: CBounceWnd::~CBounceWnd()
                     73: {
                     74:        if (m_bWindowActive)
                     75:        {
                     76:                // Suppress Foundation DestroyMenu done in CMenu destructor 
                     77:                // (Windows takes care of menu cleanup for the active window)
                     78:                //
                     79:                m_pMenuCurrent->Detach();
                     80:        }
                     81: 
                     82:        delete m_pBitmap;
                     83: 
                     84:        if (m_nSpeed != 0)
                     85:                KillTimer(1);
                     86: }
                     87: 
                     88: 
                     89: // OnCreate:
                     90: // Set up the ball parameters and start a timer.
                     91: //
                     92: int CBounceWnd::OnCreate(LPCREATESTRUCT /* p */)
                     93: {
                     94:        m_nSpeed = IDM_SLOW;
                     95:        if (!SetTimer(1, (m_nSpeed==IDM_SLOW? 100 : 0), NULL))
                     96:        {
                     97:                MessageBox("Not enough timers available for this window.",
                     98:                                "MDI:Bounce", MB_ICONEXCLAMATION | MB_OK);
                     99: 
                    100:                m_nSpeed = 0;
                    101: 
                    102:                // signal creation failure...
                    103:                return -1;
                    104:        }
                    105:        else
                    106:        {
                    107:                m_nColor = IDM_BLACK;
                    108:                m_clrBall = clrTextArray[m_nColor - IDM_BLACK];
                    109: 
                    110:                CDC* pDC = GetDC();
                    111:                m_xPixel = pDC->GetDeviceCaps(ASPECTX);
                    112:                m_yPixel = pDC->GetDeviceCaps(ASPECTY);
                    113:                ReleaseDC(pDC);
                    114: 
                    115:        // Note that we could call MakeNewBall here (which should be called
                    116:        // whenever the ball's speed, color or size has been changed), but the
                    117:        // OnSize member function is always called after the OnCreate. Since
                    118:        // the OnSize member has to call MakeNewBall anyway, we don't here.
                    119:        //
                    120: 
                    121:        }
                    122: 
                    123:        return 0;
                    124: }
                    125: 
                    126: // OnDestroy:
                    127: // Notify app main MDI frame window of destruction so it may
                    128: // do some cleanup.  Note: this uses a custom message -- see
                    129: // mdi.h and mdi.cpp for the custom message handler
                    130: //
                    131: void CBounceWnd::OnDestroy()
                    132: {
                    133:        m_pMDIFrameWnd->SendMessage(WM_CHILDDESTROY, (UINT)m_hWnd, 0);
                    134: }
                    135: 
                    136: // MakeNewBall:
                    137: // Whenever a parameter changes which would affect the speed or appearance
                    138: // of the ball, call this to regenerate the ball bitmap.
                    139: //
                    140: void CBounceWnd::MakeNewBall()
                    141: {
                    142:        if (m_pBitmap != NULL)
                    143:        {
                    144:                // Reclaim Windows resources associated with the ball bitmap
                    145:                // before redrawing
                    146: 
                    147:                m_pBitmap->DeleteObject();
                    148:        }
                    149:        else
                    150:        {
                    151:                m_pBitmap = new CBitmap;
                    152:        }
                    153: 
                    154:        m_cxTotal = (m_cxRadius + ABS(m_cxMove)) << 1;
                    155:        m_cyTotal = (m_cyRadius + ABS(m_cyMove)) << 1;
                    156: 
                    157:        CDC dcMem;
                    158:        CDC* pDC = GetDC();
                    159:        
                    160:        dcMem.CreateCompatibleDC(pDC);
                    161: 
                    162:        m_pBitmap->CreateCompatibleBitmap(pDC, m_cxTotal, m_cyTotal);
                    163: 
                    164:        ASSERT(m_pBitmap->m_hObject != NULL);
                    165: 
                    166:        ReleaseDC(pDC);
                    167: 
                    168: 
                    169:        CBitmap* pOldBitmap = dcMem.SelectObject(m_pBitmap);
                    170: 
                    171:        // draw a rectangle in the background (window) color
                    172:        CRect rect(0, 0, m_cxTotal, m_cyTotal);
                    173:        CBrush brBackground(::GetSysColor(COLOR_WINDOW));
                    174:        dcMem.FillRect(rect, &brBackground);
                    175: 
                    176:        CBrush brCross(HS_DIAGCROSS, 0L);
                    177:        CBrush* pOldBrush = dcMem.SelectObject(&brCross);
                    178: 
                    179:        dcMem.SetBkColor(m_clrBall);
                    180:        dcMem.Ellipse(ABS(m_cxMove), ABS(m_cyMove),
                    181:                                        m_cxTotal - ABS(m_cxMove), m_cyTotal - ABS(m_cyMove));
                    182: 
                    183:        dcMem.SelectObject(pOldBrush);
                    184:        dcMem.SelectObject(pOldBitmap);
                    185:        dcMem.DeleteDC();
                    186: }
                    187: 
                    188: // OnSize:
                    189: // The ball's size and displacement change according to the window size.
                    190: //
                    191: void CBounceWnd::OnSize(UINT nType, int cx, int cy)
                    192: {
                    193:        LONG lScale;
                    194: 
                    195:        m_xCenter = (m_cxClient = cx) >> 1;
                    196:        m_yCenter = (m_cyClient = cy) >> 1;
                    197:        m_xCenter += m_cxClient >> 3; // make the ball a little off-center
                    198: 
                    199:        lScale = min((LONG)m_cxClient * m_xPixel,
                    200:                (LONG)m_cyClient * m_yPixel) >> 4;
                    201:        m_cxRadius = (short)(lScale / m_xPixel);
                    202:        m_cyRadius = (short)(lScale / m_yPixel);
                    203:        m_cxMove = max(1, m_cyRadius >> 2);
                    204:        m_cyMove = max(1, m_cyRadius >> 2);
                    205: 
                    206:        MakeNewBall();
                    207: 
                    208:        CMDIChildWnd::OnSize(nType, cx, cy);
                    209: }
                    210: 
                    211: // OnColor:
                    212: // The ball's color needs to be changed.  Checkmark the right color on the
                    213: // menu.
                    214: //
                    215: void CBounceWnd::OnColor()
                    216: {
                    217:        CMenu* pMenu = m_pMDIFrameWnd->GetMenu();
                    218:        pMenu->CheckMenuItem(m_nColor, MF_UNCHECKED);
                    219: 
                    220:        m_nColor = GetCurrentMessage()->wParam;
                    221:        pMenu->CheckMenuItem(m_nColor, MF_CHECKED);
                    222: 
                    223:        if (m_nColor != IDM_CUSTOM)
                    224:                m_clrBall = clrTextArray[m_nColor - IDM_BLACK];
                    225:        else
                    226:        {
                    227:                CColorDialog dlgColor(m_clrBall);
                    228:                if (dlgColor.DoModal() == IDOK)
                    229:                        m_clrBall = dlgColor.GetColor();
                    230:        }
                    231: 
                    232:        MakeNewBall();
                    233: 
                    234:        Invalidate();
                    235: }
                    236: 
                    237: // OnSpeed:
                    238: // The ball's speed needs to be changed.  Checkmark the menus, kill the
                    239: // current timer and start a new one at the new speed.
                    240: //
                    241: void CBounceWnd::OnSpeed()
                    242: {
                    243:        CMenu* pMenu = m_pMDIFrameWnd->GetMenu();
                    244:        pMenu->CheckMenuItem(m_nSpeed, MF_UNCHECKED);
                    245: 
                    246:        m_nSpeed = GetCurrentMessage()->wParam;
                    247:        pMenu->CheckMenuItem(m_nSpeed, MF_CHECKED);
                    248: 
                    249:        KillTimer(1);
                    250:        if (!SetTimer(1, (m_nSpeed==IDM_SLOW? 100 : 0), NULL))
                    251:        {
                    252:                MessageBox("Not enough timers available for this window.",
                    253:                                "MDI:Bounce", MB_ICONEXCLAMATION | MB_OK);
                    254: 
                    255:                m_nSpeed = 0;
                    256: 
                    257:                DestroyWindow();
                    258:        }
                    259: }
                    260: 
                    261: // OnTimer:
                    262: // Animate the ball.
                    263: //
                    264: void CBounceWnd::OnTimer(UINT /* wParam */)
                    265: {
                    266:        if (m_pBitmap != NULL)
                    267:        {
                    268:                CDC dcMem;
                    269:                CDC* pdcScreen = NULL;
                    270:                CBitmap* pOldMap = NULL;
                    271: 
                    272:                pdcScreen = GetDC();    
                    273: 
                    274:                dcMem.CreateCompatibleDC(pdcScreen);
                    275: 
                    276:                ASSERT(m_pBitmap->m_hObject != NULL);
                    277: 
                    278:                pOldMap = dcMem.SelectObject(m_pBitmap);
                    279:        
                    280:                pdcScreen->BitBlt(m_xCenter - m_cxTotal / 2,
                    281:                                        m_yCenter - m_cyTotal / 2, m_cxTotal, m_cyTotal,
                    282:                                        &dcMem, 0, 0, SRCCOPY);
                    283:        
                    284:                ReleaseDC(pdcScreen);
                    285:        
                    286:                m_xCenter += m_cxMove;
                    287:                m_yCenter += m_cyMove;
                    288:        
                    289:                if ((m_xCenter + m_cxRadius >= m_cxClient) || 
                    290:                        (m_xCenter - m_cxRadius <= 0))
                    291:                {
                    292:                        m_cxMove = -m_cxMove;
                    293:                }
                    294:        
                    295:                if ((m_yCenter + m_cyRadius >= m_cyClient) || 
                    296:                        (m_yCenter - m_cyRadius <= 0))
                    297:                {
                    298:                        m_cyMove = -m_cyMove;
                    299:                }
                    300:        
                    301:                dcMem.SelectObject(pOldMap);
                    302:                dcMem.DeleteDC();
                    303:        }
                    304: }
                    305: 
                    306: // OnMDIActivate:
                    307: // The current window is being activated or deactivated.  
                    308: // Change MDI frame window menu as appropriate.
                    309: //
                    310: 
                    311: void CBounceWnd::OnMDIActivate(BOOL bActivate, CWnd* /*pActive*/, 
                    312:                                                           CWnd* /*pDeActive*/)
                    313: {
                    314: 
                    315:        CMDIFrameWnd* pFrame = m_pMDIFrameWnd;
                    316:        CMenu* pWinPopupMenu = NULL;
                    317:        CMenu* pMenu = NULL;
                    318: 
                    319:        m_bWindowActive = bActivate;
                    320: 
                    321:        if (bActivate)
                    322:        {
                    323:                pMenu = new CMenu;
                    324:                pMenu->LoadMenu("MdiMenuBounce");
                    325:                pWinPopupMenu = pMenu->GetSubMenu(BOUNCE_MENU_POS);
                    326: 
                    327:                CMenu* pLastMenu = pFrame->MDISetMenu(pMenu, pWinPopupMenu);
                    328:                pLastMenu->DestroyMenu();
                    329: 
                    330:                pMenu->CheckMenuItem(m_nColor, bActivate ? MF_CHECKED : MF_UNCHECKED);
                    331:                pMenu->CheckMenuItem(m_nSpeed, bActivate ? MF_CHECKED : MF_UNCHECKED);
                    332: 
                    333:                delete m_pMenuCurrent;
                    334:                m_pMenuCurrent = pMenu;
                    335: 
                    336:        }
                    337:        else
                    338:        {
                    339:                pMenu = new CMenu;
                    340:                pMenu->LoadMenu("MdiMenuInit");
                    341:                pWinPopupMenu = pMenu->GetSubMenu(INIT_MENU_POS);
                    342: 
                    343:                CMenu* pLastMenu = pFrame->MDISetMenu(pMenu, pWinPopupMenu);
                    344:                pLastMenu->DestroyMenu();
                    345: 
                    346:                delete m_pMenuCurrent;
                    347:                m_pMenuCurrent = pMenu;
                    348:        }
                    349: 
                    350:        pFrame->DrawMenuBar();
                    351: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.