⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 figure.cpp

📁 英文版的 想要的话可以下载了 为大家服务
💻 CPP
字号:
/*
 * FIGURE.CPP
 * Cosmo Handler Chapter 19
 *
 * Implementation of the CFigure class that we expose as a
 * CosmoFigure Object in this handler.
 *
 * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
 *
 * Kraig Brockschmidt, Microsoft
 * Internet  :  kraigb@microsoft.com
 * Compuserve:  >INTERNET:kraigb@microsoft.com
 */


#include "hcosmo.h"


/*
 * CFigure:CFigure
 * CFigure::~CFigure
 *
 * Constructor Parameters:
 *  pUnkOuter       LPUNKNOWN of the controlling unknown.
 *  pfnDestroy      PFNDESTROYED to call when object is destroyed.
 *  hInst           HINSTANCE of the application we're in.
 */

CFigure::CFigure(LPUNKNOWN pUnkOuter, PFNDESTROYED pfnDestroy
    , HINSTANCE hInst)
    {
    m_cRef=0;
    m_pUnkOuter=pUnkOuter;
    m_pfnDestroy=pfnDestroy;
    m_clsID=CLSID_CosmoFigure;

    m_cf=RegisterClipboardFormat(SZPOLYLINECLIPFORMAT);

    //NULL any contained interfaces initially.
    m_pImpIOleObject     =NULL;
    m_pImpIViewObject2   =NULL;
    m_pImpIPersistStorage=NULL;
    m_pImpIAdviseSink    =NULL;

    m_pDefIUnknown       =NULL;
    m_pDefIOleObject     =NULL;
    m_pDefIViewObject2   =NULL;
    m_pDefIPersistStorage=NULL;
    m_pDefIDataObject    =NULL;

    m_pIAdvSinkView      =NULL;
    m_dwAdviseFlags      =0;
    m_dwAdviseAspects    =0;
    m_dwFrozenAspects    =0;

    return;
    }


CFigure::~CFigure(void)
    {
    LPUNKNOWN       pIUnknown=this;

    if (NULL!=m_pUnkOuter)
        pIUnknown=m_pUnkOuter;

    /*
     * In aggregation, release cached pointers but
     * AddRef the controlling unknown first.
     */
    if (NULL!=m_pDefIOleObject)
        {
        pIUnknown->AddRef();
        m_pDefIOleObject->Release();
        }

    if (NULL!=m_pDefIViewObject2)
        {
        pIUnknown->AddRef();
        m_pDefIViewObject2->Release();
        }

    if (NULL!=m_pDefIDataObject)
        {
        pIUnknown->AddRef();
        m_pDefIDataObject->Release();
        }

    if (NULL!=m_pDefIPersistStorage)
        {
        pIUnknown->AddRef();
        m_pDefIPersistStorage->Release();
        }

    ReleaseInterface(m_pIAdvSinkView);
    ReleaseInterface(m_pDefIUnknown)

    DeleteInterfaceImp(m_pImpIAdviseSink);
    DeleteInterfaceImp(m_pImpIPersistStorage);
    DeleteInterfaceImp(m_pImpIViewObject2);
    DeleteInterfaceImp(m_pImpIOleObject);

    return;
    }




/*
 * CFigure::Init
 *
 * Purpose:
 *  Performs any intiailization of a CFigure that's prone to failure
 *  that we also use internally before exposing the object outside
 *  this DLL.
 *
 * Parameters:
 *  None
 *
 * Return Value:
 *  BOOL            TRUE if the function is successful,
 *                  FALSE otherwise.
 */

