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 / chap05 / cocosmo / cocosmo.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  15KB  |  688 lines

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