bullseye.cpp

来自「《ATL深入解析》随书源码」· C++ 代码 · 共 718 行 · 第 1/2 页

CPP
718
字号
// BullsEye.cpp : Implementation of CBullsEye

#include "stdafx.h"
#include "BullsEyeCtl.h"
#include "BullsEye.h"
#include "ocidl.h"	// Added by ClassView
#include "AboutDlg.h"

/////////////////////////////////////////////////////////////////////////////
// CBullsEyeLicense class static member variables

// {956FC2C2-5AF8-11d2-BD05-00A0C9C8E50D}
const GUID CBullsEyeLicense::RunTimeLicenseKey = 
{ 0x956fc2c2, 0x5af8, 0x11d2, { 0xbd, 0x5, 0x0, 0xa0, 0xc9, 0xc8, 0xe5, 0xd } };

HRESULT SetStrings(/*[in*/ ULONG cElems, /*[in]*/ const LPCOLESTR* rgpsz, /*[out]*/ CALPOLESTR* pStrings);
HRESULT SetCookies(/*[in*/ ULONG cElems, /*[in*/ const DWORD* pdwCookies, /*[out]*/ CADWORD* pcaCookies);

/////////////////////////////////////////////////////////////////////////////
// CBullsEye class construction, initialization and desruction

CLIPFORMAT CBullsEye::m_cfEmbeddedObject;
CLIPFORMAT CBullsEye::m_cfObjectDescriptor;

/***************/
/* Constructor */
/***************/

CBullsEye::CBullsEye()
{
    // Stock properties
    m_nBackStyle        = 0;        // Opaque    = 0, Transparent  = 1

    m_nBorderStyle      = 0;        // No border = 0, Fixed single = 1
    m_nBorderWidth      = 1;
    m_clrBackColor      = RGB (255,255,255);
    m_clrForeColor      = RGB (  0,  0,  0);
    m_bEnabled          = TRUE;

    // Custom properties
    m_clrAlternateColor = RGB (  0,  0,  0);
    m_clrCenterColor    = RGB (255,  0,  0);
    m_beep              = VARIANT_TRUE;

    // Control state
    m_alternateBrush    = NULL;
    m_backBrush         = NULL;
    m_centerBrush       = NULL;
    m_borderPen         = NULL;
    m_nAppearance       = 0;

    m_bAmbientsFetched  = false;
}

/******************/
/* FinalConstruct */
/******************/

HRESULT CBullsEye::FinalConstruct ()
{
    FreezeEvents (TRUE);
    put_RingCount (5);
    FreezeEvents (FALSE);
    return S_OK;
}

/**************/
/* Destructor */
/**************/

CBullsEye::~CBullsEye()
{
    if (m_alternateBrush) ::DeleteObject (m_alternateBrush);
    if (m_backBrush)      ::DeleteObject (m_backBrush);
    if (m_centerBrush)    ::DeleteObject (m_centerBrush);
    if (m_borderPen)      ::DeleteObject (m_borderPen);
}

/////////////////////////////////////////////////////////////////////////////
// IPerPropertyBrowsing method overrides

/********************/
/* GetDisplayString */
/********************/

STDMETHODIMP CBullsEye::GetDisplayString(DISPID dispid,BSTR *pBstr)
{
	ATLTRACE2(atlTraceControls,2,_T("CBullsEye::GetDisplayString\n"));
    switch (dispid) {
    case DISPID_BEEP:
        if (VARIANT_TRUE == m_beep)
            *pBstr = SysAllocString (OLESTR("Yes"));
        else
            *pBstr = SysAllocString (OLESTR("No"));

        return *pBstr ? S_OK : E_OUTOFMEMORY;

    case DISPID_BACKSTYLE:
        if (1 == m_nBackStyle)
            *pBstr = SysAllocString (OLESTR("Opaque"));
        else
            *pBstr = SysAllocString (OLESTR("Transparent"));

        return *pBstr ? S_OK : E_OUTOFMEMORY;

    case DISPID_ALTERNATECOLOR: // Make Visual Basic apply default formatting
    case DISPID_BACKCOLOR:      //   for these color properties
    case DISPID_CENTERCOLOR:    // Otherwise it displays color values in decimal
    case DISPID_FORECOLOR:      //   and doesn't draw the color sample correctly
    case DISPID_RINGCOUNT:
        return S_FALSE;         // This is an undocumented return value that works...
    }

    return IPerPropertyBrowsingImpl<CBullsEye>::GetDisplayString(dispid, pBstr);
}

/*********************/
/* MapPropertyToPage */
/*********************/

