Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Create a TGraphicControl with transparent sections 1

Status
Not open for further replies.

GreenKnight

Programmer
Nov 9, 2001
17
0
0
GB
To create a graphic component with transparent sections, add a message handler for CM_HITTEST.

This passes a point to the control, and expects an 'HT' constant return value (see the Windows unit). Return HTNOWHERE if the point is in an invisible section, or HTCLIENT if it's in the other bit.

Example:
Say I have a subclass of a TGraphicControl called TMyCircle, which displays a circle of Diameter 'fDiameter', but I want the bits outside the circle to be transparent.

When you, say, click in the circle, the TMyCircle gets a 'MouseDown' event, but if you click on the control (outside the circle) the MouseDown will be sent and handled by the control/form behind the TMyCircle.

You could also use this to create more complex shapes.
[tt]
interface

uses
Windows, Messages, Controls, Classes, Graphics, Math, SysUtils;

type
TMyCircle = class( TGraphicControl )
public
fDiameter: integer;

procedure CMHitTest(var Message: TCMHitTest); message CM_HITTEST;

procedure Paint; override;

function HitTest( const pX, pY : integer ) : boolean;

{ ... }

end;

implementation

procedure TMyCircle.CMHitTest(var Message: TCMHitTest);
begin
if Self.HitTest( Message.XPos, Message.YPos ) then
begin
Message.Result := HTCLIENT;
end
else
begin
Message.Result := HTNOWHERE;
end;
end;

function TMyCircle.HitTest(const pX, pY: integer): boolean;
var
lCentre : Double;
begin

{ pX, pY are relative to the TopLeft of the control. }
{ Only need one "lCentre" since the graphic is symmetrical. }
lCentre := Self.Width / 2;

{ Return True if twice the distance from the point to the centre is less than the diameter. }
{ Uses the Euler's distance formula. }
Result := ( 2 * Abs( Sqrt( Sqr( pX - lCentre ) + Sqr( pY - lCentre ) ) ) ) <= Self.fDiameter;

end;

procedure TMyCircle.Paint;
var
lDrawRect : TRect;
begin
{ Draw a circle within the border }
lDrawRect.Top := Self.BorderWidth;
lDrawRect.Left := Self.BorderWidth;
lDrawRect.Bottom := lDrawRect.Top + Self.fDiameter;
lDrawRect.Right := lDrawRect.Left + Self.fDiameter;

Canvas.Ellipse( lDrawRect );

end;
[/tt]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top