BOOL CFigure::Init(void)
    {
    LPUNKNOWN       pIUnknown=this;
    HRESULT         hr;
    DWORD           dwConn;
    FORMATETC       fe;

    if (NULL!=m_pUnkOuter)
        pIUnknown=m_pUnkOuter;

    //First create our interfaces.
    m_pImpIOleObject=new CImpIOleObject(this, pIUnknown);

    if (NULL==m_pImpIOleObject)
        return FALSE;

    m_pImpIViewObject2=new CImpIViewObject2(this, pIUnknown);

    if (NULL==m_pImpIViewObject2)
        return FALSE;

    m_pImpIPersistStorage=new CImpIPersistStorage(this, pIUnknown);

    if (NULL==m_pImpIPersistStorage)
        return FALSE;

    m_pImpIAdviseSink=new CImpIAdviseSink(this, pIUnknown);

    if (NULL==m_pImpIAdviseSink)
        return FALSE;

    /*
     * Get an IUnknown on the default handler, passing pIUnknown
     * as the controlling unknown.  The extra reference count is to
     * prevent us from going away accidentally.
     */
    m_cRef++;

    hr=OleCreateDefaultHandler(CLSID_CosmoFigure, pIUnknown
        , IID_IUnknown, (PPVOID)&m_pDefIUnknown);

    if (FAILED(hr))
        return FALSE;

    /*
     * NOTE:  The spec specifically states that any interfaces
     * besides IUnknown that we obtain on an aggregated object
     * should be Released immediately after we QueryInterface for
     * them because the QueryInterface will AddRef us, and since
     * we would not release these interfaces until we were
     * destroyed, we'd never go away because we'd never get a zero
     * ref count.
     */

    //Now try to get other interfaces to which we delegate
    hr=m_pDefIUnknown->QueryInterface(IID_IOleObject
        , (PPVOID)&m_pDefIOleObject);

    if (FAILED(hr))
        return FALSE;

    pIUnknown->Release();

    hr=m_pDefIUnknown->QueryInterface(IID_IViewObject2
        , (PPVOID)&m_pDefIViewObject2);

    if (FAILED(hr))
        return FALSE;

    pIUnknown->Release();

    hr=m_pDefIUnknown->QueryInterface(IID_IDataObject
        , (PPVOID)&m_pDefIDataObject);

    if (FAILED(hr))
        return FALSE;

    pIUnknown->Release();

    hr=m_pDefIUnknown->QueryInterface(IID_IPersistStorage
        , (PPVOID)&m_pDefIPersistStorage);

    if (FAILED(hr))
        return FALSE;

    pIUnknown->Release();

    m_cRef--;

    //Set up an advise on native data so we can keep in sync
    SETDefFormatEtc(fe, m_cf, TYMED_HGLOBAL);
    m_pDefIDataObject->DAdvise(&fe, 0, m_pImpIAdviseSink, &dwConn);

    return TRUE;
    }





/*
 * CFigure::QueryInterface
 * CFigure::AddRef
 * CFigure::Release
 *
 * Purpose:
 *  IUnknown members for CFigure object.
 */

STDMETHODIMP CFigure::QueryInterface(REFIID riid, PPVOID ppv)
    {
    *ppv=NULL;

    /*
     * The only calls we get here for IUnknown are either in a non-
     * aggregated case or when we're created in an aggregation, so
     * in either we always return our IUnknown for IID_IUnknown.
     */
    if (IID_IUnknown==riid)
        *ppv=this;

    if (IID_IPersist==riid || IID_IPersistStorage==riid)
        *ppv=m_pImpIPersistStorage;

    if (IID_IOleObject==riid)
        *ppv=m_pImpIOleObject;

    if (IID_IViewObject==riid || IID_IViewObject2==riid)
        *ppv=m_pImpIViewObject2;

    if (NULL!=*ppv)
        {
        ((LPUNKNOWN)*ppv)->AddRef();
        return NOERROR;
        }

    /*
     * Only expose default handler interfaces that you explicitly
     * know you are aggregating.  You cannot just blindly
     * delegate any other QueryInterface to the handler because
     * it may return interfaces you do not expect...such as a
     * newer version of an interface you implement in the handler.
     * We know as a handler that we must provide IDataObject,
     * IOleCache[2], IOleCacheControl, and IRunnableObject, and
     * these we get from the default handler.
     */

    if (IID_IDataObject==riid || IID_IOleCache==riid
        || IID_IOleCache2==riid || IID_IOleCacheControl==riid
        || IID_IRunnableObject==riid)
        return m_pDefIUnknown->QueryInterface(riid, ppv);

    return ResultFromScode(E_NOINTERFACE);
    }


STDMETHODIMP_(ULONG) CFigure::AddRef(void)
    {
    return ++m_cRef;
    }