STDMETHODIMP CBullsEye::MapPropertyToPage(DISPID dispid, CLSID *pClsid)
{
  ATLTRACE2(atlTraceControls,2,_T("CBullsEye::MapPropertyToPage\n"));
  // Look up the property page CLSID in the PROP MAP
  HRESULT hr = IPerPropertyBrowsingImpl<CBullsEye>::MapPropertyToPage(dispid, pClsid);
  // When there is no property page for a listed property, fail the call
  if (SUCCEEDED(hr) && CLSID_NULL == *pClsid) hr = E_INVALIDARG;
  return hr;
}

/************************/
/* GetPredefinedStrings */
/************************/

#define DIM(a) (sizeof(a)/sizeof(a[0]))

static const LPCOLESTR    rszBeepStrings [] = { OLESTR("Yes, make noise"), OLESTR("No, be mute") };
static const DWORD        rdwBeepCookies [] = { 0, 1 };
static const VARIANT_BOOL rvbBeepValues  [] = { VARIANT_TRUE, VARIANT_FALSE };

static const UINT cBeepStrings = DIM(rszBeepStrings);
static const UINT cBeepCookies = DIM(rdwBeepCookies);
static const UINT cBeepValues  = DIM(rvbBeepValues);

static const LPCOLESTR    rszBackStyleStrings [] = { OLESTR("Opaque"), OLESTR("Transparent") };
static const DWORD        rdwBackStyleCookies [] = { 0, 1 };
static const long         rvbBackStyleValues  [] = { 1, 0 };

static const UINT cBackStyleStrings = DIM(rszBackStyleStrings);
static const UINT cBackStyleCookies = DIM(rdwBackStyleCookies);
static const UINT cBackStyleValues  = DIM(rvbBackStyleValues);

STDMETHODIMP CBullsEye::GetPredefinedStrings(/*[in]*/ DISPID dispid, /*[out]*/ CALPOLESTR *pcaStringsOut, /*[out]*/ CADWORD *pcaCookiesOut)
{
	ATLTRACE2(atlTraceControls,2,_T("CBullsEye::GetPredefinedStrings\n"));
	if (NULL == pcaStringsOut || NULL == pcaCookiesOut) return E_POINTER;


    ATLASSERT (cBeepStrings == cBeepCookies);
    ATLASSERT (cBeepStrings == cBeepValues);

    ATLASSERT (cBackStyleStrings == cBackStyleCookies);
    ATLASSERT (cBackStyleStrings == cBackStyleValues);

	pcaStringsOut->cElems = 0;
	pcaStringsOut->pElems = NULL;
	pcaCookiesOut->cElems = 0;
	pcaCookiesOut->pElems = NULL;

    HRESULT hr = S_OK;
    switch (dispid) {
    case DISPID_BEEP:
        hr = SetStrings (cBeepValues, rszBeepStrings, pcaStringsOut);
        if (FAILED (hr)) return hr;
        return SetCookies (cBeepValues, rdwBeepCookies, pcaCookiesOut);

    case DISPID_BACKSTYLE:
        hr = SetStrings (cBackStyleValues, rszBackStyleStrings, pcaStringsOut);
        if (FAILED (hr)) return hr;
        return SetCookies (cBackStyleValues, rdwBackStyleCookies, pcaCookiesOut);
    }
    return IPerPropertyBrowsingImpl<CBullsEye>::GetPredefinedStrings(dispid, pcaStringsOut, pcaCookiesOut);
}

/**********************/
/* GetPredefinedValue */
/**********************/

STDMETHODIMP CBullsEye::GetPredefinedValue(DISPID dispid, DWORD dwCookie, VARIANT* pVarOut)
{
    if (NULL == pVarOut) return E_POINTER;

    ULONG i;
    switch (dispid) {
    case DISPID_BEEP:
        // Walk through cookie array looking for matching value
        for (i = 0; i < cBeepCookies; i++) {
            if (rdwBeepCookies[i] == dwCookie) {
                pVarOut->vt = VT_BOOL;
                pVarOut->boolVal = rvbBeepValues [i];
                return S_OK;
            }
        }
        return E_INVALIDARG;

    case DISPID_BACKSTYLE:
        // Walk through cookie array looking for matching value
        for (i = 0; i < cBackStyleCookies; i++) {
            if (rdwBackStyleCookies[i] == dwCookie) {
                pVarOut->vt = VT_I4;
                pVarOut->lVal = rvbBackStyleValues [i];
                return S_OK;
            }
        }
        return E_INVALIDARG;
    }

    return IPerPropertyBrowsingImpl<CBullsEye>::GetPredefinedValue(dispid, dwCookie, pVarOut);
}


/////////////////////////////////////////////////////////////////////////////
// ICategorizeProperties interface implementation

/*************************/
/* MapPropertyToCategory */
/*************************/

