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

  1. /*
  2.  * IPOLYLIN.CPP
  3.  * Polyline Component Chapter 24
  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.     if (NULL!=m_pObj->m_hWnd)
  132.         {
  133.         GetClientRect(m_pObj->m_hWnd, &rc);
  134.         RECTTORECTS(rc, ppl->rc);
  135.         }
  136.     else
  137.         {
  138.         SetRect(&rc, 0, 0, 100, 100);       //Something reasonable
  139.         RECTTORECTS(rc, ppl->rc);
  140.         }
  141.  
  142.     //Clean out the POLYLINEDATA structure and repaint the window.
  143.     for (i=0; i< CPOLYLINEPOINTS; i++)
  144.         {
  145.         ppl->rgpt[i].x=0;
  146.         ppl->rgpt[i].y=0;
  147.         }
  148.  
  149.     ppl->cPoints      =0;
  150.     ppl->rgbBackground=GetSysColor(COLOR_WINDOW);
  151.     ppl->rgbLine      =GetSysColor(COLOR_WINDOWTEXT);
  152.     ppl->iLineStyle   =PS_SOLID;
  153.  
  154.     //This is now conditional since we may not yet have a window.
  155.     if (NULL!=m_pObj->m_hWnd)
  156.         {
  157.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  158.         UpdateWindow(m_pObj->m_hWnd);
  159.         m_pObj->m_fDirty=TRUE;
  160.         }
  161.  
  162.     m_pObj->SendAdvise(OBJECTCODE_DATACHANGED);
  163.     return NOERROR;
  164.     }
  165.  
  166.  
  167.  
  168.  
  169.  
  170.  
  171. /*
  172.  * CImpIPolyline::Undo
  173.  *
  174.  * Purpose:
  175.  *  Reverses previous actions in a Polyline.
  176.  *
  177.  * Parameters:
  178.  *  None
  179.  *
  180.  * Return Value:
  181.  *  HRESULT         S_OK if we can Undo more, S_FALSE otherwise.
  182.  */
  183.  
  184. STDMETHODIMP CImpIPolyline::Undo(void)
  185.     {
  186.     SCODE           sc;
  187.  
  188.     //Decrement the number of active points and repaint.
  189.     if (m_pObj->m_pl.cPoints > 0)
  190.         {
  191.         m_pObj->m_pl.cPoints--;
  192.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  193.         UpdateWindow(m_pObj->m_hWnd);
  194.         }
  195.  
  196.     if (NULL!=m_pObj->m_pAdv)
  197.         {
  198.         m_pObj->m_fDirty=TRUE;
  199.         m_pObj->m_pAdv->OnPointChange();
  200.         }
  201.  
  202.     m_pObj->SendAdvise(OBJECTCODE_DATACHANGED);
  203.  
  204.     //Return if we can undo any more.
  205.     sc=(0!=m_pObj->m_pl.cPoints) ? S_OK : S_FALSE;
  206.     return ResultFromScode(sc);
  207.     }
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214. /*
  215.  * CImpIPolyline::Window
  216.  *
  217.  * Purpose:
  218.  *  Returns the window handle associated with this polyline.
  219.  *
  220.  * Parameters:
  221.  *  phWnd           HWND * in which to return the window handle.
  222.  *
  223.  * Return Value:
  224.  *  HRESULT         NOERROR always.
  225.  */
  226.  
  227. STDMETHODIMP CImpIPolyline::Window(HWND *phWnd)
  228.     {
  229.     *phWnd=m_pObj->m_hWnd;
  230.     return NOERROR;
  231.     }
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238. /*
  239.  * CImpIPolyline::RectGet
  240.  *
  241.  * Purpose:
  242.  *  Returns the rectangle of the Polyline in parent coordinates.
  243.  *
  244.  * Parameters:
  245.  *  pRect           LPRECT in which to return the rectangle.
  246.  *
  247.  * Return Value:
  248.  *  HRESULT         NOERROR always
  249.  */
  250.  
  251. STDMETHODIMP CImpIPolyline::RectGet(LPRECT pRect)
  252.     {
  253.     RECT            rc;
  254.     POINT           pt;
  255.  
  256.     if (NULL==m_pObj->m_hWnd)
  257.         {
  258.         SetRect(pRect, 0, 0, 150, 150); //Reasonable default
  259.         return NOERROR;
  260.         }
  261.  
  262.     //Retrieve the size of our rectangle in parent coordinates.
  263.     GetWindowRect(m_pObj->m_hWnd, &rc);
  264.     pt.x=rc.left;
  265.     pt.y=rc.top;
  266.     ScreenToClient(GetParent(m_pObj->m_hWnd), &pt);
  267.  
  268.     SetRect(pRect, pt.x, pt.y, pt.x+(rc.right-rc.left)
  269.         , pt.y+(rc.bottom-rc.top));
  270.  
  271.     return NOERROR;
  272.     }
  273.  
  274.  
  275.  
  276.  
  277.  
  278. /*
  279.  * CImpIPolyline::SizeGet
  280.  *
  281.  * Purpose:
  282.  *  Retrieves the size of the Polyline in parent coordinates.
  283.  *
  284.  * Parameters:
  285.  *  pRect           LPRECT in which to return the size.  The right
  286.  *                  and bottom fields will contain the dimensions.
  287.  *
  288.  * Return Value:
  289.  *  HRESULT         NOERROR always
  290.  */
  291.  
  292. STDMETHODIMP CImpIPolyline::SizeGet(LPRECT pRect)
  293.     {
  294.     RectGet(pRect);
  295.     return NOERROR;
  296.     }
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303. /*
  304.  * CImpIPolyline::RectSet
  305.  *
  306.  * Purpose:
  307.  *  Sets a new rectangle for the Polyline which sizes to fit.
  308.  *
  309.  * Parameters:
  310.  *  pRect           LPRECT containing the new rectangle.
  311.  *  fNotify         BOOL indicating if we're to notify anyone of
  312.  *                  the change.
  313.  *
  314.  * Return Value:
  315.  *  HRESULT         NOERROR always
  316.  */
  317.  
  318. STDMETHODIMP CImpIPolyline::RectSet(LPRECT pRect, BOOL fNotify)
  319.     {
  320.     UINT            cx, cy;
  321.     RECT            rc;
  322.  
  323.     //Scale the points from our current size to the new size
  324.     cx=pRect->right-pRect->left;
  325.     cy=pRect->bottom-pRect->top;
  326.  
  327.     SetRect(&rc, 0, 0, cx, cy);
  328.     RECTTORECTS(rc, m_pObj->m_pl.rc);
  329.  
  330.     if (NULL!=m_pObj->m_hWnd)
  331.         {
  332.         SetWindowPos(m_pObj->m_hWnd, NULL, pRect->left, pRect->top
  333.             , cx, cy, SWP_NOZORDER);
  334.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  335.         }
  336.  
  337.     if (fNotify && NULL!=m_pObj->m_pAdv)
  338.         {
  339.         m_pObj->m_fDirty=TRUE;
  340.         m_pObj->m_pAdv->OnSizeChange();
  341.         }
  342.  
  343.     return NOERROR;
  344.     }
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352. /*
  353.  * CImpIPolyline::SizeSet
  354.  *
  355.  * Purpose:
  356.  *  Sets a new size for the Polyline which sizes to fit.
  357.  *
  358.  * Parameters:
  359.  *  pRect           LPRECT containing the new rectangle.
  360.  *  fNotify         BOOL indicating if we're to notify anyone of
  361.  *                  the change.
  362.  *
  363.  * Return Value:
  364.  *  HRESULT         NOERROR always
  365.  */
  366.  
  367. STDMETHODIMP CImpIPolyline::SizeSet(LPRECT pRect, BOOL fNotify)
  368.     {
  369.     UINT            cx, cy;
  370.  
  371.     //Scale the points from our current size to the new size
  372.     cx=pRect->right-pRect->left;
  373.     cy=pRect->bottom-pRect->top;
  374.  
  375.     if (NULL!=m_pObj->m_hWnd)
  376.         {
  377.         SetWindowPos(m_pObj->m_hWnd, NULL, 0, 0, (UINT)cx, (UINT)cy
  378.             , SWP_NOMOVE | SWP_NOZORDER);
  379.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  380.         }
  381.  
  382.     if (fNotify && NULL!=m_pObj->m_pAdv)
  383.         {
  384.         m_pObj->m_fDirty=TRUE;
  385.         m_pObj->m_pAdv->OnSizeChange();
  386.         }
  387.  
  388.     return NOERROR;
  389.     }
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396. /*
  397.  * CImpIPolyline::ColorSet
  398.  *
  399.  * Purpose:
  400.  *  Changes for background or line color in the Polyline
  401.  *
  402.  * Parameters:
  403.  *  iColor          UINT index of the color to change.
  404.  *  cr              COLORREF new color to use.
  405.  *  pcrPrev         COLORREF * in whch to store the
  406.  *                  previous color.
  407.  *
  408.  * Return Value:
  409.  *  HRESULT         NOERROR if successful, otherwise a
  410.  *                  POLYLINE_E_ value.
  411.  */
  412.  
  413. STDMETHODIMP CImpIPolyline::ColorSet(UINT iColor, COLORREF cr
  414.     , COLORREF *pcrPrev)
  415.     {
  416.     COLORREF        crRet;
  417.  
  418.     if (NULL==pcrPrev)
  419.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  420.  
  421.     switch (iColor)
  422.         {
  423.         case POLYLINECOLOR_BACKGROUND:
  424.             crRet=m_pObj->m_pl.rgbBackground;
  425.             m_pObj->m_pl.rgbBackground=cr;
  426.             break;
  427.  
  428.         case POLYLINECOLOR_LINE:
  429.             crRet=m_pObj->m_pl.rgbLine;
  430.             m_pObj->m_pl.rgbLine=cr;
  431.             break;
  432.         }
  433.  
  434.     //If the color changed, repaint
  435.     if (crRet!=cr)
  436.         {
  437.         if (NULL!=m_pObj->m_pAdv)
  438.             {
  439.             m_pObj->m_fDirty=TRUE;
  440.             m_pObj->m_pAdv->OnColorChange();
  441.             }
  442.  
  443.         InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  444.         UpdateWindow(m_pObj->m_hWnd);
  445.  
  446.         m_pObj->SendAdvise(OBJECTCODE_DATACHANGED);
  447.         }
  448.  
  449.     *pcrPrev=crRet;
  450.     return NOERROR;
  451.     }
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459. /*
  460.  * CImpIPolyline::ColorGet
  461.  *
  462.  * Purpose:
  463.  *  Retrieves one of the colors currently in use by the Polyline.
  464.  *
  465.  * Parameters:
  466.  *  iColor          UINT identifying the color of interest.
  467.  *  pcr             COLORREF * in which to return the color.
  468.  *
  469.  * Return Value:
  470.  *  HRESULT         NOERROR if successful, otherwise a
  471.  *                  POLYLINE_E_ value.
  472.  */
  473.  
  474. STDMETHODIMP CImpIPolyline::ColorGet(UINT iColor, COLORREF *pcr)
  475.     {
  476.     COLORREF        crRet;
  477.  
  478.     if (NULL==pcr)
  479.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  480.  
  481.     crRet=(POLYLINECOLOR_BACKGROUND==iColor)
  482.         ? m_pObj->m_pl.rgbBackground : m_pObj->m_pl.rgbLine;
  483.  
  484.     *pcr=crRet;
  485.     return NOERROR;
  486.     }
  487.  
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
  494.  
  495. /*
  496.  * CImpIPolyline::LineStyleSet
  497.  *
  498.  * Purpose:
  499.  *  Changes the line style in use by the Polyline
  500.  *
  501.  * Parameters:
  502.  *  iStyle          UINT style of the line to use.
  503.  *  piPrev          UINT * in which to store the previous style.
  504.  *
  505.  * Return Value:
  506.  *  HRESULT         NOERROR if successful, otherwise a
  507.  *                  POLYLINE_E_ value.
  508.  */
  509.  
  510. STDMETHODIMP CImpIPolyline::LineStyleSet(UINT iStyle, UINT *piPrev)
  511.     {
  512.     UINT            uRet;
  513.  
  514.     uRet=(UINT)m_pObj->m_pl.iLineStyle;
  515.  
  516.     if (NULL==piPrev)
  517.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  518.  
  519.     //Validate the line style
  520.     if (PS_SOLID==iStyle || PS_DASH==iStyle || PS_DOT==iStyle
  521.         || PS_DASHDOT==iStyle || PS_DASHDOTDOT==iStyle)
  522.         {
  523.         m_pObj->m_pl.iLineStyle=iStyle;
  524.  
  525.         if (uRet!=(UINT)m_pObj->m_pl.iLineStyle)
  526.             {
  527.             if (NULL!=m_pObj->m_pAdv)
  528.                 {
  529.                 m_pObj->m_fDirty=TRUE;
  530.                 m_pObj->m_pAdv->OnLineStyleChange();
  531.                 }
  532.  
  533.             InvalidateRect(m_pObj->m_hWnd, NULL, TRUE);
  534.             UpdateWindow(m_pObj->m_hWnd);
  535.  
  536.             m_pObj->SendAdvise(OBJECTCODE_DATACHANGED);
  537.             }
  538.         }
  539.  
  540.     *piPrev=uRet;
  541.     return NOERROR;
  542.     }
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550. /*
  551.  * CImpIPolyline::LineStyleGet
  552.  *
  553.  * Purpose:
  554.  *  Retrieves the current line style in use in the Polyline
  555.  *
  556.  * Parameters:
  557.  *  piStyle         UINT * in which to store the style.
  558.  *
  559.  * Return Value:
  560.  *  HRESULT         NOERROR if successful, otherwise a
  561.  *                  POLYLINE_E_ value.
  562.  */
  563.  
  564. STDMETHODIMP CImpIPolyline::LineStyleGet(UINT *piStyle)
  565.     {
  566.     if (NULL==piStyle)
  567.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  568.  
  569.     *piStyle=m_pObj->m_pl.iLineStyle;
  570.     return NOERROR;
  571.     }
  572.