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 / chap19 / polyline / ipolylin.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  13KB  |  589 lines

  1. /*
  2.  * IPOLYLIN.CPP
  3.  * Polyline Component Chapter 19
  4.  *
  5.  * Implementation of the IPolyline10 interface that we expose on the
  6.  * CPolyline object.
  7.  *
  8.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Microsoft
  11.  * Internet  :  kraigb@microsoft.com
  12.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  13.  */
  14.  
  15.  
  16. #include "polyline.h"
  17.  
  18.  
  19. /*
  20.  * CImpIPolyline:CImpIPolyline
  21.  * CImpIPolyline::~CImpIPolyline
  22.  *
  23.  * Constructor Parameters:
  24.  *  pObj            PCPolyline pointing to the object we live in.
  25.  *  pUnkOuter       LPUNKNOWN of the controlling unknown.
  26.  */
  27.  
  28. CImpIPolyline::CImpIPolyline(PCPolyline pObj, LPUNKNOWN pUnkOuter)
  29.     {
  30.     m_cRef=0;
  31.     m_pObj=pObj;
  32.     m_pUnkOuter=pUnkOuter;
  33.     return;
  34.     }
  35.  
  36.  
  37. CImpIPolyline::~CImpIPolyline(void)
  38.     {
  39.     return;
  40.     }
  41.  
  42.  
  43.  
  44.  
  45. /*
  46.  * CImpIPolyline::QueryInterface
  47.  * CImpIPolyline::AddRef
  48.  * CImpIPolyline::Release
  49.  */
  50.  
  51. STDMETHODIMP CImpIPolyline::QueryInterface(REFIID riid, PPVOID ppv)
  52.     {
  53.     return m_pUnkOuter->QueryInterface(riid, ppv);
  54.     }
  55.  
  56. STDMETHODIMP_(ULONG) CImpIPolyline::AddRef(void)
  57.     {
  58.     ++m_cRef;
  59.     return m_pUnkOuter->AddRef();
  60.     }
  61.  
  62. STDMETHODIMP_(ULONG) CImpIPolyline::Release(void)
  63.     {
  64.     --m_cRef;
  65.     return m_pUnkOuter->Release();
  66.     }
  67.  
  68.  
  69.  
  70.  
  71.  
  72. /*
  73.  * CImpIPolyline::Init
  74.  *
  75.  * Purpose:
  76.  *  Instantiates a polyline window within a given parent.  The
  77.  *  parent may be a main application window, could be an MDI child
  78.  *  window. We really do not care.
  79.  *
  80.  * Parameters:
  81.  *  hWndParent      HWND of the parent of this window
  82.  *  pRect           LPRECT that this window should occupy
  83.  *  dwStyle         DWORD containing the window's style flags
  84.  *  uID             UINT ID to associate with this window
  85.  *
  86.  * Return Value:
  87.  *  HRESULT         NOERROR if successful, otherwise E_OUTOFMEMORY
  88.  */
  89.  
  90. STDMETHODIMP CImpIPolyline::Init(HWND hWndParent, LPRECT pRect
  91.     , DWORD dwStyle, UINT uID)
  92.     {
  93.     SCODE           sc;
  94.  
  95.     m_pObj->m_hWnd=CreateWindowEx(WS_EX_NOPARENTNOTIFY
  96.         , SZCLASSPOLYLINE, SZCLASSPOLYLINE, dwStyle, pRect->left
  97.         , pRect->top, pRect->right-pRect->left
  98.         , pRect->bottom-pRect->top, hWndParent, (HMENU)uID
  99.         , m_pObj->m_hInst, m_pObj);
  100.  
  101.     sc=(NULL!=m_pObj->m_hWnd) ? S_OK : E_OUTOFMEMORY;
  102.     return ResultFromScode(sc);
  103.     }
  104.  
  105.  
  106.  
  107.  
  108. /*
  109.  * CImpIPolyline::New
  110.  *
  111.  * Purpose:
  112.  *  Cleans out and reinitializes the data to defaults.
  113.  *
  114.  * Parameters:
  115.  *  None
  116.  *
  117.  * Return Value:
  118.  *  HRESULT         NOERROR always
  119.  */
  120.  
  121. STDMETHODIMP CImpIPolyline::New(void)
  122.     {
  123.     PPOLYLINEDATA   ppl=&m_pObj->m_pl;
  124.     UINT            i;
  125.     RECT            rc;
  126.  
  127.     ppl->wVerMaj=VERSIONMAJOR;
  128.     ppl->wVerMin=VERSIONMINOR;
  129.  
  130.     //Our rectangle is the size of our window's client area.
  131.     //CHAPTER19MOD
  132.     if (NULL!=m_pObj->m_hWnd)
  133.         {
  134.         GetClientRect(m_pObj->m_hWnd, &rc);
  135.         RECTTORECTS(rc, ppl->rc);
  136.         }
  137.     else
  138.         {
  139.         SetRect(&rc, 0, 0, 100, 100);       //Something reasonable
  140.         RECTTORECTS(rc, ppl->rc);
  141.         }
  142.     //End CHAPTER19MOD
  143.  
  144.     //Clean out the POLYLINEDATA structure and repaint the window.
  145.     for (i=0; i< CPOLYLINEPOINTS; i++)
  146.         {
  147.         ppl->rgpt[i].x=0;
  148.         ppl->rgpt[i].y=0;
  149.         }
  150.  
  151.     ppl->cPoints      =0;
  152.     ppl->rgbBackground=GetSysColor(COLOR_WINDOW);
  153.     ppl->rgbLine      =GetSysColor(COLOR_WINDOWTEXT);
  154.     ppl->iLineStyle   =PS_SOLID;
  155.  
  156.     //CHAPTER19MOD
  157.     //This is now conditional since we may not yet have a window.
  158.     if (NULL!=m_pObj->m_hWnd)
  159.         {
  160.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  161.         UpdateWindow(m_pObj->m_hWnd);
  162.         m_pObj->m_fDirty=TRUE;
  163.         }
  164.  
  165.     m_pObj->SendAdvise(OBJECTCODE_DATACHANGED);
  166.     //End CHAPTER19MOD
  167.  
  168.     return NOERROR;
  169.     }
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176. /*
  177.  * CImpIPolyline::Undo
  178.  *
  179.  * Purpose:
  180.  *  Reverses previous actions in a Polyline.
  181.  *
  182.  * Parameters:
  183.  *  None
  184.  *
  185.  * Return Value:
  186.  *  HRESULT         S_OK if we can Undo more, S_FALSE otherwise.
  187.  */
  188.  
  189. STDMETHODIMP CImpIPolyline::Undo(void)
  190.     {
  191.     SCODE           sc;
  192.  
  193.     //Decrement the number of active points and repaint.
  194.     if (m_pObj->m_pl.cPoints > 0)
  195.         {
  196.         m_pObj->m_pl.cPoints--;
  197.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  198.         UpdateWindow(m_pObj->m_hWnd);
  199.         }
  200.  
  201.     if (NULL!=m_pObj->m_pAdv)
  202.         {
  203.         m_pObj->m_fDirty=TRUE;
  204.         m_pObj->m_pAdv->OnPointChange();
  205.         }
  206.  
  207.     //CHAPTER19MOD
  208.     m_pObj->SendAdvise(OBJECTCODE_DATACHANGED);
  209.     //End CHAPTER19MOD
  210.  
  211.     //Return if we can undo any more.
  212.     sc=(0!=m_pObj->m_pl.cPoints) ? S_OK : S_FALSE;
  213.     return ResultFromScode(sc);
  214.     }
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221. /*
  222.  * CImpIPolyline::Window
  223.  *
  224.  * Purpose:
  225.  *  Returns the window handle associated with this polyline.
  226.  *
  227.  * Parameters:
  228.  *  phWnd           HWND * in which to return the window handle.
  229.  *
  230.  * Return Value:
  231.  *  HRESULT         NOERROR always.
  232.  */
  233.  
  234. STDMETHODIMP CImpIPolyline::Window(HWND *phWnd)
  235.     {
  236.     *phWnd=m_pObj->m_hWnd;
  237.     return NOERROR;
  238.     }
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245. /*
  246.  * CImpIPolyline::RectGet
  247.  *
  248.  * Purpose:
  249.  *  Returns the rectangle of the Polyline in parent coordinates.
  250.  *
  251.  * Parameters:
  252.  *  pRect           LPRECT in which to return the rectangle.
  253.  *
  254.  * Return Value:
  255.  *  HRESULT         NOERROR always
  256.  */
  257.  
  258. STDMETHODIMP CImpIPolyline::RectGet(LPRECT pRect)
  259.     {
  260.     RECT            rc;
  261.     POINT           pt;
  262.  
  263.     //CHAPTER19MOD
  264.     if (NULL==m_pObj->m_hWnd)
  265.         {
  266.         SetRect(pRect, 0, 0, 150, 150); //Reasonable default
  267.         return NOERROR;
  268.         }
  269.     //End CHAPTER19MOD
  270.  
  271.     //Retrieve the size of our rectangle in parent coordinates.
  272.     GetWindowRect(m_pObj->m_hWnd, &rc);
  273.     pt.x=rc.left;
  274.     pt.y=rc.top;
  275.     ScreenToClient(GetParent(m_pObj->m_hWnd), &pt);
  276.  
  277.     SetRect(pRect, pt.x, pt.y, pt.x+(rc.right-rc.left)
  278.         , pt.y+(rc.bottom-rc.top));
  279.  
  280.     return NOERROR;
  281.     }
  282.  
  283.  
  284.  
  285.  
  286.  
  287. /*
  288.  * CImpIPolyline::SizeGet
  289.  *
  290.  * Purpose:
  291.  *  Retrieves the size of the Polyline in parent coordinates.
  292.  *
  293.  * Parameters:
  294.  *  pRect           LPRECT in which to return the size.  The right
  295.  *                  and bottom fields will contain the dimensions.
  296.  *
  297.  * Return Value:
  298.  *  HRESULT         NOERROR always
  299.  */
  300.  
  301. STDMETHODIMP CImpIPolyline::SizeGet(LPRECT pRect)
  302.     {
  303.     RectGet(pRect);
  304.     return NOERROR;
  305.     }
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312. /*
  313.  * CImpIPolyline::RectSet
  314.  *
  315.  * Purpose:
  316.  *  Sets a new rectangle for the Polyline which sizes to fit.
  317.  *
  318.  * Parameters:
  319.  *  pRect           LPRECT containing the new rectangle.
  320.  *  fNotify         BOOL indicating if we're to notify anyone of
  321.  *                  the change.
  322.  *
  323.  * Return Value:
  324.  *  HRESULT         NOERROR always
  325.  */
  326.  
  327. STDMETHODIMP CImpIPolyline::RectSet(LPRECT pRect, BOOL fNotify)
  328.     {
  329.     UINT            cx, cy;
  330.     RECT            rc;
  331.  
  332.     //Scale the points from our current size to the new size
  333.     cx=pRect->right-pRect->left;
  334.     cy=pRect->bottom-pRect->top;
  335.  
  336.     SetRect(&rc, 0, 0, cx, cy);
  337.     RECTTORECTS(rc, m_pObj->m_pl.rc);
  338.  
  339.     //CHPATER19MOD
  340.     if (NULL!=m_pObj->m_hWnd)
  341.         {
  342.         SetWindowPos(m_pObj->m_hWnd, NULL, pRect->left, pRect->top
  343.             , cx, cy, SWP_NOZORDER);
  344.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  345.         }
  346.     //End CHAPTER19MOD
  347.  
  348.     if (fNotify && NULL!=m_pObj->m_pAdv)
  349.         {
  350.         m_pObj->m_fDirty=TRUE;
  351.         m_pObj->m_pAdv->OnSizeChange();
  352.         }
  353.  
  354.     return NOERROR;
  355.     }
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363. /*
  364.  * CImpIPolyline::SizeSet
  365.  *
  366.  * Purpose:
  367.  *  Sets a new size for the Polyline which sizes to fit.
  368.  *
  369.  * Parameters:
  370.  *  pRect           LPRECT containing the new rectangle.
  371.  *  fNotify         BOOL indicating if we're to notify anyone of
  372.  *                  the change.
  373.  *
  374.  * Return Value:
  375.  *  HRESULT         NOERROR always
  376.  */
  377.  
  378. STDMETHODIMP CImpIPolyline::SizeSet(LPRECT pRect, BOOL fNotify)
  379.     {
  380.     UINT            cx, cy;
  381.  
  382.     //Scale the points from our current size to the new size
  383.     cx=pRect->right-pRect->left;
  384.     cy=pRect->bottom-pRect->top;
  385.  
  386.     //CHAPTER19MOD
  387.     if (NULL!=m_pObj->m_hWnd)
  388.         {
  389.         SetWindowPos(m_pObj->m_hWnd, NULL, 0, 0, (UINT)cx, (UINT)cy
  390.             , SWP_NOMOVE | SWP_NOZORDER);
  391.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  392.         }
  393.     //End CHAPTER19MOD
  394.  
  395.     if (fNotify && NULL!=m_pObj->m_pAdv)
  396.         {
  397.         m_pObj->m_fDirty=TRUE;
  398.         m_pObj->m_pAdv->OnSizeChange();
  399.         }
  400.  
  401.     return NOERROR;
  402.     }
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409. /*
  410.  * CImpIPolyline::ColorSet
  411.  *
  412.  * Purpose:
  413.  *  Changes for background or line color in the Polyline
  414.  *
  415.  * Parameters:
  416.  *  iColor          UINT index of the color to change.
  417.  *  cr              COLORREF new color to use.
  418.  *  pcrPrev         COLORREF * in whch to store the
  419.  *                  previous color.
  420.  *
  421.  * Return Value:
  422.  *  HRESULT         NOERROR if successful, otherwise a
  423.  *                  POLYLINE_E_ value.
  424.  */
  425.  
  426. STDMETHODIMP CImpIPolyline::ColorSet(UINT iColor, COLORREF cr
  427.     , COLORREF *pcrPrev)
  428.     {
  429.     COLORREF        crRet;
  430.  
  431.     if (NULL==pcrPrev)
  432.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  433.  
  434.     switch (iColor)
  435.         {
  436.         case POLYLINECOLOR_BACKGROUND:
  437.             crRet=m_pObj->m_pl.rgbBackground;
  438.             m_pObj->m_pl.rgbBackground=cr;
  439.             break;
  440.  
  441.         case POLYLINECOLOR_LINE:
  442.             crRet=m_pObj->m_pl.rgbLine;
  443.             m_pObj->m_pl.rgbLine=cr;
  444.             break;
  445.         }
  446.  
  447.     //If the color changed, repaint
  448.     if (crRet!=cr)
  449.         {
  450.         if (NULL!=m_pObj->m_pAdv)
  451.             {
  452.             m_pObj->m_fDirty=TRUE;
  453.             m_pObj->m_pAdv->OnColorChange();
  454.             }
  455.  
  456.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  457.         UpdateWindow(m_pObj->m_hWnd);
  458.  
  459.         //CHAPTER19MOD
  460.         m_pObj->SendAdvise(OBJECTCODE_DATACHANGED);
  461.         //End CHAPTER19MOD
  462.         }
  463.  
  464.     *pcrPrev=crRet;
  465.     return NOERROR;
  466.     }
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474. /*
  475.  * CImpIPolyline::ColorGet
  476.  *
  477.  * Purpose:
  478.  *  Retrieves one of the colors currently in use by the Polyline.
  479.  *
  480.  * Parameters:
  481.  *  iColor          UINT identifying the color of interest.
  482.  *  pcr             COLORREF * in which to return the color.
  483.  *
  484.  * Return Value:
  485.  *  HRESULT         NOERROR if successful, otherwise a
  486.  *                  POLYLINE_E_ value.
  487.  */
  488.  
  489. STDMETHODIMP CImpIPolyline::ColorGet(UINT iColor, COLORREF *pcr)
  490.     {
  491.     COLORREF        crRet;
  492.  
  493.     if (NULL==pcr)
  494.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  495.  
  496.     crRet=(POLYLINECOLOR_BACKGROUND==iColor)
  497.         ? m_pObj->m_pl.rgbBackground : m_pObj->m_pl.rgbLine;
  498.  
  499.     *pcr=crRet;
  500.     return NOERROR;
  501.     }
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510. /*
  511.  * CImpIPolyline::LineStyleSet
  512.  *
  513.  * Purpose:
  514.  *  Changes the line style in use by the Polyline
  515.  *
  516.  * Parameters:
  517.  *  iStyle          UINT style of the line to use.
  518.  *  piPrev          UINT * in which to store the previous style.
  519.  *
  520.  * Return Value:
  521.  *  HRESULT         NOERROR if successful, otherwise a
  522.  *                  POLYLINE_E_ value.
  523.  */
  524.  
  525. STDMETHODIMP CImpIPolyline::LineStyleSet(UINT iStyle, UINT *piPrev)
  526.     {
  527.     UINT            uRet;
  528.  
  529.     uRet=(UINT)m_pObj->m_pl.iLineStyle;
  530.  
  531.     if (NULL==piPrev)
  532.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  533.  
  534.     //Validate the line style
  535.     if (PS_SOLID==iStyle || PS_DASH==iStyle || PS_DOT==iStyle
  536.         || PS_DASHDOT==iStyle || PS_DASHDOTDOT==iStyle)
  537.         {
  538.         m_pObj->m_pl.iLineStyle=iStyle;
  539.  
  540.         if (uRet!=(UINT)m_pObj->m_pl.iLineStyle)
  541.             {
  542.             if (NULL!=m_pObj->m_pAdv)
  543.                 {
  544.                 m_pObj->m_fDirty=TRUE;
  545.                 m_pObj->m_pAdv->OnLineStyleChange();
  546.                 }
  547.  
  548.             InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  549.             UpdateWindow(m_pObj->m_hWnd);
  550.  
  551.             //CHAPTER19MOD
  552.             m_pObj->SendAdvise(OBJECTCODE_DATACHANGED);
  553.             //End CHAPTER19MOD
  554.             }
  555.         }
  556.  
  557.     *piPrev=uRet;
  558.     return NOERROR;
  559.     }
  560.  
  561.  
  562.  
  563.  
  564.  
  565.  
  566.  
  567. /*
  568.  * CImpIPolyline::LineStyleGet
  569.  *
  570.  * Purpose:
  571.  *  Retrieves the current line style in use in the Polyline
  572.  *
  573.  * Parameters:
  574.  *  piStyle         UINT * in which to store the style.
  575.  *
  576.  * Return Value:
  577.  *  HRESULT         NOERROR if successful, otherwise a
  578.  *                  POLYLINE_E_ value.
  579.  */
  580.  
  581. STDMETHODIMP CImpIPolyline::LineStyleGet(UINT *piStyle)
  582.     {
  583.     if (NULL==piStyle)
  584.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  585.  
  586.     *piStyle=m_pObj->m_pl.iLineStyle;
  587.     return NOERROR;
  588.     }
  589.