STDMETHODIMP CBullsEye::MapPropertyToCategory(/*[in]*/ DISPID dispid, /*[out]*/ PROPCAT* ppropcat)
{
    if (NULL == ppropcat) return E_POINTER;

    switch (dispid) {
    case DISPID_FORECOLOR:
    case DISPID_BACKCOLOR:
    case DISPID_CENTERCOLOR:
    case DISPID_ALTERNATECOLOR:
    case DISPID_RINGCOUNT:
    case DISPID_BACKSTYLE:
        *ppropcat = PROPCAT_Appearance;
        return S_OK;

    case DISPID_BEEP:
    case DISPID_ENABLED:
        *ppropcat = PROPCAT_Behavior;
        return S_OK;

    case DISPID_RINGVALUE:
        *ppropcat = PROPCAT_Scoring;
        return S_OK;

    default:
        return E_FAIL;
    }
}

/*******************/
/* GetCategoryName */
/*******************/

STDMETHODIMP CBullsEye::GetCategoryName(/*[in]*/ PROPCAT propcat, /*[in]*/ LCID lcid, /*[out]*/ BSTR* pbstrName)
{
    if(PROPCAT_Scoring == propcat) {
        *pbstrName = ::SysAllocString(L"Scoring"); 
        return S_OK;
    }
    return E_FAIL;
}

/////////////////////////////////////////////////////////////////////////////
// IViewObjectExImpl method overrides

/*****************/
/* GetViewStatus */
/*****************/

STDMETHODIMP CBullsEye::GetViewStatus(DWORD* pdwStatus)
{
	ATLTRACE2(atlTraceControls,2,_T("CBullsEye::GetViewStatus\n"));
    *pdwStatus = m_nBackStyle == 1 ?  // Opaque?
        VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE :
        VIEWSTATUS_DVASPECTTRANSPARENT ;
	return S_OK;
}

/*****************/
/* QueryHitPoint */
/*****************/

STDMETHODIMP CBullsEye::QueryHitPoint(DWORD dwAspect, LPCRECT pRectBounds, POINT ptlLoc, LONG /* lCloseHint */, DWORD *pHitResult)
{
    ATLTRACE2(atlTraceControls,2,_T("CBullsEye::QueryHitPoint\n"));
    switch (dwAspect) {
    case DVASPECT_CONTENT:
    case DVASPECT_OPAQUE:
    case DVASPECT_TRANSPARENT:
        // Compute point relative to control's origin
        CPoint   pt (ptlLoc.x - pRectBounds->left, ptlLoc.y - pRectBounds->top);
        if (-1 != HitTest (pt))
		    *pHitResult = HITRESULT_HIT;
        else
		    *pHitResult = HITRESULT_OUTSIDE;

		return S_OK;
    }
    ATLTRACE2(atlTraceControls,2,_T("Wrong DVASPECT\n"));
    return E_FAIL;
}

/****************/
/* QueryHitRect */
/****************/

STDMETHODIMP CBullsEye::QueryHitRect(DWORD dwAspect, LPCRECT pRectBounds, LPCRECT prcLoc, LONG /* lCloseHint */, DWORD* pHitResult)
{
	ATLTRACE2(atlTraceControls,2,_T("CBullsEye::QueryHitRect\n"));
    switch (dwAspect) {
    case DVASPECT_CONTENT:
    case DVASPECT_OPAQUE:
    case DVASPECT_TRANSPARENT:
        RECT rc;
		*pHitResult = UnionRect(&rc, pRectBounds, prcLoc) ? HITRESULT_HIT : HITRESULT_OUTSIDE;
		return S_OK;
	}
	ATLTRACE2(atlTraceControls,2,_T("Wrong DVASPECT\n"));
	return E_FAIL;
}

/////////////////////////////////////////////////////////////////////////////
// IDataObject method overrides

/****************/
/* QueryGetData */
/****************/

STDMETHODIMP CBullsEye::QueryGetData(FORMATETC* pformatetc)
{
	ATLTRACE2(atlTraceControls,2,_T("CBullsEye::QueryGetData\n"));

    if (NULL == pformatetc) return E_POINTER;

    if (pformatetc->lindex != -1) return DV_E_LINDEX;

    if ((pformatetc->tymed & TYMED_MFPICT) == 0) return DV_E_TYMED ;

    if (pformatetc->dwAspect != DVASPECT_CONTENT) return DV_E_DVASPECT;

    return S_OK;
}

/*****************/
/* EnumFormatEtc */
/*****************/

STDMETHODIMP CBullsEye::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC** ppenumFormatEtc)
{
    static FORMATETC array[] = { 
        { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT }, };

⌨️ 快捷键说明

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