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 / chap15 / square / square.cpp < prev    next >
C/C++ Source or Header  |  1995-05-03  |  17KB  |  826 lines

  1. /*
  2.  * SQUARE.CPP
  3.  * Square Rendering/Calculation Automation Object Chapter 15
  4.  *
  5.  * An automation object that draws a square in various rotational
  6.  * states and provides access to it through IDispatch.
  7.  *
  8.  * This file contains all the code for this sample.
  9.  *
  10.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  11.  *
  12.  * Kraig Brockschmidt, Microsoft
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #define INITGUIDS
  19. #include "square.h"
  20.  
  21. ULONG       g_cObj=0;
  22. ULONG       g_cLock=0;
  23. HWND        g_hWnd=NULL;
  24.  
  25.  
  26. /*
  27.  * WinMain
  28.  *
  29.  * Purpose:
  30.  *  Main entry point of application.
  31.  */
  32.  
  33. int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hInstPrev
  34.     , LPSTR pszCmdLine, int nCmdShow)
  35.     {
  36.     MSG         msg;
  37.     PCApp       pApp;
  38.  
  39.     SETMESSAGEQUEUE;
  40.  
  41.     pApp=new CApp(hInst, hInstPrev, pszCmdLine, nCmdShow);
  42.  
  43.     if (NULL==pApp)
  44.         return -1;
  45.  
  46.     if (pApp->Init())
  47.         {
  48.         while (GetMessage(&msg, NULL, 0,0 ))
  49.             {
  50.             TranslateMessage(&msg);
  51.             DispatchMessage(&msg);
  52.             }
  53.         }
  54.  
  55.     delete pApp;
  56.     return msg.wParam;
  57.     }
  58.  
  59.  
  60.  
  61.  
  62.  
  63. /*
  64.  * MainWndProc
  65.  *
  66.  * Purpose:
  67.  *  Standard window class procedure.
  68.  */
  69.  
  70. LRESULT APIENTRY MainWndProc(HWND hWnd, UINT iMsg
  71.     , WPARAM wParam, LPARAM lParam)
  72.     {
  73.     switch (iMsg)
  74.         {
  75.         case WM_DESTROY:
  76.             PostQuitMessage(0);
  77.             break;
  78.  
  79.         default:
  80.             return (DefWindowProc(hWnd, iMsg, wParam, lParam));
  81.         }
  82.  
  83.     return 0L;
  84.     }
  85.  
  86.  
  87.  
  88.  
  89.  
  90. /*
  91.  * ObjectDestroyed
  92.  *
  93.  * Purpose:
  94.  *  Function for the object to call when it gets destroyed.
  95.  *  We destroy the main window if the proper conditions are met
  96.  *  for shutdown.
  97.  */
  98.  
  99. void ObjectDestroyed(void)
  100.     {
  101.     g_cObj--;
  102.  
  103.     //No more objects and no locks, shut the app down.
  104.     if (0L==g_cObj && 0L==g_cLock && IsWindow(g_hWnd))
  105.         PostMessage(g_hWnd, WM_CLOSE, 0, 0L);
  106.  
  107.     return;
  108.     }
  109.  
  110.  
  111.  
  112.  
  113. /*
  114.  * CApp::CApp
  115.  * CApp::~CApp
  116.  *
  117.  * Constructor Parameters:
  118.  *  hInst           HINSTANCE of the Application from WinMain
  119.  *  hInstPrev       HINSTANCE of a previous instance from WinMain
  120.  *  pszCmdLine      LPSTR of the command line.
  121.  *  nCmdShow        UINT specifying how to show the app window,
  122.  *                  from WinMain.
  123.  */
  124.  
  125. CApp::CApp(HINSTANCE hInst, HINSTANCE hInstPrev
  126.     , LPSTR pszCmdLine, UINT nCmdShow)
  127.     {
  128.     //Initialize WinMain parameter holders.
  129.     m_hInst     =hInst;
  130.     m_hInstPrev =hInstPrev;
  131.     m_pszCmdLine=pszCmdLine;
  132.     m_nCmdShow  =nCmdShow;
  133.  
  134.     m_dwRegCO=0;
  135.     m_pIClassFactory=NULL;
  136.     m_fInitialized=FALSE;
  137.     return;
  138.     }
  139.  
  140.  
  141. CApp::~CApp(void)
  142.     {
  143.     //Opposite of CoRegisterClassObject; class factory ref is now 1
  144.     if (0L!=m_dwRegCO)
  145.         CoRevokeClassObject(m_dwRegCO);
  146.  
  147.     //The last Release, which frees the class factory.
  148.     if (NULL!=m_pIClassFactory)
  149.         m_pIClassFactory->Release();
  150.  
  151.     if (m_fInitialized)
  152.         CoUninitialize();
  153.  
  154.     return;
  155.     }
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162. /*
  163.  * CApp::Init
  164.  *
  165.  * Purpose:
  166.  *  Initializes an CApp object by registering window classes,
  167.  *  creating the main window, and doing anything else prone to
  168.  *  failure.  If this function fails the caller should guarantee
  169.  *  that the destructor is called.
  170.  *
  171.  * Return Value:
  172.  *  BOOL            TRUE if successful, FALSE otherwise.
  173.  */
  174.  
  175. BOOL CApp::Init(void)
  176.     {
  177.     WNDCLASS    wc;
  178.     HRESULT     hr;
  179.     HWND        hWnd;
  180.  
  181.     if (lstrcmpiA(m_pszCmdLine, "-Embedding"))
  182.         return FALSE;
  183.  
  184.     CHECKVER_OLE;
  185.  
  186.     if (FAILED(CoInitialize(NULL)))
  187.         return FALSE;
  188.  
  189.     m_fInitialized=TRUE;
  190.  
  191.     if (!m_hInstPrev)
  192.         {
  193.         wc.style          = CS_HREDRAW | CS_VREDRAW;
  194.         wc.lpfnWndProc    = MainWndProc;
  195.         wc.cbClsExtra     = 0;
  196.         wc.cbWndExtra     = 0;
  197.         wc.hInstance      = m_hInst;
  198.         wc.hIcon          = NULL;
  199.         wc.hCursor        = NULL;
  200.         wc.hbrBackground  = (HBRUSH)(COLOR_WINDOW + 1);
  201.         wc.lpszMenuName   = NULL;
  202.         wc.lpszClassName  = TEXT("SphereSquare");
  203.  
  204.         if (!RegisterClass(&wc))
  205.             return FALSE;
  206.  
  207.         //Child window in which to draw
  208.         wc.lpfnWndProc    = SquareWndProc;
  209.         wc.cbWndExtra     = CBSQUAREWNDEXTRA;
  210.         wc.hCursor        = (HCURSOR)LoadCursor(NULL, IDC_ARROW);
  211.         wc.lpszClassName  = SZCLASSSQUARE;
  212.  
  213.         if (!RegisterClass(&wc))
  214.             return FALSE;
  215.  
  216.         }
  217.  
  218.     //This window is never shown
  219.     hWnd=CreateWindow(TEXT("SphereSquare"), TEXT("SphereSquare")
  220.         , WS_OVERLAPPEDWINDOW, 100, 100, 400, 400
  221.         , NULL, NULL, m_hInst, NULL);
  222.  
  223.     if (NULL==hWnd)
  224.         return FALSE;
  225.  
  226.     g_hWnd=hWnd;
  227.  
  228.     m_pIClassFactory=new CSquareClassFactory(hWnd, m_hInst);
  229.  
  230.     if (NULL==m_pIClassFactory)
  231.         return FALSE;
  232.  
  233.     m_pIClassFactory->AddRef();
  234.  
  235.     hr=CoRegisterClassObject(CLSID_SphereSquare, m_pIClassFactory
  236.         , CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &m_dwRegCO);
  237.  
  238.     if (FAILED(hr))
  239.         return FALSE;
  240.  
  241.     return TRUE;
  242.     }
  243.  
  244.  
  245.  
  246. //Class Factory implementation
  247.  
  248.  
  249.  
  250. /*
  251.  * CSquareClassFactory::CSquareClassFactory
  252.  * CSquareClassFactory::~CSquareClassFactory
  253.  *
  254.  * Constructor Parameters:
  255.  *  hWnd            HWND of the application.
  256.  *  hInst           HINSTANCE to pass to objects we create.
  257.  */
  258.  
  259. CSquareClassFactory::CSquareClassFactory(HWND hWnd
  260.     , HINSTANCE hInst)
  261.     {
  262.     m_cRef=0L;
  263.     m_hWnd=hWnd;
  264.     m_hInst=hInst;
  265.     return;
  266.     }
  267.  
  268.  
  269. CSquareClassFactory::~CSquareClassFactory(void)
  270.     {
  271.     return;
  272.     }
  273.  
  274.  
  275.  
  276.  
  277. /*
  278.  * CSquareClassFactory::QueryInterface
  279.  * CSquareClassFactory::AddRef
  280.  * CSquareClassFactory::Release
  281.  */
  282.  
  283. STDMETHODIMP CSquareClassFactory::QueryInterface(REFIID riid
  284.     , PPVOID ppv)
  285.     {
  286.     *ppv=NULL;
  287.  
  288.     if (IID_IUnknown==riid || IID_IClassFactory==riid)
  289.         *ppv=this;
  290.  
  291.     if (NULL!=*ppv)
  292.         {
  293.         ((LPUNKNOWN)*ppv)->AddRef();
  294.         return NOERROR;
  295.         }
  296.  
  297.     return ResultFromScode(E_NOINTERFACE);
  298.     }
  299.  
  300.  
  301. STDMETHODIMP_(ULONG) CSquareClassFactory::AddRef(void)
  302.     {
  303.     return ++m_cRef;
  304.     }
  305.  
  306.  
  307. STDMETHODIMP_(ULONG) CSquareClassFactory::Release(void)
  308.     {
  309.     if (0!=--m_cRef)
  310.         return m_cRef;
  311.  
  312.     delete this;
  313.     return 0;
  314.     }
  315.  
  316.  
  317.  
  318.  
  319. /*
  320.  * CSquareClassFactory::CreateInstance
  321.  * CSquareClassFactory::LockServer
  322.  */
  323.  
  324. STDMETHODIMP CSquareClassFactory::CreateInstance(LPUNKNOWN pUnkOuter
  325.     , REFIID riid, PPVOID ppvObj)
  326.     {
  327.     PCSquare    pObj;
  328.     HRESULT     hr;
  329.  
  330.     *ppvObj=NULL;
  331.  
  332.     if (NULL!=pUnkOuter)
  333.         return ResultFromScode(CLASS_E_NOAGGREGATION);
  334.  
  335.     pObj=new CSquare();
  336.  
  337.     g_cObj++;
  338.     hr=ResultFromScode(E_OUTOFMEMORY);
  339.  
  340.     if (NULL!=pObj)
  341.         {
  342.         if (pObj->Init(m_hWnd, m_hInst))
  343.             {
  344.             hr=pObj->QueryInterface(riid, ppvObj);
  345.             }
  346.         }
  347.  
  348.     if (FAILED(hr))
  349.         {
  350.         if (NULL!=pObj)
  351.             delete pObj;
  352.  
  353.         ObjectDestroyed();
  354.         }
  355.  
  356.     return hr;
  357.     }
  358.  
  359.  
  360.  
  361. STDMETHODIMP CSquareClassFactory::LockServer(BOOL fLock)
  362.     {
  363.     if (fLock)
  364.         g_cLock++;
  365.     else
  366.         {
  367.         g_cLock--;
  368.  
  369.         //Centralizes shutdown in ObjectDestroyed
  370.         g_cObj++;
  371.         ObjectDestroyed();
  372.         }
  373.  
  374.     return NOERROR;
  375.     }
  376.  
  377.  
  378.  
  379. //Object implementation
  380.  
  381.  
  382. /*
  383.  * CSquare::CSquare
  384.  * CSquare::~CSquare
  385.  */
  386.  
  387. CSquare::CSquare(void)
  388.     {
  389.     m_cRef=0;
  390.     m_hWnd=NULL;
  391.  
  392.     m_pITypeInfo=NULL;
  393.     m_pIUnkDisp=NULL;
  394.  
  395.     m_cRadius=100.0;
  396.     m_dDeclin=0.0;
  397.     m_dTheta=0.0;
  398.  
  399.     m_xOrg=(int)(1.5*m_cRadius);
  400.     m_yOrg=m_xOrg;
  401.  
  402.     m_crBack=GetSysColor(COLOR_WINDOW);
  403.     m_crLinePos=RGB(255, 255, 0);
  404.     m_crLineNeg=RGB(255, 0, 0);
  405.     m_hPenPos=NULL;
  406.     m_hPenNeg=NULL;
  407.  
  408.     m_cx=200;
  409.     m_cy=220;
  410.     m_xPos=100;
  411.     m_yPos=100;
  412.  
  413.     return;
  414.     }
  415.  
  416.  
  417. CSquare::~CSquare(void)
  418.     {
  419.     ReleaseInterface(m_pITypeInfo);
  420.     ReleaseInterface(m_pIUnkDisp);
  421.  
  422.     if (NULL!=m_hPenPos)
  423.         DeleteObject(m_hPenPos);
  424.  
  425.     if (NULL!=m_hPenNeg)
  426.         DeleteObject(m_hPenNeg);
  427.  
  428.     if (NULL!=m_hWnd)
  429.         DestroyWindow(m_hWnd);
  430.  
  431.     return;
  432.     }
  433.  
  434.  
  435.  
  436. /*
  437.  * CSquare::Init
  438.  *
  439.  * Purpose:
  440.  *  Creates the window in which we draw.
  441.  */
  442.  
  443. BOOL CSquare::Init(HWND hWndOwner, HINSTANCE hInst)
  444.     {
  445.     ITypeLib       *pITypeLib;
  446.     HRESULT         hr;
  447.  
  448.     //Create both default pens
  449.     CreatePens(TRUE, TRUE);
  450.  
  451.     m_hWnd=CreateWindow(SZCLASSSQUARE, SZCLASSSQUARE
  452.         , WS_CAPTION | WS_POPUP, m_xPos, m_yPos, m_cx, m_cy
  453.         , hWndOwner, NULL, hInst, this);
  454.  
  455.  
  456.     if (NULL==m_hWnd)
  457.         return NULL;
  458.  
  459.  
  460.     if (FAILED(LoadRegTypeLib(LIBID_SphereSquareLibrary, 1, 0
  461.         , LANG_NEUTRAL, &pITypeLib)))
  462.         {
  463.         if (FAILED(LoadTypeLib(OLETEXT("SQUARE.TLB"), &pITypeLib)))
  464.             return FALSE;
  465.         }
  466.  
  467.     hr=pITypeLib->GetTypeInfoOfGuid(IID_ISphereSquare, &m_pITypeInfo);
  468.  
  469.     if (FAILED(hr))
  470.         {
  471.         pITypeLib->Release();
  472.         return FALSE;
  473.         }
  474.  
  475.     hr=CreateStdDispatch((IUnknown *)this, (ISphereSquare *)this
  476.         , m_pITypeInfo, &m_pIUnkDisp);
  477.  
  478.     pITypeLib->Release();
  479.  
  480.     if (FAILED(hr))
  481.         return FALSE;
  482.  
  483.     return TRUE;
  484.     }
  485.  
  486.  
  487.  
  488.  
  489. /*
  490.  * CSquare::CreatePens
  491.  *
  492.  * Purpose:
  493.  *  Creates one or both line color pens
  494.  *
  495.  * Parameters:
  496.  *  fPositive       BOOL instructing us to create positive line color.
  497.  *  fNegative       BOOL instructing us to create negative line color.
  498.  *
  499.  * Return Value:
  500.  *  None
  501.  */
  502.  
  503. void CSquare::CreatePens(BOOL fPositive, BOOL fNegative)
  504.     {
  505.     if (fPositive)
  506.         {
  507.         if (NULL!=m_hPenPos)
  508.             DeleteObject(m_hPenPos);
  509.  
  510.         m_hPenPos=CreatePen(PS_SOLID, 1, m_crLinePos);
  511.  
  512.         if (NULL==m_hPenPos)
  513.             m_hPenPos=(HPEN)GetStockObject(BLACK_PEN);
  514.         }
  515.  
  516.     if (fNegative)
  517.         {
  518.         if (NULL!=m_hPenNeg)
  519.             DeleteObject(m_hPenNeg);
  520.  
  521.         m_hPenNeg=CreatePen(PS_SOLID, 1, m_crLineNeg);
  522.  
  523.         if (NULL==m_hPenNeg)
  524.             m_hPenNeg=(HPEN)GetStockObject(BLACK_PEN);
  525.         }
  526.  
  527.     return;
  528.     }
  529.  
  530.  
  531.  
  532.  
  533. /*
  534.  * CSquare::Draw
  535.  *
  536.  * Purpose:
  537.  *  Draws the image of a square rotated according to m_dDeclin
  538.  *  and m_dTheta with an edge length of m_cRadius.
  539.  *
  540.  * Parameters:
  541.  *  hDC             HDC on which to draw.
  542.  *
  543.  * Return Value;
  544.  *  None
  545.  */
  546.  
  547. void CSquare::Draw(HDC hDC)
  548.     {
  549.     POINT           pt[5];
  550.     int             x, y;
  551.     double          rad;
  552.     RECT            rc;
  553.     HGDIOBJ         hGDI;
  554.  
  555.     SetBkColor(hDC, m_crBack);
  556.  
  557.     //Erase the background
  558.     SetRect(&rc, 0, 0, m_xOrg*2, m_yOrg*2);
  559.     ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
  560.  
  561.     rad=cos(m_dDeclin);
  562.  
  563.     x=(int)(m_cRadius*cos(m_dTheta));
  564.     y=(int)(m_cRadius*rad*sin(m_dTheta));
  565.  
  566.     SETPOINT(pt[0], m_xOrg+x, m_yOrg+y);
  567.     SETPOINT(pt[2], m_xOrg-x, m_yOrg-y);
  568.  
  569.     x=(int)(m_cRadius*cos(m_dTheta+PI/2));
  570.     y=(int)(m_cRadius*rad*sin(m_dTheta+PI/2));
  571.  
  572.     SETPOINT(pt[3], m_xOrg+x, m_yOrg+y);
  573.     SETPOINT(pt[1], m_xOrg-x, m_yOrg-y);
  574.  
  575.     pt[4]=pt[0];
  576.  
  577.     /*
  578.      * Set the line color according to which side of the square
  579.      * is facing out of the screen.  We'll draw the positive
  580.      * z lines a yellow (default), the negative face red
  581.      * (default).  Both colors can be changed by the controller.
  582.      *
  583.      * To determine which side is out, we only have to look at
  584.      * the rad value which is cos(m_dDeclin).  If positive, then
  585.      * we're in the positive range.
  586.      */
  587.  
  588.     hGDI=SelectObject(hDC, (rad > 0) ? m_hPenPos : m_hPenNeg);
  589.     Polyline(hDC, pt, sizeof(pt)/sizeof(POINT));
  590.  
  591.     SelectObject(hDC, GetStockObject(WHITE_PEN));
  592.     MoveToEx(hDC, m_xOrg, m_yOrg, NULL);
  593.     LineTo(hDC, pt[0].x, pt[0].y);
  594.  
  595.     SelectObject(hDC, hGDI);
  596.     return;
  597.     }
  598.  
  599.  
  600.  
  601.  
  602. /*
  603.  * SquareWndProc
  604.  *
  605.  * Purpose:
  606.  *  Window procedure for the Square window.
  607.  */
  608.  
  609. LRESULT APIENTRY SquareWndProc(HWND hWnd, UINT iMsg, WPARAM wParam
  610.     , LPARAM lParam)
  611.     {
  612.     PCSquare    pcp;
  613.     PAINTSTRUCT         ps;
  614.     HDC                 hDC;
  615.     RECT                rc;
  616.  
  617.     pcp=(PCSquare)GetWindowLong(hWnd, SQWL_STRUCTURE);
  618.  
  619.     switch (iMsg)
  620.         {
  621.         case WM_CREATE:
  622.             pcp=(PCSquare)((LPCREATESTRUCT)lParam)
  623.                 ->lpCreateParams;
  624.             SetWindowLong(hWnd, SQWL_STRUCTURE, (LONG)pcp);
  625.             break;
  626.  
  627.         case WM_ERASEBKGND:
  628.             hDC=(HDC)wParam;
  629.             SetBkColor(hDC, pcp->m_crBack);
  630.             GetClientRect(hWnd, &rc);
  631.             ExtTextOut(hDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
  632.             break;
  633.  
  634.         case WM_PAINT:
  635.             hDC=BeginPaint(hWnd, &ps);
  636.             pcp->Draw(hDC);
  637.             EndPaint(hWnd, &ps);
  638.             break;
  639.  
  640.         case WM_CLOSE:
  641.             /*
  642.              * Eat this or Alt+F4 can destroy the window, even
  643.              * though we don't have a system menu.
  644.              */
  645.             break;
  646.  
  647.         default:
  648.             return DefWindowProc(hWnd, iMsg, wParam, lParam);
  649.         }
  650.  
  651.     return 0L;
  652.     }
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659. /*
  660.  * CSquare::QueryInterface
  661.  * CSquare::AddRef
  662.  * CSquare::Release
  663.  *
  664.  * Purpose:
  665.  *  IUnknown members for CSquare object.
  666.  */
  667.  
  668. STDMETHODIMP CSquare::QueryInterface(REFIID riid, PPVOID ppv)
  669.     {
  670.     *ppv=NULL;
  671.  
  672.     if (IID_IUnknown==riid || IID_ISphereSquare==riid)
  673.         *ppv=this;
  674.  
  675.     if (IID_IDispatch==riid || DIID_DISphereSquare==riid)
  676.         return m_pIUnkDisp->QueryInterface(IID_IDispatch, ppv);
  677.  
  678.     if (NULL!=*ppv)
  679.         {
  680.         ((IUnknown *)*ppv)->AddRef();
  681.         return NOERROR;
  682.         }
  683.  
  684.     return ResultFromScode(E_NOINTERFACE);
  685.     }
  686.  
  687.  
  688. STDMETHODIMP_(ULONG) CSquare::AddRef(void)
  689.     {
  690.     return ++m_cRef;
  691.     }
  692.  
  693.  
  694. STDMETHODIMP_(ULONG) CSquare::Release(void)
  695.     {
  696.     if (0L!=--m_cRef)
  697.         return m_cRef;
  698.  
  699.     ObjectDestroyed();
  700.     delete this;
  701.     return 0L;
  702.     }
  703.  
  704.  
  705.  
  706. //ISphereSquare members
  707.  
  708. STDMETHODIMP_(double) CSquare::get_Radius(void)
  709.     {
  710.     return m_cRadius;
  711.     }
  712.  
  713. STDMETHODIMP_(void) CSquare::put_Radius(double cRadius)
  714.     {
  715.     //Only use positive radii.
  716.     if (cRadius > 0.0)
  717.         m_cRadius=cRadius;
  718.  
  719.     //We'll be lazy and not throw exceptions.
  720.     return;
  721.     }
  722.  
  723.  
  724. STDMETHODIMP_(double) CSquare::get_Theta(void)
  725.     {
  726.     return m_dTheta;
  727.     }
  728.  
  729. STDMETHODIMP_(void) CSquare::put_Theta(double dTheta)
  730.     {
  731.     //Anything is valid when you do trig
  732.     m_dTheta=dTheta;
  733.     return;
  734.     }
  735.  
  736.  
  737. STDMETHODIMP_(double) CSquare::get_Declination(void)
  738.     {
  739.     return m_dDeclin;
  740.     }
  741.  
  742. STDMETHODIMP_(void) CSquare::put_Declination(double dDeclin)
  743.     {
  744.     m_dDeclin=dDeclin;
  745.     return;
  746.     }
  747.  
  748.  
  749. STDMETHODIMP_(long) CSquare::get_BackColor(void)
  750.     {
  751.     return m_crBack;
  752.     }
  753.  
  754. STDMETHODIMP_(void) CSquare::put_BackColor(long crBack)
  755.     {
  756.     m_crBack=crBack;
  757.     return;
  758.     }
  759.  
  760.  
  761. STDMETHODIMP_(long) CSquare::get_LineColorPositive(void)
  762.     {
  763.     return m_crLinePos;
  764.     }
  765.  
  766. STDMETHODIMP_(void) CSquare::put_LineColorPositive(long crLinePos)
  767.     {
  768.     m_crLinePos=crLinePos;
  769.     return;
  770.     }
  771.  
  772.  
  773. STDMETHODIMP_(long) CSquare::get_LineColorNegative(void)
  774.     {
  775.     return m_crLineNeg;
  776.     }
  777.  
  778. STDMETHODIMP_(void) CSquare::put_LineColorNegative(long crLineNeg)
  779.     {
  780.     m_crLineNeg=crLineNeg;
  781.     return;
  782.     }
  783.  
  784.  
  785. STDMETHODIMP_(void) CSquare::Draw(void)
  786.     {
  787.     InvalidateRect(m_hWnd, NULL, FALSE);
  788.     UpdateWindow(m_hWnd);
  789.     return;
  790.     }
  791.  
  792. STDMETHODIMP_(void) CSquare::SetCenterPoint(int cx, int cy)
  793.     {
  794.     //No validation...we're deing lazy
  795.     m_xOrg=cx;
  796.     m_yOrg=cy;
  797.     return;
  798.     }
  799.  
  800. STDMETHODIMP_(void) CSquare::ShowWindow(int nCmdShow)
  801.     {
  802.     ::ShowWindow(m_hWnd, nCmdShow);
  803.     UpdateWindow(m_hWnd);
  804.     return;
  805.     }
  806.  
  807. STDMETHODIMP_(void) CSquare::SetWindowPosition(int xPos, int yPos)
  808.     {
  809.     m_xPos=xPos;
  810.     m_yPos=yPos;
  811.  
  812.     SetWindowPos(m_hWnd, NULL, m_xPos, m_yPos, 0, 0
  813.         , SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  814.     return;
  815.     }
  816.  
  817. STDMETHODIMP_(void) CSquare::SetWindowSize(int cx, int cy)
  818.     {
  819.     m_cx=cx;
  820.     m_cy=cy;
  821.  
  822.     SetWindowPos(m_hWnd, NULL, 0, 0, m_cx, m_cy
  823.         , SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
  824.     return;
  825.     }
  826.