For our "Circle" control, we will add an event called
"ClickIn". This event will be fired from the control whenever an user clicks
inside its circular area.
To do this, we will invoke the "Add
Event to C++ Control" dialog by clicking the right mouse button on the control
toolbutton (in the RadVC toolbox) and then selecting "Add Event" context menu
item:
"ClickIn" Event |
Circle.h |
Circle.cpp |
struct msgClickIn
{
short nX;
short nY;
};
class CCircle : public CWnd
{
...
//Events
//{{AFX_CTRL_EVENT_DEF_START
long FireClickIn(short nX, short nY);
//}}AFX_CTRL_EVENT_DEF_END
...
public:
enum eCircleEvents
{
ClickIn = 1L,
};
}; |
long CCircle::FireClickIn(short nX, short nY)
{
msgClickIn msg;
msg.nX = nX;
msg.nY = nY;
return FireCppEvent(ClickIn, (LPARAM)&msg);
} |
If
we decided our "ClickIn" event only to have one parameter (short nX) instead of
two, then the event code would look a lot simpler as follows: |
class CCircle : public CWnd
{
...
//Events
//{{AFX_CTRL_EVENT_DEF_START
long FireClickIn(short nX);
//}}AFX_CTRL_EVENT_DEF_END
...
public:
enum eCircleEvents
{
ClickIn = 1L,
};
}; |
long CCircle::FireClickIn(short nX)
{
return FireCppEvent(ClickIn, (LPARAM)nX);
} |
The
event code would have gotten even simpler if we decided not to have any parameters at
all.. |
class CCircle : public CWnd
{
...
//Events
//{{AFX_CTRL_EVENT_DEF_START
long FireClickIn();
//}}AFX_CTRL_EVENT_DEF_END
...
public:
enum eCircleEvents
{
ClickIn = 1L,
};
}; |
long CCircle::FireClickIn()
{
return FireCppEvent(ClickIn, 0);
} |
Firing Event:
"ClickIn" event
will be fired from our control whenever the user clicks inside the circle boundary. Thus
to fire this event from the control, we need to respond to Windows WM_LBUTTONDOWN message
on the control and call "FireClickIn(..)" function.
To add a WM_LBUTTONDOWN
message handler for the control, we need to invoke the Class Wizard by simply pressing
CTRL+W or selecting "Class Wizard" menu item from the Developer Studio's
"View" menu. This will display the "MFC ClassWizard" dialog box as
shown below:
- In this dialog box,
-
- (1) Select "CCircle" in the
class name combo box.
- (2) Select "WM_LBUTTONDOWN" in
the listbox called "Messages".
- (3) Click on the "Add Function"
button. This will add a new item in the listbox called "Member Functions for the
message handler "OnLButtonDown".
- (4) Click "OK" to finish adding
the message handler.
The "ClassWizard" will now open
the implementation source file for the control called "Circle.cpp" and
highlights the handler function body:
- void CCircle::OnLButtonDown(UINT nFlags,
CPoint point)
{
- // TODO: Add your
message handler code here and/or call default
CWnd::OnLButtonDown(nFlags, point);
}
Add the following code to
fire the "ClickIn" event from the "WM_LBUTTONDOWN" message handler.
void
CCircle::OnLButtonDown(UINT nFlags, CPoint point)
{
if(InCircle(point))
FireClickIn((short)point.x, (short)point.y);
CWnd::OnLButtonDown(nFlags, point);
}
For this example the event
is to be fired only when the click occurs inside a circular or elliptical region within
the control. To determine this we have used a helper function called "InCircle":
Circle.h |
Circle.cpp |
class CCircle : public CWnd
{
..
BOOL
InCircle(CPoint point);
..
..
}; |
BOOL
CCircle::InCircle(CPoint point)
{
CRect rect;
GetClientRect(rect);
// Determine radii
double a = (rect.right - rect.left) / 2;
double b = (rect.bottom - rect.top) / 2;
// Determine x, y
double x = point.x - (rect.left + rect.right) / 2;
double y = point.y - (rect.top + rect.bottom) / 2;
// Apply ellipse formula
return (((x * x) / (a * a) + (y * y) / (b * b)) <= 1);
} |
You need to add the
following declaration of the "Incircle" function to your control's .H file.
Next >> Part
7: Adding a Method to the Control
Related Links:
|