STDMETHODIMP_(ULONG) CFigure::Release(void)
    {
    if (0!=--m_cRef)
        return m_cRef;

    m_cRef++;
    delete this;
    return 0;
    }





/*
 * CFigure::Draw
 *
 * Purpose:
 *  Paints the current window to an hDC which might be a printer.
 *
 * Parameters:
 *  hDC             HDC to draw on, could be a metafile or
 *                  printer DC.
 *  pRect           LPRECT defining hDC bounds in which to draw.
 *  dwAspect        DWORD aspect to draw.
 *  ptd             DVTARGETDEVICE * containing device info.
 *  hICDev          HDC containing the IC for the device.
 *  ppl             PPOLYLINEDATA from which to draw.
 *
 * Return Value:
 *  None
 */

void CFigure::Draw(HDC hDC, LPRECT pRect, DWORD dwAspect
    , DVTARGETDEVICE *ptd, HDC hICDev, PPOLYLINEDATA ppl)
    {
    HBRUSH          hBrush;
    HPEN            hPen;
    HGDIOBJ         hObj1, hObj2;
    UINT            i, j;
    int             nDC;
    POINTS          pt1,pt2;
    POINT           rgpt[CPOLYLINEPOINTS];

    nDC=SaveDC(hDC);

    for (i=0; i < ppl->cPoints; i++)
        {
        rgpt[i].x=ppl->rgpt[i].x;
        rgpt[i].y=ppl->rgpt[i].y;
        }

    hPen=CreatePen(ppl->iLineStyle, 1, ppl->rgbLine);
    hObj1=SelectObject(hDC, hPen);

    hBrush=CreateSolidBrush(ppl->rgbBackground);
    hObj2=SelectObject(hDC, hBrush);
    SetBkColor(hDC, ppl->rgbBackground);

    //If we have one point, draw a dot to indicate it's position.
    if (1==m_pl.cPoints)
        {
        pt1.x=(short)rgpt[0].x;
        pt1.y=(short)rgpt[0].y;
        PointScale(pRect, &pt1, TRUE);
        SetPixel(hDC, pt1.x, pt1.y, m_pl.rgbLine);
        }
    else
        {
        //Erase the background for bitmaps and metafiles.
        SelectObject(hDC, GetStockObject(NULL_PEN));
        Rectangle(hDC, pRect->left, pRect->top, pRect->right+1
            , pRect->bottom+1);
        SelectObject(hDC, hPen);

        for (i=0; i < ppl->cPoints; i++)
            {
            for (j=i; j < ppl->cPoints; j++)
                {
                pt1.x=(short)rgpt[i].x;
                pt1.y=(short)rgpt[i].y;
                pt2.x=(short)rgpt[j].x;
                pt2.y=(short)rgpt[j].y;
                PointScale(pRect, &pt1, TRUE);
                PointScale(pRect, &pt2, TRUE);
                MoveToEx(hDC, pt1.x, pt1.y, NULL);
                LineTo(hDC, pt2.x, pt2.y);
                }
            }
        }

    SelectObject(hDC, hObj1);
    SelectObject(hDC, hObj2);
    DeleteObject(hBrush);
    DeleteObject(hPen);

    RestoreDC(hDC, nDC);
    return;
    }







/*
 * CFIgure::PointScale
 *
 * Purpose:
 *  Scales a point from a 0-32767 coordinate to a rectangle relative
 *  coordinate.
 *
 * Parameters:
 *  pRect           LPRECT in which to scale.
 *  ppt             LPPOINTS to convert
 *  fUnused         BOOL of no use.
 *
 * Return Value:
 *  None
 */

void CFigure::PointScale(LPRECT pRect, LPPOINTS ppt, BOOL fUnused)
    {
    DWORD   cx, cy;

    cx=(DWORD)(pRect->right-pRect->left);
    cy=(DWORD)(pRect->bottom-pRect->top);

    //Must use DWORD to insure proper scaling.
    ppt->x=pRect->left+(UINT)(((DWORD)ppt->x*cx) >> 15);
    ppt->y=pRect->top+(UINT)(((DWORD)ppt->y*cy) >> 15);

    return;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -