SAMPLE: Deriving an OLE Control from a Base ControlID: Q141489
|
The Shapes32.exe sample illustrates deriving an OLE control from another.
The following file is available for download from the Microsoft
Software Library:
Shapes32.exeFor more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:
Q119591 How to Obtain Microsoft Support Files from Online Services
The SHAPES32 sample illustrates deriving an OLE control from a base
control, thus allowing the derived control to take advantage of the base
control's methods, properties, and events.
The SHAPES32 sample implements a base control class called CBaseShapeCtrl,
and two derived control classes called CCircleCtrl and CRectangleCtrl.
CCircleCtrl and CRectangleCtrl draw themselves using the properties
provided by the base CBaseShapeCtrl class. CCircleCtrl and CRectangleCtrl
also allow access to the methods and events implemented in the base
CBaseShapeCtrl class.
Name Type Use
------------ --------- ---------------------------------------------------
FillColor Property An OLE_COLOR value which represents the color
used
to fill the shape.
LineColor Property An OLE_COLOR value which represents the color
used
for the shape's outline.
LineWidth Property A short value which represents the line width in
pixels of the shape's outline.
BaseMethod1 Method A test method which, when invoked, fires the
BaseEvent1 event. Takes a single parameter of type
long.
BaseMethod2 Method A test method which, when invoked, fires the
BaseEvent2 event. Takes a single parameter of type
BSTR.
BaseEvent1 Event A test event. Returns a long.
BaseEvent2 Event A test event. Returns a BSTR.
The CCircleCtrl class provides the functionality of a simple circle
control.
Name Type Use
------------- --------- ---------------------------------------------------
CircleShape Property A boolean value. If TRUE the control draws
itself
as a circle, if FALSE it draws itself as an
ellipse.
CircleOffset Property A short value which represents the number of
pixels offset from the center of the bounding
rectangle at which the control will draw itself.
CircleMethod1 Method A test method which, when invoked, fires the
CircleEvent1 event. Takes a single parameter of
type long.
CircleMethod2 Method A test method which, when invoked, fires the
CircleEvent2 event. Takes a single parameter of
type long.
CircleEvent1 Event A test event. Returns a long.
CircleEvent2 Event A test event. Returns a long.
The CRectangleCtrl class provides the functionality of a simple rectangle
control. It implements the following properties, events, and methods:
Name Type Use
-------------- --------- ---------------------------------------------------
RoundedCorners Property A boolean value. If TRUE the control draws
itself with rounded corners, if FALSE it draws
itself with square corners.
RectangleInset Property A short value which represents the number of
pixels inside the control's bounding rectangle
by which the control will inset itself.
RectMethod1 Method A test method which, when invoked, fires the
RectEvent1 event. Takes no parameters.
RectMethod2 Method A test method which, when invoked, fires the
RectEvent2 event. Takes no parameters.
RectEvent1 Event A test event. Returns void.
RectEvent2 Event A test event. Returns void.
BEGIN_MESSAGE_MAP(CBaseShapeCtrl, COleControl)
//{{AFX_MSG_MAP(CBaseShapeCtrl)
//}}AFX_MSG_MAP
//ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()
If this isn't done, control containers will list the Properties... verb
twice when the Edit | Control Object menu is selected.
BOOL CBaseShapeCtrl::CBaseShapeCtrlFactory::UpdateRegistry(BOOL
bRegister)
{
return TRUE;
}
If this isn't done the base control will get registered and containers
will list it along with the derived controls when the user attempts to
insert a new control.
BOOL CBaseShapePropPage::CBaseShapePropPageFactory::UpdateRegistry(
BOOL bRegister)
{
return TRUE;
}
If this isn't done the base class control's property page will get
registered and will appear in the registry.
CBaseShapeCtrl::CBaseShapeCtrl()
{
//InitializeIIDs(&IID_DBaseShape, &IID_DBaseShapeEvents);
// TODO: Initialize your control's instance data here.
}
If this isn't done there will be a memory leak upon termination when
the cached type information for the base class does not get freed.
void CBaseShapeCtrl::DoPropExchange(CPropExchange* pPX)
{
// ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
...
}
The _Version property is serialized via a call to the ExchangeVersion
method in the DoPropExchange method of the derived control.
void CCircleCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
CBaseShapeCtrl::DoPropExchange(pPX);
...
}
// Primary dispatch interface for CCircleCtrl
[ uuid(A7EC6760-BFED-11CE-8250-524153480001),
helpstring("Dispatch interface for sample Circle Control"), hidden ]
dispinterface _DCircle
{
properties:
// NOTE - ClassWizard will maintain property information here.
// Use extreme caution when editing this section.
//{{AFX_ODL_PROP(CCircleCtrl)
[id(65537)] OLE_COLOR FillColor;
[id(65538)] OLE_COLOR LineColor;
[id(65539)] short LineWidth;
[id(1)] boolean CircleShape;
[id(2)] short CircleOffset;
//}}AFX_ODL_PROP
...
The FillColor, LineColor, and LineWidth properties implemented in the base
class have DISPID's of 1, 2, and 3 respectively. Once the HIWORD portion
of these DISPID's has been adjusted they become 65537, 65538, and 65539.
[ uuid(A7EC6761-BFED-11CE-8250-524153480001),
helpstring("Event interface for sample Circle Control") ]
dispinterface _DCircleEvents
{
properties:
// Event interface has no properties
methods:
// NOTE - ClassWizard will maintain event information here.
// Use extreme caution when editing this section.
//{{AFX_ODL_EVENT(CCircleCtrl)
[id(1)] void BaseEvent1(long lParam);
[id(2)] void BaseEvent2(BSTR pszString);
[id(3)] void CircleEvent1(long lParam);
[id(4)] void CircleEvent2(long lParam);
//}}AFX_ODL_EVENT
};
Manually updating the DISPIDs can be problematic because ClassWizard may
get confused when it sees the entries for the events in the base class.
It's possible that more than one event may be assigned the same DISPID.
After adding new events to a derived class, inspect the project's .ODL
file and fix any conflicts.
class CCircleCtrl : public CBaseShapeCtrl
{
...
// Dispatch and event IDs
public:
enum {
//{{AFX_DISP_ID(CCircleCtrl)
//dispidFillColor = 65537L,
//dispidLineColor = 65538L,
//dispidLineWidth = 65539L,
//dispidBaseMethod1 = 65540L,
//dispidBaseMethod2 = 65541L,
dispidCircleShape = 1L,
dispidCircleOffset = 2L,
dispidCircleMethod1 = 3L,
dispidCircleMethod2 = 4L,
//eventidBaseEvent1 = 1L,
//eventidBaseEvent2 = 2L,
eventidCircleEvent1 = 3L,
eventidCircleEvent2 = 4L,
//}}AFX_DISP_ID
};
SHAPES is based on a ControlWizard generated OLE control. Files included
with the sample which are directly related to deriving an OLE control from
a base control are:MFC Technical Note #39
Additional query words: Shapes Shapes2
Keywords : kbcode kbole kbsample kbMFC kbVC
Version : 4.0 4.1
Platform : NT WINDOWS
Issue type :
Last Reviewed: August 5, 1999