home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap07 / cosmo / cosmo.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  16KB  |  698 lines

  1. /*
  2.  * COSMO.CPP
  3.  * Cosmo Chapter 7
  4.  *
  5.  * WinMain and CCosmoFrame implementations.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13.  
  14.  
  15. //CHAPTER7MOD
  16. #define INITGUIDS
  17. //End CHAPTER7MOD
  18. #include "cosmo.h"
  19.  
  20.  
  21. /*
  22.  * WinMain
  23.  *
  24.  * Purpose:
  25.  *  Main entry point of application.  Should register the app class
  26.  *  if a previous instance has not done so and do any other one-time
  27.  *  initializations.
  28.  */
  29.  
  30. int PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrev
  31.     , LPSTR pszCmdLine, int nCmdShow)
  32.     {
  33.     PCCosmoFrame    pFR;
  34.     FRAMEINIT       fi;
  35.     WPARAM          wRet;
  36.  
  37.     //Attempt to allocate and initialize the application
  38.     pFR=new CCosmoFrame(hInst, hPrev, pszCmdLine, nCmdShow);
  39.  
  40.     if (NULL==pFR)
  41.         return -1;
  42.  
  43.     fi.idsMin=IDS_FRAMEMIN;
  44.     fi.idsMax=IDS_FRAMEMAX;
  45.     fi.idsStatMin=IDS_STATMESSAGEMIN;
  46.     fi.idsStatMax=IDS_STATMESSAGEMAX;
  47.     fi.idStatMenuMin=ID_MENUFILE;
  48.     fi.idStatMenuMax=ID_MENUHELP;
  49.     fi.iPosWindowMenu=WINDOW_MENU;
  50.     fi.cMenus=CMENUS;
  51.  
  52.     fi.x=CW_USEDEFAULT;
  53.     fi.y=CW_USEDEFAULT;
  54.     fi.cx=440;
  55.     fi.cy=460;
  56.  
  57.     //If we can initialize pFR, start chugging messages
  58.     if (pFR->Init(&fi))
  59.         wRet=pFR->MessageLoop();
  60.  
  61.     delete pFR;
  62.     return wRet;
  63.     }
  64.  
  65.  
  66.  
  67.  
  68. /*
  69.  * CCosmoFrame::CCosmoFrame
  70.  * CCosmoFrame::~CCosmoFrame
  71.  *
  72.  * Constructor Parameters:
  73.  *  hInst           HINSTANCE from WinMain
  74.  *  hInstPrev       HINSTANCE from WinMain
  75.  *  pszCmdLine      LPSTR from WinMain
  76.  *  nCmdShow        int from WInMain
  77.  */
  78.  
  79. CCosmoFrame::CCosmoFrame(HINSTANCE hInst, HINSTANCE hInstPrev
  80.     , LPSTR pszCmdLine, int nCmdShow)
  81.     : CFrame(hInst, hInstPrev, pszCmdLine, nCmdShow)
  82.     {
  83.     UINT        i;
  84.  
  85.     for (i=0; i<5; i++)
  86.         m_hBmpLines[i]=NULL;
  87.  
  88.     m_uIDCurLine=0;
  89.  
  90.     //CHAPTER7MOD
  91.     m_fInitialized=FALSE;
  92.     //End CHAPTER7MOD
  93.     return;
  94.     }
  95.  
  96.  
  97. CCosmoFrame::~CCosmoFrame(void)
  98.     {
  99.     UINT        i;
  100.  
  101.     for (i=0; i<5; i++)
  102.         {
  103.         if (NULL!=m_hBmpLines[i])
  104.             DeleteObject(m_hBmpLines[i]);
  105.         }
  106.  
  107.     //CHAPTER7MOD
  108.     if (m_fInitialized)
  109.         CoUninitialize();
  110.     //End CHAPTER7MOD
  111.  
  112.     return;
  113.     }
  114.  
  115.  
  116.  
  117.  
  118. //CHAPTER7MOD
  119. /*
  120.  * CCosmoFrame::Init
  121.  *
  122.  * Purpose:
  123.  *  Call CoInitialize then calling down into the base class
  124.  *  initialization.
  125.  *
  126.  * Parameters:
  127.  *  pFI             PFRAMEINIT containing initialization parameters.
  128.  *
  129.  * Return Value:
  130.  *  BOOL            TRUE if initialization succeeded, FALSE otherwise.
  131.  */
  132.  
  133. BOOL CCosmoFrame::Init(PFRAMEINIT pFI)
  134.     {
  135.     CHECKVER_COM;
  136.  
  137.     if (FAILED(CoInitialize(NULL)))
  138.         return FALSE;
  139.  
  140.     m_fInitialized=TRUE;
  141.  
  142.     return CFrame::Init(pFI);
  143.     }
  144. //End CHAPTER7MOD
  145.  
  146.  
  147.  
  148. /*
  149.  * CCosmoFrame::CreateCClient
  150.  *
  151.  * Purpose:
  152.  *  Constructs a new client specific to the application.
  153.  *
  154.  * Parameters:
  155.  *  None
  156.  *
  157.  * Return Value:
  158.  *  PCClient        Pointer to the new client object.
  159.  */
  160.  
  161. PCClient CCosmoFrame::CreateCClient(void)
  162.     {
  163.     return (PCClient)(new CCosmoClient(m_hInst, this));
  164.     }
  165.  
  166.  
  167.  
  168.  
  169.  
  170. /*
  171.  * CCosmoFrame::RegisterAllClasses
  172.  *
  173.  * Purpose:
  174.  *  Registers all classes used in this application.
  175.  *
  176.  * Parameters:
  177.  *  None
  178.  *
  179.  * Return Value:
  180.  *  BOOL            TRUE if registration succeeded, FALSE otherwise.
  181.  */
  182.  
  183. BOOL CCosmoFrame::RegisterAllClasses(void)
  184.     {
  185.     WNDCLASS        wc;
  186.  
  187.     //First let the standard frame do its thing
  188.     if (!CFrame::RegisterAllClasses())
  189.         return FALSE;
  190.  
  191.     /*
  192.      * We want a different background color for the document
  193.      * because the Polyline we put in the document will paint
  194.      * with COLOR_WINDOW which by default which is CLASSLIB's
  195.      * default document color.
  196.      */
  197.  
  198.     GetClassInfo(m_hInst, SZCLASSDOCUMENT, &wc);
  199.     UnregisterClass(SZCLASSDOCUMENT, m_hInst);
  200.  
  201.     wc.hbrBackground=(HBRUSH)(COLOR_APPWORKSPACE+1);
  202.  
  203.     if (!RegisterClass(&wc))
  204.         return FALSE;
  205.  
  206.     //Register the Polyline window.
  207.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  208.     wc.hInstance     = m_hInst;
  209.     wc.cbClsExtra    = 0;
  210.     wc.lpfnWndProc   = PolylineWndProc;
  211.     wc.cbWndExtra    = CBPOLYLINEWNDEXTRA;
  212.     wc.hIcon         = NULL;
  213.     wc.hCursor       = LoadCursor(NULL, IDC_CROSS);
  214.     wc.hbrBackground = NULL;
  215.     wc.lpszMenuName  = NULL;
  216.     wc.lpszClassName = SZCLASSPOLYLINE;
  217.  
  218.     if (!RegisterClass(&wc))
  219.         return FALSE;
  220.  
  221.     return TRUE;
  222.     }
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229. /*
  230.  * CCosmoFrame::PreShowInit
  231.  *
  232.  * Purpose:
  233.  *  Called from Init before intially showing the window.  We do
  234.  *  whatever else we want here, modifying nCmdShow as necessary
  235.  *  which affects ShowWindow in Init.
  236.  *
  237.  * Parameters:
  238.  *  None
  239.  *
  240.  * Return Value:
  241.  *  BOOL            TRUE if this initialization succeeded,
  242.  *                  FALSE otherwise.
  243.  */
  244.  
  245. BOOL CCosmoFrame::PreShowInit(void)
  246.     {
  247.     CreateLineMenu();
  248.     CheckLineSelection(IDM_LINESOLID);
  249.     return TRUE;
  250.     }
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257. /*
  258.  * CCosmoFrame::CreateLineMenu
  259.  *
  260.  * Purpose:
  261.  *  Initializes the bitmaps used to create the Line menu and
  262.  *  replaces the text items defined in the application resources
  263.  *  with these bitmaps.  Note that the contents of m_hBmpLines
  264.  *  must be cleaned up when the application terminates.
  265.  *
  266.  * Parameters:
  267.  *  None
  268.  *
  269.  * Return Value:
  270.  *  None
  271.  */
  272.  
  273. void CCosmoFrame::CreateLineMenu(void)
  274.     {
  275.     HMENU       hMenu;
  276.     HDC         hDC, hMemDC;
  277.     HPEN        hPen;
  278.     HGDIOBJ     hObj;
  279.     TEXTMETRIC  tm;
  280.     UINT        i, cx, cy;
  281.  
  282.  
  283.     hMenu=GetSubMenu(GetMenu(m_hWnd), 3);   //Line menu.
  284.     hDC=GetDC(m_hWnd);
  285.  
  286.     //Create each line in a menu item 8 chars wide, one char high.
  287.     GetTextMetrics(hDC, &tm);
  288.     cx=tm.tmAveCharWidth*8;
  289.     cy=tm.tmHeight;
  290.  
  291.     /*
  292.      * Create a memory DC in which to draw lines, and bitmaps
  293.      * for each line.
  294.      */
  295.     hMemDC=CreateCompatibleDC(hDC);
  296.     ReleaseDC(m_hWnd, hDC);
  297.  
  298.     for (i=0; i<5; i++)
  299.         {
  300.         m_hBmpLines[i]=CreateCompatibleBitmap(hMemDC, cx, cy);
  301.         SelectObject(hMemDC, m_hBmpLines[i]);
  302.  
  303.         PatBlt(hMemDC, 0, 0, cx, cy, WHITENESS);
  304.  
  305.         hPen=CreatePen(i, 1, 0L);       //i=line style like PS_SOLID
  306.         hObj=SelectObject(hMemDC, hPen);
  307.  
  308.         MoveToEx(hMemDC, 0, cy/2, NULL);
  309.         LineTo(hMemDC, cx, cy/2);
  310.  
  311.         ModifyMenu(hMenu, IDM_LINEMIN+i, MF_BYCOMMAND | MF_BITMAP
  312.             , IDM_LINEMIN+i, (LPTSTR)(LONG)(UINT)m_hBmpLines[i]);
  313.  
  314.         SelectObject(hMemDC, hObj);
  315.         DeleteObject(hPen);
  316.         }
  317.  
  318.     CheckMenuItem(hMenu, IDM_LINESOLID, MF_CHECKED);
  319.     DeleteDC(hMemDC);
  320.  
  321.     return;
  322.     }
  323.  
  324.  
  325.  
  326.  
  327. /*
  328.  * CCosmoFrame::CreateToolbar
  329.  *
  330.  * Purpose:
  331.  *  Procedure to create all the necessary toolbar buttons.
  332.  *
  333.  * Parameters:
  334.  *  None
  335.  *
  336.  * Return Value:
  337.  *  UINT            Number of tools added to the bar.
  338.  */
  339.  
  340. UINT CCosmoFrame::CreateToolbar(void)
  341.     {
  342.     UINT            iLast;
  343.     UINT            uState=GIZMO_NORMAL;
  344.     UINT            utCmd =GIZMOTYPE_BUTTONCOMMAND;
  345.     UINT            utEx  =GIZMOTYPE_BUTTONATTRIBUTEEX;
  346.  
  347.     //Insert the standard ones.
  348.     iLast=CFrame::CreateToolbar();
  349.  
  350.     /*
  351.      * Insert File Import in the 5th position and account for
  352.      * it in iLast.
  353.      */
  354.     m_pTB->Add(utCmd, 4, IDM_FILEIMPORT, m_dxB, m_dyB
  355.         , NULL, m_hBmp, 2, uState);
  356.     iLast++;
  357.  
  358.     //Separator
  359.     m_pTB->Add(GIZMOTYPE_SEPARATOR, iLast++, 0, 6, m_dyB
  360.         , NULL, NULL, 0, uState);
  361.  
  362.     /*
  363.      * For the Background bitmap, preserve our use of black
  364.      * (part of the image)
  365.      */
  366.     m_pTB->Add(utCmd, iLast++, IDM_COLORBACKGROUND, m_dxB, m_dyB
  367.         , NULL, m_hBmp, 3, GIZMO_NORMAL | PRESERVE_BLACK);
  368.  
  369.     m_pTB->Add(utCmd, iLast++, IDM_COLORLINE, m_dxB, m_dyB
  370.         , NULL, m_hBmp, 4, uState);
  371.  
  372.     //Separator
  373.     m_pTB->Add(GIZMOTYPE_SEPARATOR, iLast++, 0, 6, m_dyB
  374.         , NULL, NULL, 0, uState);
  375.  
  376.     //Line styles.
  377.     m_pTB->Add(utEx, iLast++, IDM_LINESOLID, m_dxB, m_dyB
  378.         , NULL, m_hBmp, 5, uState);
  379.     m_pTB->Add(utEx, iLast++, IDM_LINEDASH, m_dxB, m_dyB
  380.         , NULL, m_hBmp, 6, uState);
  381.     m_pTB->Add(utEx, iLast++, IDM_LINEDOT, m_dxB, m_dyB
  382.         , NULL, m_hBmp, 7, uState);
  383.     m_pTB->Add(utEx, iLast++, IDM_LINEDASHDOT, m_dxB, m_dyB
  384.         , NULL, m_hBmp, 8, uState);
  385.     m_pTB->Add(utEx, iLast++, IDM_LINEDASHDOTDOT, m_dxB, m_dyB
  386.         , NULL, m_hBmp, 9, uState);
  387.  
  388.     return iLast;
  389.     }
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398. /*
  399.  * CCosmoFrame::OnCommand
  400.  *
  401.  * Purpose:
  402.  *  WM_COMMAND handler for the Cosmo frame window that just
  403.  *  processes the line menu and the color menu leaving the
  404.  *  CFrame to do everything else.
  405.  *
  406.  * Parameters:
  407.  *  hWnd            HWND of the frame window.
  408.  *  wParam          WPARAM of the message.
  409.  *  lParam          LPARAM of the message.
  410.  *
  411.  * Return Value:
  412.  *  LRESULT         Return value for the message.
  413.  */
  414.  
  415. LRESULT CCosmoFrame::OnCommand(HWND hWnd, WPARAM wParam
  416.     , LPARAM lParam)
  417.     {
  418.     PCCosmoDoc      pDoc;
  419.     TCHAR           szFile[CCHPATHMAX];
  420.     BOOL            fOK;
  421.     UINT            i, uTemp;
  422.     COLORREF        rgColors[16];
  423.     CHOOSECOLOR     cc;
  424.  
  425.     COMMANDPARAMS(wID, wCode, hWndMsg);
  426.  
  427.     /*
  428.      * Don't bother with anything during first initialization,
  429.      * skipping many toolbar notifications.
  430.      */
  431.     if (m_fInit)
  432.         return 0L;
  433.  
  434.     pDoc=(PCCosmoDoc)m_pCL->ActiveDocument();
  435.  
  436.     /*
  437.      * Check for the line style commands which are
  438.      * IDM_LINEMIN+<style>.  We handle this by changing the menu
  439.      * and toolbar, then we pass it to the document for real
  440.      * processing.
  441.      */
  442.     if (NULL!=pDoc && IDM_LINEMIN <= wID && IDM_LINEMAX >=wID)
  443.         {
  444.         CheckLineSelection(wID);
  445.         pDoc->LineStyleSet(wID-IDM_LINEMIN);
  446.         return 0L;
  447.         }
  448.  
  449.     switch (wID)
  450.         {
  451.         case IDM_FILEIMPORT:
  452.             szFile[0]=0;
  453.             fOK=SaveOpenDialog(szFile, CCHPATHMAX, IDS_FILEIMPORT
  454.                 , TRUE, &i);
  455.  
  456.             if (fOK)
  457.                 {
  458.                 uTemp=pDoc->Load(FALSE, szFile);
  459.                 pDoc->ErrorMessage(uTemp);
  460.                 }
  461.  
  462.             return (LRESULT)fOK;
  463.  
  464.  
  465.         case IDM_COLORBACKGROUND:
  466.         case IDM_COLORLINE:
  467.             //Invoke the color chooser for either color
  468.             uTemp=(IDM_COLORBACKGROUND==wID)
  469.                 ? DOCCOLOR_BACKGROUND : DOCCOLOR_LINE;
  470.  
  471.             for (i=0; i<16; i++)
  472.                 rgColors[i]=RGB(0, 0, i*16);
  473.  
  474.             memset(&cc, 0, sizeof(CHOOSECOLOR));
  475.             cc.lStructSize=sizeof(CHOOSECOLOR);
  476.             cc.lpCustColors=rgColors;
  477.             cc.hwndOwner=hWnd;
  478.             cc.Flags=CC_RGBINIT;
  479.             cc.rgbResult=pDoc->ColorGet(uTemp);
  480.  
  481.             if (ChooseColor(&cc))
  482.                 pDoc->ColorSet(uTemp, cc.rgbResult);
  483.  
  484.             break;
  485.  
  486.  
  487.         default:
  488.            CFrame::OnCommand(hWnd, wParam, lParam);
  489.         }
  490.  
  491.     return 0L;
  492.     }
  493.  
  494.  
  495.  
  496.  
  497.  
  498.  
  499. /*
  500.  * CCosmoFrame::OnDocumentDataChange
  501.  *
  502.  * Purpose:
  503.  *  Update the Line menu and toolbar if the style in the data
  504.  *  changes.
  505.  *
  506.  * Parameters:
  507.  *  pDoc            PCDocument notifying the sink.
  508.  *
  509.  * Return Value:
  510.  *  None
  511.  */
  512.  
  513. void CCosmoFrame::OnDocumentDataChange(PCDocument pDoc)
  514.     {
  515.     CheckLineSelection(IDM_LINEMIN
  516.         +((PCCosmoDoc)pDoc)->LineStyleGet());
  517.     return;
  518.     }
  519.  
  520.  
  521.  
  522.  
  523. /*
  524.  * CCosmoFrame::OnDocumentActivate
  525.  *
  526.  * Purpose:
  527.  *  Informs us that document activation changed, so update the UI
  528.  *  for that new document.
  529.  *
  530.  * Parameters:
  531.  *  pDoc            PCDocument notifying the sink.
  532.  *
  533.  * Return Value:
  534.  *  None
  535.  */
  536.  
  537. void CCosmoFrame::OnDocumentActivate(PCDocument pDoc)
  538.     {
  539.     CheckLineSelection(IDM_LINEMIN
  540.         +((PCCosmoDoc)pDoc)->LineStyleGet());
  541.     return;
  542.     }
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550. /*
  551.  * CCosmoFrame::UpdateMenus
  552.  *
  553.  * Purpose:
  554.  *  Handles the WM_INITMENU message for the frame window.  Depending
  555.  *  on the existence of an active window, menu items are selectively
  556.  *  enabled and disabled.
  557.  *
  558.  * Parameters:
  559.  *  hMenu           HMENU of the menu to intialize
  560.  *  iMenu           UINT position of the menu.
  561.  *
  562.  * Return Value:
  563.  *  None
  564.  */
  565.  
  566. void CCosmoFrame::UpdateMenus(HMENU hMenu, UINT iMenu)
  567.     {
  568.     PCDocument  pDoc;
  569.     BOOL        fOK=FALSE;
  570.     BOOL        fCallDefault=TRUE;
  571.     UINT        i;
  572.     UINT        uTemp;
  573.     UINT        uTempE;
  574.     UINT        uTempD;
  575.  
  576.     pDoc=m_pCL->ActiveDocument();
  577.  
  578.     uTempE=MF_ENABLED | MF_BYCOMMAND;
  579.     uTempD=MF_DISABLED | MF_GRAYED | MF_BYCOMMAND;
  580.     uTemp=((NULL!=pDoc) ? uTempE : uTempD);
  581.  
  582.     //File menu:  If there is document window, disable Import.
  583.     if (m_phMenu[0]==hMenu)
  584.         EnableMenuItem(hMenu, IDM_FILEIMPORT, uTemp);
  585.  
  586.     //Color menu:  no document, no commands
  587.     if (m_phMenu[2]==hMenu)
  588.         {
  589.         EnableMenuItem(hMenu, IDM_COLORBACKGROUND, uTemp);
  590.         EnableMenuItem(hMenu, IDM_COLORLINE,       uTemp);
  591.         fCallDefault=FALSE;
  592.         }
  593.  
  594.     //Line menu:  no document, no commands
  595.     if (m_phMenu[3]==hMenu)
  596.         {
  597.         for (i=IDM_LINEMIN; i<=IDM_LINEMAX; i++)
  598.             EnableMenuItem(hMenu, i, uTemp);
  599.  
  600.         fCallDefault=FALSE;
  601.         }
  602.  
  603.     if (fCallDefault)
  604.         CFrame::UpdateMenus(hMenu, iMenu);
  605.  
  606.     return;
  607.     }
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614. /*
  615.  * CCosmoFrame::UpdateToolbar
  616.  *
  617.  * Purpose:
  618.  *  Enables and disables tools depending on whether we have
  619.  *  a document or not.
  620.  *
  621.  * Parameters:
  622.  *  None
  623.  *
  624.  * Return Value:
  625.  *  None
  626.  */
  627.  
  628. void CCosmoFrame::UpdateToolbar(void)
  629.     {
  630.     BOOL        fLast;
  631.     UINT        i;
  632.  
  633.     //Save the last enabled state before CFrame changes it
  634.     fLast=m_fLastEnable;
  635.  
  636.     //Let the default hack on its tools
  637.     CFrame::UpdateToolbar();
  638.  
  639.     /*
  640.      * If CFrame::UpdateToolbar changed anything, then we need
  641.      * to change as well--if nothing changes, nothing to do.
  642.      */
  643.     if (fLast!=m_fLastEnable)
  644.         {
  645.         m_pTB->Enable(IDM_FILEIMPORT, m_fLastEnable);
  646.  
  647.         m_pTB->Enable(IDM_COLORBACKGROUND, m_fLastEnable);
  648.         m_pTB->Enable(IDM_COLORLINE,       m_fLastEnable);
  649.  
  650.         for (i=IDM_LINEMIN; i <= IDM_LINEMAX; i++)
  651.             m_pTB->Enable(i, m_fLastEnable);
  652.         }
  653.  
  654.     return;
  655.     }
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662. /*
  663.  * CCosmoFrame::CheckLineSelection
  664.  *
  665.  * Purpose:
  666.  *  Maintains the bitmap menu and the tools for the line selection.
  667.  *  Both are mutially exclusive option lists where a selection in
  668.  *  one has to affect the other.
  669.  *
  670.  * Parameters:
  671.  *  uID             UINT ID of the item to be selected
  672.  *
  673.  * Return Value:
  674.  *  None
  675.  */
  676.  
  677. void CCosmoFrame::CheckLineSelection(UINT uID)
  678.     {
  679.     UINT        i;
  680.     HMENU       hMenu;
  681.  
  682.     //Update menus and tools if the selection changed.
  683.     if (uID!=m_uIDCurLine)
  684.         {
  685.         m_uIDCurLine=uID;
  686.         hMenu=GetMenu(m_hWnd);
  687.  
  688.         //Uncheck all lines initially.
  689.         for (i=IDM_LINEMIN; i<=IDM_LINEMAX; i++)
  690.             CheckMenuItem(hMenu, i, MF_UNCHECKED | MF_BYCOMMAND);
  691.  
  692.         CheckMenuItem(hMenu, uID, MF_CHECKED | MF_BYCOMMAND);
  693.         m_pTB->Check(uID, TRUE);
  694.         }
  695.  
  696.     return;
  697.     }
  698.