Property Name |
Type |
Stock DISPID |
Description |
BackColor |
OLE_COLOR |
DISPID_BACKCOLOR |
Background color |
BackStyle |
long |
DISPID_BACKSTYLE |
Background style, transparent or opaque |
Enabled |
VARIANT_BOOL |
DISPID_ENABLED |
Enabled status, TRUE or FALSE |
ForeColor |
OLE_COLOR |
DISPID_FORECOLOR |
Foreground color |
Figure 6 BullsEye Stock Methods
Method Name |
Stock DISPID |
Description |
AboutBox |
DISPID_ABOUTBOX |
Display the control's Help About dialog |
DoClick |
DISPID_DOCLICK |
Simulate a mouse click on the control |
Refresh |
DISPID_REFRESH |
Redraw the control |
Figure 7 BullsEye Custom Properties
Property Name |
Type |
Custom DISPID |
Description |
Application |
IDispatch* |
DISPID_APPLICATION |
Return the IDispatch* for the hosting application |
AlternateColor |
OLE_COLOR |
DISPID_ALTERNATECOLOR |
Get/set the color of the alternate (even) rings |
Beep |
VARIANT_BOOL |
DISPID_BEEP |
Enable/disable sound effects for the control |
CenterColor |
OLE_COLOR |
DISPID_CENTERCOLOR |
Get/set the color of the center (odd) rings |
Parent |
IDispatch* |
DISPID_PARENT |
Return the IDispatch* for the control's parent |
RingCount |
short |
DISPID_RINGCOUNT |
Get/set the number of rings |
RingValue |
long |
DISPID_RINGVALUE |
Get/set the value of each ring |
// ATLInternals.idl : IDL source for ATLInternals.dll
//
// This file will be processed by the MIDL tool to
// produce the type library (ATLInternals.tlb) and marshalling code.
import "oaidl.idl";
import "ocidl.idl";
import "CategorizeProperties.idl";
#include "olectl.h"
// IBullsEye Interface
[
object,
uuid(7DC59CC4-36C0-11D2-AC05-00A0C9C8E50D),
dual,
helpstring("IBullsEye Interface"),
pointer_default(unique)
]
interface IBullsEye : IDispatch
{
const int DISPID_ALTERNATECOLOR = 1;
const int DISPID_BEEP = 2;
const int DISPID_CENTERCOLOR = 3;
const int DISPID_RINGCOUNT = 4;
const int DISPID_RINGVALUE = 5;
const int DISPID_APPLICATION = 6;
const int DISPID_PARENT = 7;
[propput, id(DISPID_BACKCOLOR)] HRESULT BackColor([in]OLE_COLOR clr);
[propget, id(DISPID_BACKCOLOR)] HRESULT BackColor(
[out,retval]OLE_COLOR* pclr);
[propput, id(DISPID_BACKSTYLE)] HRESULT BackStyle([in]long style);
[propget, id(DISPID_BACKSTYLE)] HRESULT BackStyle([out,retval]long* style);
[propput, id(DISPID_FORECOLOR)] HRESULT ForeColor([in]OLE_COLOR clr);
[propget, id(DISPID_FORECOLOR)] HRESULT ForeColor(
[out,retval]OLE_COLOR* pclr);
[propput, id(DISPID_ENABLED)] HRESULT Enabled([in]VARIANT_BOOL vbool);
[propget, id(DISPID_ENABLED)] HRESULT Enabled(
[out,retval]VARIANT_BOOL* pbool);
[propget, id(DISPID_ALTERNATECOLOR), helpstring("property AlternateColor"),
bindable, requestedit] HRESULT AlternateColor([out, retval] OLE_COLOR *pVal);
[propput, id(DISPID_ALTERNATECOLOR), helpstring("property AlternateColor"),
bindable, requestedit] HRESULT AlternateColor([in] OLE_COLOR newVal);
[propget, id(DISPID_BEEP), helpstring("property Beep"), bindable,
requestedit] HRESULT Beep([out, retval] VARIANT_BOOL *pVal);
[propput, id(DISPID_BEEP), helpstring("property Beep"), bindable,
requestedit] HRESULT Beep([in] VARIANT_BOOL newVal);
[propget, id(DISPID_CENTERCOLOR), helpstring("property CenterColor"),
bindable, requestedit] HRESULT CenterColor([out, retval] OLE_COLOR *pVal);
[propput, id(DISPID_CENTERCOLOR), helpstring("property CenterColor"),
bindable, requestedit] HRESULT CenterColor([in] OLE_COLOR newVal);
[propget, id(DISPID_RINGCOUNT), helpstring("property RingCount"), bindable,
requestedit] HRESULT RingCount([out, retval] short *pVal);
[propput, id(DISPID_RINGCOUNT), helpstring("property RingCount"), bindable,
requestedit] HRESULT RingCount([in] short newVal);
[propget, id(DISPID_RINGVALUE), helpstring("property RingValue"), bindable,
requestedit] HRESULT RingValue([in] short sRingNumber,
[out, retval] long *pVal);
[propput, id(DISPID_RINGVALUE), helpstring("property RingValue"), bindable,
requestedit] HRESULT RingValue([in] short sRingNumber, [in] long newVal);
[propget, id(DISPID_APPLICATION), helpstring("property Application")] HRESULT
Application([out, retval] LPDISPATCH *pVal);
[propget, id(DISPID_PARENT), helpstring("property Parent")] HRESULT
Parent([out, retval] LPDISPATCH *pVal);
[id(DISPID_REFRESH), helpstring("method Refresh")] HRESULT Refresh();
[id(DISPID_DOCLICK), helpstring("method DoClick")] HRESULT DoClick();
[id(DISPID_ABOUTBOX), helpstring("method AboutBox")] HRESULT AboutBox();
};
// Useful definitions of the event DISPIDs
const int DISPID_ONRINGHIT = 1;
const int DISPID_ONSCORECHANGED = 2;
[
uuid(95CD3721-FC5C-11D1-8CC3-00A0C9C8E50D),
version(1.0),
helpstring("ATLInternals 1.0 Type Library")
]
library ATLINTERNALSLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
// _IBullsEyeEvents Dispatch Interface
[
uuid(19FF9872-36ED-11d2-AC05-00A0C9C8E50D),
helpstring("Event interface for BullsEye Control")
]
dispinterface _IBullsEyeEvents
{
properties:
methods:
[id(DISPID_ONRINGHIT)] void OnRingHit(short ringNumber);
[id(DISPID_ONSCORECHANGED)] void OnScoreChanged(long ringValue);
};
[
uuid(7DC59CC5-36C0-11D2-AC05-00A0C9C8E50D),
helpstring("BullsEye Class")
]
coclass BullsEye
{
[default] interface IBullsEye;
[default, source] dispinterface _IBullsEyeEvents;
};
[
uuid(7DC59CC8-36C0-11D2-AC05-00A0C9C8E50D),
helpstring("BullsEyePropPage Class")
]
coclass BullsEyePropPage
{
interface IUnknown;
};
};
Figure 9 BullsEye Custom Events
Event |
Event DISPID |
Description |
void OnRingHit (short sRingNumber) |
DISPID_ONRINGHIT |
The user clicked on one of the bull's-eye rings. The argument specifies the ring the user clicked. Rings are numbered from 1 to n from the center outwards. |
void OnScoreChanged (long RingValue) |
DISPID_ONSCORECHANGED |
This event follows the OnRingHit event when the user clicks on a bull's-eye ring. The argument specifies the score value of the ring the user clicked. |
Figure 13 BullsEye
/////////////////////////////////////////////////////////////////////////////
// CBullsEye
class ATL_NO_VTABLE CBullsEye :
// COM object support
public CComObjectRootEx<CComSingleThreadModel>,
// Class object support
public CComCoClass<CBullsEye, &CLSID_BullsEye>,
// Default dual (IDispatch-derived) interface to control
// Request for properties preprocessed by stock property base class
public CStockPropImpl<CBullsEye, IBullsEye, &IID_IBullsEye,
&LIBID_ATLInternalsLib>,
// Error info support for default dual interface
public ISupportErrorInfo,
// Basic "Lite" Control implementation
public CComControl<CBullsEye>,
public IOleControlImpl<CBullsEye>,
public IOleObjectImpl<CBullsEye>,
public IOleInPlaceActiveObjectImpl<CBullsEye>,
public IOleInPlaceObjectWindowlessImpl<CBullsEye>,
public IViewObjectExImpl<CBullsEye>,
// "Lite" control persistence implementation
public IPersistStreamInitImpl<CBullsEye>,
// Full control additional implementations
// Support for OLE embedding
public IDataObjectImpl<CBullsEye>,
public IPersistStorageImpl<CBullsEye>,
// Support for property pages
public ISpecifyPropertyPagesImpl<CBullsEye>,
// Support for fast activation
public IQuickActivateImpl<CBullsEye>,
// Connection point implementation
public IConnectionPointContainerImpl<CBullsEye>,
public IProvideClassInfo2Impl<&CLSID_BullsEye, &DIID__IBullsEyeEvents,
&LIBID_ATLInternalsLib>,
// Full controls supporting connection points
// also receive property change notification support
public IPropertyNotifySinkCP<CBullsEye>
{
public:
CBullsEye() { }
DECLARE_REGISTRY_RESOURCEID(IDR_BULLSEYE)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CBullsEye)
// Default dual (IDispatch-derived) interface to control
COM_INTERFACE_ENTRY(IBullsEye)
COM_INTERFACE_ENTRY(IDispatch)
// Error info support for default dual interface
COM_INTERFACE_ENTRY(ISupportErrorInfo)
// Basic "Lite" Control implementation
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
COM_INTERFACE_ENTRY(IOleInPlaceObject)
COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
COM_INTERFACE_ENTRY(IViewObjectEx)
COM_INTERFACE_ENTRY(IViewObject2)
COM_INTERFACE_ENTRY(IViewObject)
// "Lite" control persistence implementation
COM_INTERFACE_ENTRY(IPersistStreamInit)
COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
// Full control additional implementations
// Support for OLE embedding
COM_INTERFACE_ENTRY(IDataObject)
COM_INTERFACE_ENTRY(IPersistStorage)
// Support for property pages
COM_INTERFACE_ENTRY(ISpecifyPropertyPages)
// Support for fast activation
COM_INTERFACE_ENTRY(IQuickActivate)
// Support for Connection Points
COM_INTERFACE_ENTRY(IConnectionPointContainer)
COM_INTERFACE_ENTRY(IProvideClassInfo2)
COM_INTERFACE_ENTRY(IProvideClassInfo)
END_COM_MAP()
// Initially, the control's stock properties are the only
// properties supported via persistence and property pages
BEGIN_PROP_MAP(CBullsEye)
PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
PROP_ENTRY("BackColor", DISPID_BACKCOLOR, CLSID_StockColorPage)
PROP_ENTRY("BackStyle", DISPID_BACKSTYLE, CLSID_NULL)
PROP_ENTRY("Enabled", DISPID_ENABLED, CLSID_NULL)
PROP_ENTRY("ForeColor", DISPID_FORECOLOR, CLSID_StockColorPage)
END_PROP_MAP()
// Initially, enabling connection point support for a full control
// only supports property change notifications
BEGIN_CONNECTION_POINT_MAP(CBullsEye)
CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink)
END_CONNECTION_POINT_MAP()
// Initially, the control passes all Windows messages to the base class
BEGIN_MSG_MAP(CBullsEye)
CHAIN_MSG_MAP(CComControl<CBullsEye>)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
// ISupportsErrorInfo
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid)
{ // Implementation deleted for clarity. . . }
// IViewObjectEx
DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)
// IBullsEye
public:
HRESULT OnDraw(ATL_DRAWINFO& di)
{ // . . . Sample drawing code omitted for clarity }
// Initially, the only member variables are those for the stock properties
OLE_COLOR m_clrBackColor;
LONG m_nBackStyle;
BOOL m_bEnabled;
OLE_COLOR m_clrForeColor;
};
Figure 14 CStockPropImpl Properties
Stock Property |
Data Member |
APPEARANCE |
m_nAppearance |
AUTOSIZE |
m_bAutoSize |
BACKCOLOR |
m_clrBackColor |
BACKSTYLE |
m_nBackStyle |
BORDERCOLOR |
m_clrBorderColor |
BORDERSTYLE |
m_nBorderStyle |
BORDERVISIBLE |
m_bBorderVisible |
BORDERWIDTH |
m_nBorderWidth |
CAPTION |
m_bstrCaption |
DRAWMODE |
m_nDrawMode |
DRAWSTYLE |
m_nDrawStyle |
DRAWWIDTH |
m_nDrawWidth |
ENABLED |
m_bEnabled |
FILLCOLOR |
m_clrFillColor |
FILLSTYLE |
m_nFillStyle |
FONT |
m_pFont |
FORECOLOR |
m_clrForeColor |
HWND |
m_hWnd |
MOUSEICON |
m_pMouseIcon |
MOUSEPOINTER |
m_nMousePointer |
PICTURE |
m_pPicture |
READYSTATE |
m_nReadyState |
TABSTOP |
m_bTabStop |
TEXT |
m_bstrText |
VALID |
m_bValid |
Figure 15 IMPLEMENT_STOCKPROP Macro
#define IMPLEMENT_STOCKPROP(type, fname, pname, dispid) \
HRESULT STDMETHODCALLTYPE put_##fname(type pname) \
{ \
ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::put_%s\n"), _T(#fname)); \
T* pT = (T*) this; \
if (pT->FireOnRequestEdit(dispid) == S_FALSE) return S_FALSE; \
pT->m_##pname = pname; \
pT->m_bRequiresSave = TRUE; \
pT->FireOnChanged(dispid); \
pT->FireViewChange(); \
pT->SendOnDataChange(NULL); \
return S_OK; \
} \
HRESULT STDMETHODCALLTYPE get_##fname(type* p##pname) \
{ \
ATLTRACE2(atlTraceControls,2,_T("CStockPropImpl::get_%s\n"), _T(#fname)); \
T* pT = (T*) this; \
*p##pname = pT->m_##pname; \
return S_OK; \
}