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 / chap23 / cosmo / cosmo.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  25.2 KB  |  1,070 lines

  1. /*
  2.  * COSMO.CPP
  3.  * Cosmo Chapter 23
  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. #define INITGUIDS
  16. #include "cosmo.h"
  17.  
  18. /*
  19.  * These are for proper implementation of the class factory,
  20.  * OLE Documents support, and shutdown conditions.
  21.  */
  22. ULONG g_cObj=0;
  23. ULONG g_cLock=0;
  24. HWND  g_hWnd=NULL;
  25. BOOL  g_fUser=FALSE;
  26.  
  27.  
  28. //CHAPTER23MOD
  29. //This is filled by CFigure on in-place activation
  30. PCToolBar  g_pInPlaceTB=NULL;
  31. //End CHAPTER23MOD
  32.  
  33.  
  34. /*
  35.  * WinMain
  36.  *
  37.  * Purpose:
  38.  *  Main entry point of application.  Should register the app class
  39.  *  if a previous instance has not done so and do any other one-time
  40.  *  initializations.
  41.  */
  42.  
  43. int PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrev
  44.     , LPSTR pszCmdLine, int nCmdShow)
  45.     {
  46.     PCCosmoFrame    pFR;
  47.     FRAMEINIT       fi;
  48.     WPARAM          wRet;
  49.  
  50.     SETMESSAGEQUEUE;
  51.  
  52.     //Attempt to allocate and initialize the application
  53.     pFR=new CCosmoFrame(hInst, hPrev, pszCmdLine, nCmdShow);
  54.  
  55.     if (NULL==pFR)
  56.         return -1;
  57.  
  58.     fi.idsMin=IDS_FRAMEMIN;
  59.     fi.idsMax=IDS_FRAMEMAX;
  60.     fi.idsStatMin=IDS_STATMESSAGEMIN;
  61.     fi.idsStatMax=IDS_STATMESSAGEMAX;
  62.     fi.idStatMenuMin=ID_MENUFILE;
  63.     fi.idStatMenuMax=ID_MENUHELP;
  64.     fi.iPosWindowMenu=WINDOW_MENU;
  65.     fi.cMenus=CMENUS;
  66.  
  67.     fi.x=CW_USEDEFAULT;
  68.     fi.y=CW_USEDEFAULT;
  69.     fi.cx=440;
  70.     fi.cy=460;
  71.  
  72.     //If we can initialize pFR, start chugging messages
  73.     if (pFR->Init(&fi))
  74.         wRet=pFR->MessageLoop();
  75.  
  76.     delete pFR;
  77.     return wRet;
  78.     }
  79.  
  80.  
  81.  
  82. /*
  83.  * ObjectDestroyed
  84.  *
  85.  * Purpose:
  86.  *  Function for the Cosmo Figure object to call when it gets
  87.  *  destroyed.  We destroy the main window if the proper conditions
  88.  *  are met for shutdown.
  89.  */
  90.  
  91. void ObjectDestroyed(void)
  92.     {
  93.     g_cObj--;
  94.  
  95.     //No more objects, no locks, no user control, shut the app down.
  96.     if (0L==g_cObj && 0L==g_cLock && IsWindow(g_hWnd) && !g_fUser)
  97.         PostMessage(g_hWnd, WM_CLOSE, 0, 0L);
  98.  
  99.     return;
  100.     }
  101.  
  102.  
  103.  
  104.  
  105.  
  106. /*
  107.  * CCosmoFrame::CCosmoFrame
  108.  * CCosmoFrame::~CCosmoFrame
  109.  *
  110.  * Constructor Parameters:
  111.  *  hInst           HINSTANCE from WinMain
  112.  *  hInstPrev       HINSTANCE from WinMain
  113.  *  pszCmdLine      LPSTR from WinMain
  114.  *  nCmdShow        int from WInMain
  115.  */
  116.  
  117. CCosmoFrame::CCosmoFrame(HINSTANCE hInst, HINSTANCE hInstPrev
  118.     , LPSTR pszCmdLine, int nCmdShow)
  119.     : CFrame(hInst, hInstPrev, pszCmdLine, nCmdShow)
  120.     {
  121.     UINT        i;
  122.  
  123.     for (i=0; i<5; i++)
  124.         m_hBmpLines[i]=NULL;
  125.  
  126.     m_uIDCurLine=0;
  127.     m_fInitialized=FALSE;
  128.     m_pIClassDataTran=NULL;
  129.  
  130.     m_fEmbedding=FALSE;
  131.     m_dwRegCO=0;
  132.     m_pIClassFactory=NULL;
  133.  
  134.     //CHAPTER23MOD
  135.     m_pIOleIPFrame=NULL;    //Flag for in-place or not.
  136.     //End CHAPTER23MOD
  137.  
  138.     return;
  139.     }
  140.  
  141.  
  142. CCosmoFrame::~CCosmoFrame(void)
  143.     {
  144.     UINT        i;
  145.  
  146.     //Reverse CoRegisterClassObject, takes class factory ref to 1
  147.     if (0L!=m_dwRegCO)
  148.         CoRevokeClassObject(m_dwRegCO);
  149.  
  150.     ReleaseInterface(m_pIClassFactory);
  151.  
  152.     for (i=0; i<5; i++)
  153.         {
  154.         if (NULL!=m_hBmpLines[i])
  155.             DeleteObject(m_hBmpLines[i]);
  156.         }
  157.  
  158.     if (NULL!=m_pIClassDataTran)
  159.         {
  160.         m_pIClassDataTran->LockServer(FALSE);
  161.         m_pIClassDataTran->Release();
  162.         }
  163.  
  164.     OleFlushClipboard();
  165.  
  166.     if (m_fInitialized)
  167.         OleUninitialize();
  168.  
  169.     return;
  170.     }
  171.  
  172.  
  173.  
  174.  
  175. /*
  176.  * CCosmoFrame::Init
  177.  *
  178.  * Purpose:
  179.  *  Call CoInitialize then calling down into the base class
  180.  *  initialization.
  181.  *
  182.  * Parameters:
  183.  *  pFI             PFRAMEINIT containing initialization parameters.
  184.  *
  185.  * Return Value:
  186.  *  BOOL            TRUE if initialization succeeded, FALSE otherwise.
  187.  */
  188.  
  189. BOOL CCosmoFrame::Init(PFRAMEINIT pFI)
  190.     {
  191.     HRESULT     hr;
  192.  
  193.     CHECKVER_OLE;
  194.  
  195.     if (FAILED(OleInitialize(NULL)))
  196.         return FALSE;
  197.  
  198.     m_fInitialized=TRUE;
  199.  
  200.     hr=CoGetClassObject(CLSID_DataTransferObject
  201.         , CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory
  202.         , (PPVOID)&m_pIClassDataTran);
  203.  
  204.     if (SUCCEEDED(hr))
  205.         m_pIClassDataTran->LockServer(TRUE);
  206.  
  207.  
  208.     //Check for command line flags
  209.     ParseCommandLine();
  210.  
  211.     if (NULL!=m_ppszCmdArgs)
  212.         {
  213.         if(0==lstrcmpi(m_ppszCmdArgs[0], TEXT("-Embedding"))
  214.            || 0==lstrcmpi(m_ppszCmdArgs[0], TEXT("/Embedding")))
  215.             m_fEmbedding=TRUE;
  216.         }
  217.  
  218.     g_fUser=!m_fEmbedding;
  219.  
  220.  
  221.     /*
  222.      * Create our class factory and register it for this application
  223.      * using CoRegisterClassObject.  The REGCLS_*USE flags have to
  224.      * do with servicable object from this instance, not with MDI or
  225.      * SDI.  Since it's most convenient to be single use, we'll do
  226.      * this in either version.
  227.      *
  228.      * In addition, it only makes sense to do any of this if we're
  229.      * being launched to be a server.
  230.      */
  231.     if (m_fEmbedding)
  232.         {
  233.         m_pIClassFactory=new CFigureClassFactory(this);
  234.  
  235.         if (NULL==m_pIClassFactory)
  236.             return FALSE;
  237.  
  238.         //Since we hold on to this, we should AddRef it.
  239.         m_pIClassFactory->AddRef();
  240.  
  241.         hr=CoRegisterClassObject(CLSID_CosmoFigure, m_pIClassFactory
  242.             , CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &m_dwRegCO);
  243.  
  244.         if (FAILED(hr))
  245.             return FALSE;
  246.         }
  247.  
  248.     return CFrame::Init(pFI);
  249.     }
  250.  
  251.  
  252.  
  253. //CHAPTER23MOD
  254.  
  255. /*
  256.  * CCosmoFrame::MessageLoop
  257.  *
  258.  * Purpose:
  259.  *  Override of standard message loop function in CLASSLIB to use
  260.  *  in-place accelerators when necessary.  We only need to make
  261.  *  sure we call OleTranslateAccelerator as appropriate.
  262.  *
  263.  * Parameters:
  264.  *  None
  265.  *
  266.  * Return Value:
  267.  *  WPARAM          Contents of msg.wParam from WM_QUIT.
  268.  */
  269.  
  270. WPARAM CCosmoFrame::MessageLoop(void)
  271.     {
  272.     MSG     msg;
  273.  
  274.     while (GetMessage(&msg, NULL, 0,0 ))
  275.         {
  276.         //If we're in-place, don't bother with MDI accelerators
  277.         if (NULL==m_pIOleIPFrame)
  278.             {
  279.             if (m_pCL->TranslateAccelerator(&msg))
  280.                 continue;
  281.             }
  282.  
  283.         //Translate our accelerators.
  284.         if (TranslateAccelerator(m_hWnd, m_hAccel, &msg))
  285.             continue;
  286.  
  287.         /*
  288.          * Let the container have a crack during in-place.  Note
  289.          * that if we were an MDI multiple-use server, which we
  290.          * are not, then we'd have to make sure that the document
  291.          * with the in-place object was active, and we would
  292.          * have to make sure that we use the right IOleInPlaceFrame
  293.          * and frame info variables.  So what's shown here is a
  294.          * somewhat simplified case.
  295.          */
  296.         if (NULL!=m_pIOleIPFrame)
  297.             {
  298.             if (NOERROR==OleTranslateAccelerator(m_pIOleIPFrame
  299.                 , &m_frameInfo, &msg))
  300.                 continue;
  301.             }
  302.  
  303.         TranslateMessage(&msg);
  304.         DispatchMessage(&msg);
  305.         }
  306.  
  307.     return msg.wParam;
  308.     }
  309.  
  310.  
  311.  
  312.  
  313.  
  314. /*
  315.  * CCosmoFrame::FMessageHook
  316.  *
  317.  * Purpose:
  318.  *  Override of CFrame::FMessageHook so we can specifically trap
  319.  *  WM_MENUSELECT messages in order to call
  320.  *  IOleInPlaceFrame::SetStatusText.
  321.  *
  322.  * Parameters:
  323.  *  <WndProc Parameters>
  324.  *  pLRes           LRESULT * in which to store the return
  325.  *                  value for the message.
  326.  *
  327.  * Return Value:
  328.  *  BOOL            TRUE to prevent further processing,
  329.  *                  FALSE otherwise.
  330.  */
  331.  
  332. BOOL CCosmoFrame::FMessageHook(HWND hWnd, UINT iMsg
  333.     , WPARAM wParam, LPARAM lParam, LRESULT *pLRes)
  334.     {
  335.     TCHAR           szText[128];
  336.  
  337.     if (WM_MENUSELECT!=iMsg)
  338.         return FALSE;
  339.  
  340.     if (NULL==m_pIOleIPFrame)
  341.         return FALSE;
  342.  
  343.     /*
  344.      * We have to now get the message that the StatStrip would
  345.      * display for this menu over to the container.  We do this
  346.      * by letting the StatStrip do its thing first on our currently
  347.      * hidden window (beware of this technique if you are multiple
  348.      * use and might be visible!) then we ask the StatStrip for its
  349.      * current text which we send to the container via
  350.      * IOleInPlaceFrame::SetStatusText.
  351.      */
  352.  
  353.     m_pSL->MenuSelect(wParam, lParam);
  354.     m_pSL->MessageGet(szText, sizeof(szText));
  355.    #ifdef WIN32ANSI
  356.     OLECHAR     szTemp[128];
  357.  
  358.     MultiByteToWideChar(CP_ACP, 0, szText, -1, szTemp, 128);
  359.     m_pIOleIPFrame->SetStatusText(szTemp);
  360.    #else
  361.     m_pIOleIPFrame->SetStatusText(szText);
  362.    #endif
  363.  
  364.     *pLRes=0L;
  365.     return TRUE;
  366.     }
  367.  
  368.  
  369. //End CHAPTER23MOD
  370.  
  371.  
  372.  
  373.  
  374. /*
  375.  * CCosmoFrame::CreateCClient
  376.  *
  377.  * Purpose:
  378.  *  Constructs a new client specific to the application.
  379.  *
  380.  * Parameters:
  381.  *  None
  382.  *
  383.  * Return Value:
  384.  *  PCClient        Pointer to the new client object.
  385.  */
  386.  
  387. PCClient CCosmoFrame::CreateCClient(void)
  388.     {
  389.     return (PCClient)(new CCosmoClient(m_hInst, this));
  390.     }
  391.  
  392.  
  393.  
  394.  
  395.  
  396. /*
  397.  * CCosmoFrame::RegisterAllClasses
  398.  *
  399.  * Purpose:
  400.  *  Registers all classes used in this application.
  401.  *
  402.  * Parameters:
  403.  *  None
  404.  *
  405.  * Return Value:
  406.  *  BOOL            TRUE if registration succeeded, FALSE otherwise.
  407.  */
  408.  
  409. BOOL CCosmoFrame::RegisterAllClasses(void)
  410.     {
  411.     WNDCLASS        wc;
  412.  
  413.     //First let the standard frame do its thing
  414.     if (!CFrame::RegisterAllClasses())
  415.         return FALSE;
  416.  
  417.     /*
  418.      * We want a different background color for the document
  419.      * because the Polyline we put in the document will paint
  420.      * with COLOR_WINDOW which by default which is CLASSLIB's
  421.      * default document color.
  422.      */
  423.  
  424.     GetClassInfo(m_hInst, SZCLASSDOCUMENT, &wc);
  425.     UnregisterClass(SZCLASSDOCUMENT, m_hInst);
  426.  
  427.     wc.hbrBackground=(HBRUSH)(COLOR_APPWORKSPACE+1);
  428.  
  429.     if (!RegisterClass(&wc))
  430.         return FALSE;
  431.  
  432.     //Register the Polyline window.
  433.     wc.style         = CS_HREDRAW | CS_VREDRAW;
  434.     wc.hInstance     = m_hInst;
  435.     wc.cbClsExtra    = 0;
  436.     wc.lpfnWndProc   = PolylineWndProc;
  437.     wc.cbWndExtra    = CBPOLYLINEWNDEXTRA;
  438.     wc.hIcon         = NULL;
  439.     wc.hCursor       = LoadCursor(NULL, IDC_CROSS);
  440.     wc.hbrBackground = NULL;
  441.     wc.lpszMenuName  = NULL;
  442.     wc.lpszClassName = SZCLASSPOLYLINE;
  443.  
  444.     if (!RegisterClass(&wc))
  445.         return FALSE;
  446.  
  447.     //CHAPTER23MOD
  448.     if (!HatchWindowRegister(m_hInst))
  449.         return FALSE;
  450.     //End CHAPTER23MOD
  451.  
  452.     return TRUE;
  453.     }
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460. /*
  461.  * CCosmoFrame::PreShowInit
  462.  *
  463.  * Purpose:
  464.  *  Called from Init before intially showing the window.  We do
  465.  *  whatever else we want here, modifying nCmdShow as necessary
  466.  *  which affects ShowWindow in Init.
  467.  *
  468.  * Parameters:
  469.  *  None
  470.  *
  471.  * Return Value:
  472.  *  BOOL            TRUE if this initialization succeeded,
  473.  *                  FALSE otherwise.
  474.  */
  475.  
  476. BOOL CCosmoFrame::PreShowInit(void)
  477.     {
  478.     CreateLineMenu();
  479.     CheckLineSelection(IDM_LINESOLID);
  480.  
  481.     //Save the window handle for shutdown if necessary.
  482.     g_hWnd=m_hWnd;
  483.  
  484.     //If we're under OLE control, don't show the main window.
  485.     if (m_fEmbedding)
  486.         m_nCmdShow=SW_HIDE;
  487.  
  488.     return TRUE;
  489.     }
  490.  
  491.  
  492.  
  493. /*
  494.  * CCosmoFrame::CreateLineMenu
  495.  *
  496.  * Purpose:
  497.  *  Initializes the bitmaps used to create the Line menu and
  498.  *  replaces the text items defined in the application resources
  499.  *  with these bitmaps.  Note that the contents of m_hBmpLines
  500.  *  must be cleaned up when the application terminates.
  501.  *
  502.  * Parameters:
  503.  *  None
  504.  *
  505.  * Return Value:
  506.  *  None
  507.  */
  508.  
  509. void CCosmoFrame::CreateLineMenu(void)
  510.     {
  511.     HMENU       hMenu;
  512.     HDC         hDC, hMemDC;
  513.     HPEN        hPen;
  514.     HGDIOBJ     hObj;
  515.     TEXTMETRIC  tm;
  516.     UINT        i, cx, cy;
  517.  
  518.  
  519.     hMenu=GetSubMenu(GetMenu(m_hWnd), 3);   //Line menu.
  520.     hDC=GetDC(m_hWnd);
  521.  
  522.     //Create each line in a menu item 8 chars wide, one char high.
  523.     GetTextMetrics(hDC, &tm);
  524.     cx=tm.tmAveCharWidth*8;
  525.     cy=tm.tmHeight;
  526.  
  527.     /*
  528.      * Create a memory DC in which to draw lines, and bitmaps
  529.      * for each line.
  530.      */
  531.     hMemDC=CreateCompatibleDC(hDC);
  532.     ReleaseDC(m_hWnd, hDC);
  533.  
  534.     for (i=0; i<5; i++)
  535.         {
  536.         m_hBmpLines[i]=CreateCompatibleBitmap(hMemDC, cx, cy);
  537.         SelectObject(hMemDC, m_hBmpLines[i]);
  538.  
  539.         PatBlt(hMemDC, 0, 0, cx, cy, WHITENESS);
  540.  
  541.         hPen=CreatePen(i, 1, 0L);       //i=line style like PS_SOLID
  542.         hObj=SelectObject(hMemDC, hPen);
  543.  
  544.         MoveToEx(hMemDC, 0, cy/2, NULL);
  545.         LineTo(hMemDC, cx, cy/2);
  546.  
  547.         ModifyMenu(hMenu, IDM_LINEMIN+i, MF_BYCOMMAND | MF_BITMAP
  548.             , IDM_LINEMIN+i, (LPTSTR)(LONG)(UINT)m_hBmpLines[i]);
  549.  
  550.         SelectObject(hMemDC, hObj);
  551.         DeleteObject(hPen);
  552.         }
  553.  
  554.     CheckMenuItem(hMenu, IDM_LINESOLID, MF_CHECKED);
  555.     DeleteDC(hMemDC);
  556.  
  557.     return;
  558.     }
  559.  
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567.  
  568. /*
  569.  * CCosmoFrame::CreateToolbar
  570.  *
  571.  * Purpose:
  572.  *  Procedure to create all the necessary toolbar buttons.
  573.  *
  574.  * Parameters:
  575.  *  None
  576.  *
  577.  * Return Value:
  578.  *  UINT            Number of tools added to the bar.
  579.  */
  580.  
  581. UINT CCosmoFrame::CreateToolbar(void)
  582.     {
  583.     UINT            iLast;
  584.     UINT            uState=GIZMO_NORMAL;
  585.     UINT            utCmd =GIZMOTYPE_BUTTONCOMMAND;
  586.     UINT            utEx  =GIZMOTYPE_BUTTONATTRIBUTEEX;
  587.  
  588.     //Insert the standard ones.
  589.     iLast=CFrame::CreateToolbar();
  590.  
  591.     /*
  592.      * Insert File Import in the 5th position and account for
  593.      * it in iLast.
  594.      */
  595.     m_pTB->Add(utCmd, 4, IDM_FILEIMPORT, m_dxB, m_dyB
  596.         , NULL, m_hBmp, 2, uState);
  597.     iLast++;
  598.  
  599.     //Separator
  600.     m_pTB->Add(GIZMOTYPE_SEPARATOR, iLast++, 0, 6, m_dyB
  601.         , NULL, NULL, 0, uState);
  602.  
  603.     /*
  604.      * For the Background bitmap, preserve our use of black
  605.      * (part of the image)
  606.      */
  607.     m_pTB->Add(utCmd, iLast++, IDM_COLORBACKGROUND, m_dxB, m_dyB
  608.         , NULL, m_hBmp, 3, GIZMO_NORMAL | PRESERVE_BLACK);
  609.  
  610.     m_pTB->Add(utCmd, iLast++, IDM_COLORLINE, m_dxB, m_dyB
  611.         , NULL, m_hBmp, 4, uState);
  612.  
  613.     //Separator
  614.     m_pTB->Add(GIZMOTYPE_SEPARATOR, iLast++, 0, 6, m_dyB
  615.         , NULL, NULL, 0, uState);
  616.  
  617.     //Line styles.
  618.     m_pTB->Add(utEx, iLast++, IDM_LINESOLID, m_dxB, m_dyB
  619.         , NULL, m_hBmp, 5, uState);
  620.     m_pTB->Add(utEx, iLast++, IDM_LINEDASH, m_dxB, m_dyB
  621.         , NULL, m_hBmp, 6, uState);
  622.     m_pTB->Add(utEx, iLast++, IDM_LINEDOT, m_dxB, m_dyB
  623.         , NULL, m_hBmp, 7, uState);
  624.     m_pTB->Add(utEx, iLast++, IDM_LINEDASHDOT, m_dxB, m_dyB
  625.         , NULL, m_hBmp, 8, uState);
  626.     m_pTB->Add(utEx, iLast++, IDM_LINEDASHDOTDOT, m_dxB, m_dyB
  627.         , NULL, m_hBmp, 9, uState);
  628.  
  629.     return iLast;
  630.     }
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639. /*
  640.  * CCosmoFrame::OnCommand
  641.  *
  642.  * Purpose:
  643.  *  WM_COMMAND handler for the Cosmo frame window that just
  644.  *  processes the line menu and the color menu leaving the
  645.  *  CFrame to do everything else.
  646.  *
  647.  * Parameters:
  648.  *  hWnd            HWND of the frame window.
  649.  *  wParam          WPARAM of the message.
  650.  *  lParam          LPARAM of the message.
  651.  *
  652.  * Return Value:
  653.  *  LRESULT         Return value for the message.
  654.  */
  655.  
  656. LRESULT CCosmoFrame::OnCommand(HWND hWnd, WPARAM wParam
  657.     , LPARAM lParam)
  658.     {
  659.     PCCosmoDoc      pDoc;
  660.     TCHAR           szFile[CCHPATHMAX];
  661.     BOOL            fOK;
  662.     UINT            i, uTemp;
  663.     COLORREF        rgColors[16];
  664.     CHOOSECOLOR     cc;
  665.  
  666.     COMMANDPARAMS(wID, wCode, hWndMsg);
  667.  
  668.     /*
  669.      * Don't bother with anything during first initialization,
  670.      * skipping many toolbar notifications.
  671.      */
  672.     if (m_fInit)
  673.         return 0L;
  674.  
  675.     pDoc=(PCCosmoDoc)m_pCL->ActiveDocument();
  676.  
  677.     /*
  678.      * Check for the line style commands which are
  679.      * IDM_LINEMIN+<style>.  We handle this by changing the menu
  680.      * and toolbar, then we pass it to the document for real
  681.      * processing.
  682.      */
  683.     if (NULL!=pDoc && IDM_LINEMIN <= wID && IDM_LINEMAX >=wID)
  684.         {
  685.         CheckLineSelection(wID);
  686.         pDoc->LineStyleSet(wID-IDM_LINEMIN);
  687.         return 0L;
  688.         }
  689.  
  690.     switch (wID)
  691.         {
  692.         case IDM_FILEIMPORT:
  693.             szFile[0]=0;
  694.             fOK=SaveOpenDialog(szFile, CCHPATHMAX, IDS_FILEIMPORT
  695.                 , TRUE, &i);
  696.  
  697.             if (fOK)
  698.                 {
  699.                 uTemp=pDoc->Load(FALSE, szFile);
  700.                 pDoc->ErrorMessage(uTemp);
  701.                 }
  702.  
  703.             return (LRESULT)fOK;
  704.  
  705.  
  706.         case IDM_COLORBACKGROUND:
  707.         case IDM_COLORLINE:
  708.             //Invoke the color chooser for either color
  709.             uTemp=(IDM_COLORBACKGROUND==wID)
  710.                 ? DOCCOLOR_BACKGROUND : DOCCOLOR_LINE;
  711.  
  712.             for (i=0; i<16; i++)
  713.                 rgColors[i]=RGB(0, 0, i*16);
  714.  
  715.             memset(&cc, 0, sizeof(CHOOSECOLOR));
  716.             cc.lStructSize=sizeof(CHOOSECOLOR);
  717.             cc.lpCustColors=rgColors;
  718.  
  719.             //CHAPTER23MOD
  720.             /*
  721.              * If we're in-place active, use the container's frame
  722.              * window instead of our own as the parent of the dialog.
  723.              */
  724.             if (NULL!=m_pIOleIPFrame)
  725.                 m_pIOleIPFrame->GetWindow(&cc.hwndOwner);
  726.             else
  727.                 cc.hwndOwner=hWnd;
  728.             //End CHAPTER23MOD
  729.  
  730.             cc.Flags=CC_RGBINIT;
  731.             cc.rgbResult=pDoc->ColorGet(uTemp);
  732.  
  733.             if (ChooseColor(&cc))
  734.                 pDoc->ColorSet(uTemp, cc.rgbResult);
  735.  
  736.             break;
  737.  
  738.         //CHAPTER23MOD
  739.         case ID_HATCHWINDOW:
  740.             //Open the in-place object on hatch border double-click.
  741.             if (HWN_BORDERDOUBLECLICKED==wCode)
  742.                 pDoc->OpenInPlaceObject();
  743.  
  744.             break;
  745.  
  746.         case IDM_EDITOPEN:
  747.             //Invoke the OPEN verb on the current object.
  748.             pDoc->OpenInPlaceObject();
  749.             break;
  750.         //End CHAPTER23MOD
  751.  
  752.         default:
  753.            CFrame::OnCommand(hWnd, wParam, lParam);
  754.         }
  755.  
  756.     return 0L;
  757.     }
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764. /*
  765.  * CCosmoFrame::OnDocumentDataChange
  766.  *
  767.  * Purpose:
  768.  *  Update the Line menu and toolbar if the style in the data
  769.  *  changes.
  770.  *
  771.  * Parameters:
  772.  *  pDoc            PCDocument notifying the sink.
  773.  *
  774.  * Return Value:
  775.  *  None
  776.  */
  777.  
  778. void CCosmoFrame::OnDocumentDataChange(PCDocument pDoc)
  779.     {
  780.     CheckLineSelection(IDM_LINEMIN
  781.         +((PCCosmoDoc)pDoc)->LineStyleGet());
  782.     return;
  783.     }
  784.  
  785.  
  786.  
  787.  
  788. /*
  789.  * CCosmoFrame::OnDocumentActivate
  790.  *
  791.  * Purpose:
  792.  *  Informs us that document activation changed, so update the UI
  793.  *  for that new document.
  794.  *
  795.  * Parameters:
  796.  *  pDoc            PCDocument notifying the sink.
  797.  *
  798.  * Return Value:
  799.  *  None
  800.  */
  801.  
  802. void CCosmoFrame::OnDocumentActivate(PCDocument pDoc)
  803.     {
  804.     CheckLineSelection(IDM_LINEMIN
  805.         +((PCCosmoDoc)pDoc)->LineStyleGet());
  806.     return;
  807.     }
  808.  
  809.  
  810.  
  811.  
  812.  
  813.  
  814.  
  815. /*
  816.  * CCosmoFrame::UpdateMenus
  817.  *
  818.  * Purpose:
  819.  *  Handles the WM_INITMENU message for the frame window.  Depending
  820.  *  on the existence of an active window, menu items are selectively
  821.  *  enabled and disabled.
  822.  *
  823.  * Parameters:
  824.  *  hMenu           HMENU of the menu to intialize
  825.  *  iMenu           UINT position of the menu.
  826.  *
  827.  * Return Value:
  828.  *  None
  829.  */
  830.  
  831. void CCosmoFrame::UpdateMenus(HMENU hMenu, UINT iMenu)
  832.     {
  833.     PCDocument  pDoc;
  834.     BOOL        fOK=FALSE;
  835.     BOOL        fCallDefault=TRUE;
  836.     UINT        i;
  837.     UINT        uTemp;
  838.     UINT        uTempE;
  839.     UINT        uTempD;
  840.  
  841.     pDoc=m_pCL->ActiveDocument();
  842.  
  843.     uTempE=MF_ENABLED | MF_BYCOMMAND;
  844.     uTempD=MF_DISABLED | MF_GRAYED | MF_BYCOMMAND;
  845.     uTemp=((NULL!=pDoc) ? uTempE : uTempD);
  846.  
  847.     //File menu:  If there is document window, disable Import.
  848.     if (m_phMenu[0]==hMenu)
  849.         EnableMenuItem(hMenu, IDM_FILEIMPORT, uTemp);
  850.  
  851.     //Color menu:  no document, no commands
  852.     if (m_phMenu[2]==hMenu)
  853.         {
  854.         EnableMenuItem(hMenu, IDM_COLORBACKGROUND, uTemp);
  855.         EnableMenuItem(hMenu, IDM_COLORLINE,       uTemp);
  856.         fCallDefault=FALSE;
  857.         }
  858.  
  859.     //Line menu:  no document, no commands
  860.     if (m_phMenu[3]==hMenu)
  861.         {
  862.         for (i=IDM_LINEMIN; i<=IDM_LINEMAX; i++)
  863.             EnableMenuItem(hMenu, i, uTemp);
  864.  
  865.         fCallDefault=FALSE;
  866.         }
  867.  
  868.     if (fCallDefault)
  869.         CFrame::UpdateMenus(hMenu, iMenu);
  870.  
  871.     return;
  872.     }
  873.  
  874.  
  875.  
  876.  
  877.  
  878.  
  879. /*
  880.  * CCosmoFrame::UpdateToolbar
  881.  *
  882.  * Purpose:
  883.  *  Enables and disables tools depending on whether we have
  884.  *  a document or not.
  885.  *
  886.  * Parameters:
  887.  *  None
  888.  *
  889.  * Return Value:
  890.  *  None
  891.  */
  892.  
  893. void CCosmoFrame::UpdateToolbar(void)
  894.     {
  895.     BOOL        fLast;
  896.     UINT        i;
  897.  
  898.     //Save the last enabled state before CFrame changes it
  899.     fLast=m_fLastEnable;
  900.  
  901.     //Let the default hack on its tools
  902.     CFrame::UpdateToolbar();
  903.  
  904.     /*
  905.      * If CFrame::UpdateToolbar changed anything, then we need
  906.      * to change as well--if nothing changes, nothing to do.
  907.      */
  908.     if (fLast!=m_fLastEnable)
  909.         {
  910.         m_pTB->Enable(IDM_FILEIMPORT, m_fLastEnable);
  911.  
  912.         m_pTB->Enable(IDM_COLORBACKGROUND, m_fLastEnable);
  913.         m_pTB->Enable(IDM_COLORLINE,       m_fLastEnable);
  914.  
  915.         for (i=IDM_LINEMIN; i <= IDM_LINEMAX; i++)
  916.             m_pTB->Enable(i, m_fLastEnable);
  917.         }
  918.  
  919.     return;
  920.     }
  921.  
  922.  
  923.  
  924.  
  925.  
  926.  
  927. /*
  928.  * CCosmoFrame::CheckLineSelection
  929.  *
  930.  * Purpose:
  931.  *  Maintains the bitmap menu and the tools for the line selection.
  932.  *  Both are mutially exclusive option lists where a selection in
  933.  *  one has to affect the other.
  934.  *
  935.  * Parameters:
  936.  *  uID             UINT ID of the item to be selected
  937.  *
  938.  * Return Value:
  939.  *  None
  940.  */
  941.  
  942. void CCosmoFrame::CheckLineSelection(UINT uID)
  943.     {
  944.     UINT        i;
  945.     HMENU       hMenu;
  946.  
  947.     //Update menus and tools if the selection changed.
  948.     if (uID!=m_uIDCurLine)
  949.         {
  950.         m_uIDCurLine=uID;
  951.  
  952.         //CHAPTER23MOD
  953.         /*
  954.          * Should only check on the popup, not on the main menu since it
  955.          * could be a shared menu at the moment.
  956.          */
  957.         hMenu=m_phMenu[3];
  958.         //End CHAPTER23MOD
  959.  
  960.         //Uncheck all lines initially.
  961.         for (i=IDM_LINEMIN; i<=IDM_LINEMAX; i++)
  962.             CheckMenuItem(hMenu, i, MF_UNCHECKED | MF_BYCOMMAND);
  963.  
  964.         CheckMenuItem(hMenu, uID, MF_CHECKED | MF_BYCOMMAND);
  965.         m_pTB->Check(uID, TRUE);
  966.  
  967.         //CHAPTER23MOD
  968.         //Affect in-place toolbar as well
  969.         if (NULL!=g_pInPlaceTB)
  970.             g_pInPlaceTB->Check(uID, TRUE);
  971.         //End CHAPTER23MOD
  972.         }
  973.  
  974.     return;
  975.     }
  976.  
  977.  
  978.  
  979. /*
  980.  * CCosmoFrame::UpdateEmbeddingUI
  981.  *
  982.  * Purpose:
  983.  *  Puts the application into the user interface for editing an
  984.  *  embedded object, manipulating menus and title bars.
  985.  *
  986.  * Parameters:
  987.  *  fEmbedding      BOOL TRUE to go in the mode, FALSE to leave it.
  988.  *  pszApp          LPCTSTR name of the container application as
  989.  *                  received in IOleObject::SetHostNames.
  990.  *  pszObj          LPCTSTR name of the object in the container as
  991.  *                  received in IOleObject::SetHostNames.
  992.  *
  993.  * Return Value:
  994.  *  None
  995.  */
  996.  
  997. void CCosmoFrame::UpdateEmbeddingUI(BOOL fEmbedding
  998.     , PCDocument pDoc, LPCTSTR pszApp, LPCTSTR pszObj)
  999.     {
  1000.     HMENU           hMenu;
  1001.     TCHAR           szTemp[256];
  1002.  
  1003.     //First let's play with the File menu.
  1004.     hMenu=m_phMenu[0];
  1005.  
  1006.     //Remove or add the File New, Open, and Save items
  1007.     if (fEmbedding)
  1008.         {
  1009.         DeleteMenu(m_phMenu[0], IDM_FILENEW,   MF_BYCOMMAND);
  1010.         DeleteMenu(m_phMenu[0], IDM_FILEOPEN,  MF_BYCOMMAND);
  1011.         DeleteMenu(m_phMenu[0], IDM_FILECLOSE, MF_BYCOMMAND);
  1012.         DeleteMenu(m_phMenu[0], IDM_FILESAVE,  MF_BYCOMMAND);
  1013.  
  1014.         //Save As->Save Copy As
  1015.         ModifyMenu(m_phMenu[0], IDM_FILESAVEAS, MF_BYCOMMAND
  1016.             , IDM_FILESAVEAS, PSZ(IDS_SAVECOPYAS));
  1017.         }
  1018.     else
  1019.         {
  1020.         InsertMenu(m_phMenu[0], 0, MF_BYPOSITION, IDM_FILENEW
  1021.             , PSZ(IDS_NEW));
  1022.         InsertMenu(m_phMenu[0], 1, MF_BYPOSITION, IDM_FILEOPEN
  1023.             , PSZ(IDS_OPEN));
  1024.         InsertMenu(m_phMenu[0], 2, MF_BYPOSITION, IDM_FILESAVE
  1025.             , PSZ(IDS_SAVE));
  1026.         InsertMenu(m_phMenu[0], 3, MF_BYPOSITION, IDM_FILECLOSE
  1027.             , PSZ(IDS_SAVE));
  1028.  
  1029.         //Save Copy As->Save As
  1030.         ModifyMenu(m_phMenu[0], IDM_FILESAVEAS, MF_BYCOMMAND
  1031.             , IDM_FILESAVEAS, PSZ(IDS_SAVEAS));
  1032.         }
  1033.  
  1034.     //Change "Exit" to "Exit & Return to xx" or vice-versa for SDI
  1035.     if (fEmbedding)
  1036.         wsprintf(szTemp, PSZ(IDS_EXITANDRETURN), (LPSTR)pszObj);
  1037.     else
  1038.         lstrcpy(szTemp, PSZ(IDS_EXIT));
  1039.  
  1040.     ModifyMenu(m_phMenu[0], IDM_FILEEXIT, MF_STRING, IDM_FILEEXIT
  1041.         , szTemp);
  1042.     DrawMenuBar(m_hWnd);
  1043.  
  1044.     //Now let's play with the toolbar.
  1045.     m_pTB->Show(IDM_FILENEW,   !fEmbedding);
  1046.     m_pTB->Show(IDM_FILEOPEN,  !fEmbedding);
  1047.     m_pTB->Show(IDM_FILECLOSE, !fEmbedding);
  1048.     m_pTB->Show(IDM_FILESAVE,  !fEmbedding);
  1049.  
  1050.     //Enable what's left appropriately.
  1051.     UpdateToolbar();
  1052.  
  1053.     //Now play with the title bar.
  1054.  
  1055.     //IDS_EMBEDDINGCAPTION is MDI/SDI sensitive in COSMO.RC.
  1056.     wsprintf(szTemp, PSZ(IDS_EMBEDDINGCAPTION), pszObj);
  1057.  
  1058.     /*
  1059.      * Remember that in MDI situations that Windows takes care of
  1060.      * the frame window caption bar when the document is maximized.
  1061.      */
  1062.    #ifdef MDI
  1063.     SetWindowText(pDoc->Window(), szTemp);
  1064.    #else
  1065.     SetWindowText(m_hWnd, szTemp);
  1066.    #endif
  1067.  
  1068.     return;
  1069.     }
  1070.