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 / chap10 / polyline / ipolylin.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  11.7 KB  |  560 lines

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