The rule governing the Circle control flash behavior is that the circle should flash only if the mouse is within the circular area of the control. To achieve this effect, you must implement "hit testing," which checks the coordinates of every mouse click within the control to see if they are within the circle. Hit testing is implemented in the Circle control by the InCircle
function. InCircle
returns TRUE if the given point is within the area of the circle or the ellipse.
To implement the InCircle function
The Add Member Function dialog box is displayed.
BOOL
. This is the type of value the function will return.InCircle(CPoint& point)
.This will add the following declaration in the protected section of CIRCCTL.H:
BOOL InCircle(CPoint& point);
It will also add a function definition at the end of CIRCCTL.CPP and position the cursor in the function:
BOOL CCircCtrl::InCircle(CPoint& point)
{
}
BOOL CCircCtrl::InCircle(CPoint& point)
{
CRect rc;
GetClientRect(rc);
GetDrawRect(&rc);
// Determine radii
double a = (rc.right - rc.left) / 2;
double b = (rc.bottom - rc.top) / 2;
// Determine x, y
double x = point.x - (rc.left + rc.right) / 2;
double y = point.y - (rc.top + rc.bottom) / 2;
// Apply ellipse formula
return ((x * x) / (a * a) + (y * y) / (b * b) <= 1);
}
The function works by calculating whether the point is within the boundary of the ellipse. The GetDrawRect
function is called to make the necessary adjustments to the bounding rectangle if the value of the CircleShape property is TRUE.
The variables a
and b
are set to the horizontal and vertical radii of the ellipse. Based on the given point, the variables x
and y
are translated into the coordinates that are offsets from the center of the ellipse. The last line returns the Boolean result of the calculation, using the standard formula for an ellipse. Note that this calculation is also valid for a circle because a circle is simply a special case of an ellipse.
The mouse message handlers perform hit testing by passing the point coordinates that they receive as parameters to the InCircle
member function. If InCircle
returns TRUE, the circle is painted appropriately.