unit arrowbtn; {******************************************************************** TArrowButton component for Delphi Author: Kent Miller Frederick, MD Compuserve: 74113,200 Freeware: Feel free to use and improve I welcome any comments or suggestions that you may have, however I am new to creating components so please be gentle. *********************************************************************} interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs; type TButtonDirection = (arwUP, arwRIGHT, arwLEFT, arwDOWN); TArrowButton = class(TGraphicControl) private kDirection: TButtonDirection; kButtonColor: TColor; kButtonDown: boolean; kpnts: array[1..3] of TPoint; kRgn: HRgn; procedure SetDirection(value: TButtonDirection); procedure SetButtonColor(value: TColor); procedure FreeRegion; protected procedure Paint; override; procedure DrawUpArrow; procedure DrawRightArrow; procedure DrawDownArrow; procedure DrawLeftArrow; procedure MoveButton; virtual; procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN; procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property ButtonColor: TColor read kButtonColor write SetButtonColor; property Direction: TButtonDirection read kDirection write SetDirection; property Enabled; property ParentShowHint; property ShowHint; property Visible; property OnClick; end; procedure Register; implementation const { offset from border of control to corner of button } S_OFFSET = 3; constructor TArrowButton.Create(AOwner: TComponent); begin inherited Create(AOwner); ControlStyle := [csClickEvents, csCaptureMouse]; Width := 33; Height := 33; kDirection := arwUP; kButtonColor := clTeal; kRgn := 0; kButtonDown := False; end; destructor TArrowButton.Destroy; begin if kRgn <> 0 then FreeRegion; inherited Destroy; end; procedure TArrowButton.Paint; begin inherited Paint; FreeRegion; case kDirection of arwUP: DrawUpArrow; arwRIGHT: DrawRightArrow; arwDOWN: DrawDownArrow; arwLEFT: DrawLeftArrow; end; end; procedure TArrowButton.DrawUpArrow; begin Canvas.Brush.Color := clBlack; Canvas.Pen.Color := clBlack; { create border region for button } kpnts[1] := Point(Width div 2, S_OFFSET); kpnts[2] := Point(Width - S_OFFSET, Height - S_OFFSET); kpnts[3] := Point(S_OFFSET, Height - S_OFFSET); { save region to capture mouse clicks } kRgn := CreatePolygonRgn(kpnts, 3, ALTERNATE); { draw black border around button } FrameRgn(Canvas.Handle, kRgn, Canvas.Brush.Handle, 2, 2); { create region within black border for button } Inc(kpnts[1].Y, 3); Dec(kpnts[2].X, 4); Dec(kpnts[2].Y, 2); Inc(kpnts[3].X, 3); Dec(kpnts[3].Y, 2); Canvas.Brush.Color := kButtonColor; { draw button } Canvas.Polygon(kpnts); MoveButton; end; procedure TArrowButton.DrawRightArrow; begin Canvas.Brush.Color := clBlack; Canvas.Pen.Color := clBlack; kpnts[1] := Point(S_OFFSET, S_OFFSET); kpnts[2] := Point(Width - S_OFFSET, Height div 2); kpnts[3] := Point(S_OFFSET, Height - S_OFFSET); kRgn := CreatePolygonRgn(kpnts, 3, ALTERNATE); FrameRgn(Canvas.Handle, kRgn, Canvas.Brush.Handle, 2, 2); Inc(kpnts[1].X, 2); Inc(kpnts[1].Y, 3); Dec(kpnts[2].X, 3); Inc(kpnts[3].X, 2); Dec(kpnts[3].Y, 3); Canvas.Brush.Color := kButtonColor; Canvas.Polygon(kpnts); MoveButton; end; procedure TArrowButton.DrawDownArrow; begin Canvas.Brush.Color := clBlack; Canvas.Pen.Color := clBlack; kpnts[1] := Point(Width - S_OFFSET, S_OFFSET); kpnts[2] := Point(Width div 2, Height - S_OFFSET); kpnts[3] := Point(S_OFFSET, S_OFFSET); kRgn := CreatePolygonRgn(kpnts, 3, ALTERNATE); FrameRgn(Canvas.Handle, kRgn, Canvas.Brush.Handle, 2, 2); Dec(kpnts[1].X, 3); Inc(kpnts[1].Y, 2); Dec(kpnts[2].Y, 3); Inc(kpnts[3].X, 2); Inc(kpnts[3].Y, 2); Canvas.Brush.Color := kButtonColor; Canvas.Polygon(kpnts); MoveButton; end; procedure TArrowButton.DrawLeftArrow; begin Canvas.Brush.Color := clBlack; Canvas.Pen.Color := clBlack; kpnts[1] := Point(Width - S_OFFSET, S_OFFSET); kpnts[2] := Point(Width - S_OFFSET, Height - S_OFFSET); kpnts[3] := Point(S_OFFSET, Height div 2); kRgn := CreatePolygonRgn(kpnts, 3, ALTERNATE); FrameRgn(Canvas.Handle, kRgn, Canvas.Brush.Handle, 2, 2); Dec(kpnts[1].X, 2); Inc(kpnts[1].Y, 3); Dec(kpnts[2].X, 2); Dec(kpnts[2].Y, 2); Inc(kpnts[3].X, 3); Canvas.Brush.Color := kButtonColor; Canvas.Polygon(kpnts); MoveButton; end; procedure TArrowButton.MoveButton; begin if not kButtonDown then { button is in up position } with Canvas do begin { draw lines around button for raised look } Pen.Color := clBlack; MoveTo(kpnts[1].X, kpnts[1].Y); LineTo(kpnts[2].X, kpnts[2].Y); MoveTo(kpnts[2].X, kpnts[2].Y); LineTo(kpnts[3].X, kpnts[3].Y); Pen.Color := clWhite; MoveTo(kpnts[1].X, kpnts[1].Y); LineTo(kpnts[3].X, kpnts[3].Y); end else { button is in down position } with Canvas do begin { draw lines around button for sunken look } Pen.Color := clBlack; MoveTo(kpnts[1].X, kpnts[1].Y); LineTo(kpnts[3].X, kpnts[3].Y); Pen.Color := kButtonColor; MoveTo(kpnts[1].X, kpnts[1].Y); LineTo(kpnts[2].X, kpnts[2].Y); MoveTo(kpnts[2].X, kpnts[2].Y); LineTo(kpnts[3].X, kpnts[3].Y); end; end; procedure TArrowButton.SetDirection(value: TButtonDirection); begin if value <> kDirection then begin kDirection := value; Invalidate; end; end; procedure TArrowButton.SetButtonColor(value: TColor); begin if value <> kButtonColor then begin kButtonColor := value; Invalidate; end; end; procedure TArrowButton.FreeRegion; begin if kRgn <> 0 then DeleteObject(kRgn); kRgn := 0; end; procedure TArrowButton.WMLButtonDown(var Message: TWMLButtonDown); begin { if mouse is clicked on the arrowbutton make it appear sunken } if not PtInRegion(kRgn, Message.xPos, Message.yPos) then Exit; kButtonDown := True; MoveButton; inherited; end; procedure TArrowButton.WMLButtonUp(var Message: TWMLButtonUp); begin { if arrowbutton is down and mouse is released then make arrowbutton appear raised } if not kButtonDown then Exit; kButtonDown := False; MoveButton; inherited; end; procedure Register; begin RegisterComponents('Samples', [TArrowButton]); end; end.