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

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