(************************************************************************
*    This File is Part of the AHM Triton Tools                          *
*    for Borland Delphi and C++ Builder.                                *
*************************************************************************
* Copyright © 1995-1999 Alexander H. Mehlhorn (AHM) and Tritontools.com *
* All Rights reserved.                                                  *
*                                                                       *
*    For more Information contact us at                                 *
*    E-Mail : support@tritontools.com                                   *
*    URL : http://www.tritontools.com                                   *
*                                                                       *
*    AHM is copyright by Alexander H. Mehlhorn                          *
*    All Parts of this Collection were developed,                       *
*    designed and implemented by AHM                                    *
*                                                                       *
*    Under no Circumstances may you distribute this file                *
*    in this or any other format. This File is supplied                 *
*    as Evaluation of Source only. No Delphi Components may be developed*
*    using extracts or subsets of this code without expressed permission*
*    by AHM.                                                            *
*                                                                       *
*************************************************************************)
unit AHMTButton;
interface
{$I AHM.INC}
uses
  Windows, Messages, Classes, Graphics, Controls,AHMTBackground,
  AHMEnhancedClass,AHMControls,StdCtrls,Forms,Sysutils,Dialogs;

type
  TAHMButton = class(TButtonControl)
  private
    FAHMAboutStr : TAHMAboutEnhancedStr;
    FButtonColor: TColor;
    FActive: Boolean;
    FCanvas : TCanvas;
    Flags : Longint;
    fword : Boolean;
    F3D : TAHMFont3D;
    FAHMGlyph : TAHMGlyph;
    FButtonSunk : Boolean;
    FImage       : TBitmap;
    FBack: TAHMBackground;
    FModalResult: TModalResult;
    FDefault: Boolean;
    FCancel: Boolean;
    Procedure Set3D(value : TAHMFont3D);
    Procedure SetButtonSunk(Value : Boolean);
    Procedure SetAHMGlyph(value : TAHMGlyph);
    Procedure Setword(value : Boolean);
    Procedure GlyphChange(Sender : TObject);
    procedure DrawItem(const DrawItemStruct: TDrawItemStruct);
    procedure CMDialogKey(var Message: TCMDialogKey); message CM_DIALOGKEY;
    procedure CMDialogChar(var Message: TCMDialogChar); message CM_DialogChar;
    procedure CMFocusChanged(var Message: TCMFocusChanged); message CM_FOCUSCHANGED;
    procedure CNCommand(var Message: TWMCommand); message CN_COMMAND;
    procedure CNMeasureItem(var Message: TWMMeasureItem); message CN_MEASUREITEM;
    procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
    procedure CMEnabledChanged(var Message: TMessage); message CM_ENABLEDCHANGED;
    procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
    procedure SetFBack(const Value: TAHMBackground);
    procedure SetDefault(Value: Boolean);
    procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
  protected
    procedure Notification(AComponent: TComponent;Operation: TOperation); override;
    procedure CreateParams(var Params: TCreateParams); override;
    Procedure Click; override;
    procedure CreateWnd; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property About : TAHMAboutEnhancedStr read FAHMAboutStr write FAHMAboutStr;
    {$IFDEF AHMONLY4}
    property Anchors;
    property BiDiMode;
    property Constraints;
    property DragKind;
    property ParentBiDiMode;
    {$ENDIF}
    property Caption;
    property Cancel: Boolean read FCancel write FCancel default False;
    property Default: Boolean read FDefault write SetDefault default False;
    property Font3D   : TAHMFont3D read F3D write Set3d;
    property Glyph    : TAHMGlyph read FAHMGlyph write SetAHMGlyph;
    property ParentShowHint;
    property ShowHint;
    property Font;
    property Visible;
    property ModalResult: TModalResult read FModalResult write FModalResult default 0;
    Property WordWrap : Boolean read fword write Setword default false;
    Property ButtonSunk : Boolean read FButtonSunk write SetButtonSunk default False;
    property Background : TAHMBackground read FBack write SetFBack;
    property OnClick;
    property DragCursor;
    property ParentFont;
    property PopupMenu;
    property TabOrder;
    property TabStop;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDrag;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property OnEnter;
    property OnExit;
    property OnStartDrag;
    property Enabled;
    property Width default 100;
    property Height default 20;
  end;

implementation

Procedure TAHMButton.Createparams(var Params: TCreateParams);
begin
  Inherited Createparams(Params);
  CreateSubClass(Params, 'BUTTON');
  Params.Style := Params.Style or bs_Ownerdraw;
end;

Procedure TAHMButton.CMEnabledChanged(var Message: TMessage);
begin
  inherited;
  Repaint;
end;

procedure TAHMButton.Notification(AComponent: TComponent;Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if (Operation = opRemove) and (AComponent = Background) then SetFBack(nil);
end;


Procedure TAHMButton.SetButtonSunk(Value : Boolean);
begin
  if Value<>FButtonSunk then
  begin
    FButtonSunk:=Value;
    RecreateWnd;
  end;
end;

Procedure TAHMButton.GlyphChange(Sender : TObject);
begin
  Invalidate;
end;

constructor TAHMButton.Create(AOwner: TComponent);
Begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csSetCaption, csOpaque, csDoubleClicks];
  Width := 75;
  Height := 25;
  TabStop := True;
  FCanvas := TControlCanvas.Create;
  FImage:=TBitmap.Create;
{$IFDEF AHMINPRISE3}
  FImage.HandleType:=bmDDB;
{$ENDIF}
  Flags:=DT_Center or DT_VCenter or DT_SINGLELINE or DT_END_ELLIPSIS;
  FButtonColor := clSilver;
  FAHMGlyph:=TAHMGlyph.create(Self);
  FAHMGlyph.OnChange:=GlyphChange;
  F3D:=TAHMFont3D.create(Self);
end;

destructor TAHMButton.Destroy;
Begin
  if FBack<>nil then FBack.OList.remove(self);
  FBack:=nil;
  FAHMGlyph.OnChange:=nil;
  FCanvas.Free;
  F3D.free;
  FAHMGlyph.free;
  FImage.Free;
  inherited Destroy;
end;

procedure TAHMButton.SetAHMGlyph(value : TAHMGlyph);
begin
  FAHMGlyph.assign(value);
end;

procedure TAHMButton.Set3D(Value: TAHMFont3D);
begin
  F3D.assign(Value);
end;

procedure TAHMButton.CNCommand(var Message: TWMCommand);
begin
  if Message.NotifyCode = BN_CLICKED then Click;
end;


procedure TAHMButton.SetWord(Value: Boolean);
Begin
  if Value <> fword then
  Begin
    fword := Value;
    if fword then flags:=DT_Center or DT_VCenter or DT_Wordbreak
             else flags:=DT_Center or DT_VCenter or DT_SINGLELINE or DT_END_ELLIPSIS;
    invalidate;
  end;
end;

procedure TAHMButton.SetFBack(const Value: TAHMBackground);
begin
  if FBack<>nil then FBack.OList.remove(self);
  if value<>nil then value.additem(self);
  FBack:=Value;
  Invalidate;
end;


procedure TAHMButton.Click;
{$IFNDEF AHMINPRISE3}
var Form: TForm;
{$ELSE}
var Form: TCustomForm;
{$ENDIF}
begin
  Form := GetParentForm(Self);
  if Form <> nil then Form.ModalResult := ModalResult;
  inherited Click;
end;

procedure TAHMButton.SetDefault(Value: Boolean);
{$IFNDEF AHMINPRISE3}
var Form: TForm;
{$ELSE}
var Form: TCustomForm;
{$ENDIF}
begin
  FDefault := Value;
  if HandleAllocated then
  begin
    Form := GetParentForm(Self);
    if Form <> nil then
      Form.Perform(CM_FOCUSCHANGED, 0, Longint(Form.ActiveControl));
  end;
end;

procedure TAHMButton.CreateWnd;
begin
  inherited CreateWnd;
  FActive := FDefault;
end;

procedure TAHMButton.CMDialogKey(var Message: TCMDialogKey);
begin
  with Message do
  if  (((CharCode = VK_RETURN) and FActive) or
      ((CharCode = VK_ESCAPE) and FCancel)) and
      (KeyDataToShiftState(Message.KeyData) = []) and CanFocus then
  begin
      Click;
      Result := 1;
  end else inherited;
end;

procedure TAHMButton.WMLButtonDown(var Message: TWMLButtonDown);
begin
  DefaultHandler(Message);
end;

procedure TAHMButton.CMDialogChar(var Message: TCMDialogChar);
begin
  with Message do
  if IsAccel(CharCode, Caption) and CanFocus then
  begin
    Click;
    Result := 1;
  end else inherited;
end;


procedure TAHMButton.CMFocusChanged(var Message: TCMFocusChanged);
begin
  with Message do
  if Sender is TAHMButton then
     FActive := Sender = Self
  else
    FActive := FDefault;
  inherited;
end;

procedure TAHMButton.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
  DefaultHandler(Message);
end;

procedure TAHMButton.CNDrawItem(var Message: TWMDrawItem);
begin
  DrawItem(Message.DrawItemStruct^);
end;

procedure TAHMButton.DrawItem(const DrawItemStruct: TDrawItemStruct);
var r : TRect; x2,y2 : Integer;
    EdgeFlag : LongInt;
begin
  with DrawItemStruct do
  begin
    FCanvas.Handle := hDC;
    FCanvas.Font := Font;
    FCanvas.Brush := Brush;
    FCanvas.Brush.color:=clbtnface;
    FCanvas.Fillrect(Clientrect);
    if assigned(FBack) then FBack.draw(FCanvas.handle,width,height,true);
    r:=rect(0,0,width,height);
    if (itemState=ODA_SELECT) and Enabled then begin offsetrect(r,1,1); y2:=1; end
                   else y2:=0;
    Inflaterect(r,-3,-3);
    if caption<>'' then x2:=r.left+1 else x2:=round((width-FAHMGlyph.width)/2)+1;
    FAHMGlyph.Draw(FCanvas,X2+2,round((height-fahmglyph.height)/2)+y2,enabled,(itemState=ODA_SELECT),False);
    offsetrect(r,FAHMGlyph.width+2,0);
    r.right:=r.right-FAHMGlyph.width-2;
    if Enabled then
    begin
      if caption<>'' then F3D.write(Font,Fcanvas.handle,r,caption,flags,enabled);
    end else if caption<>'' then AHMDrawDisabledText(Font,Fcanvas,r,PChar(caption),flags);
    R:=rect(0,0,width,height);
    if (FButtonSunk) {and not(odSelected in State)} then
    begin
      EdgeFlag:=Edge_Sunken;
      DrawEdge(FCanvas.Handle,R,EdgeFlag,BF_SOFT or BF_TopLeft);
      DrawEdge(FCanvas.Handle,R,EdgeFlag,BF_Soft or BF_BottomRight);
      R:=Rect(2,2,Width-2,Height-2);
    end;
    if not(Enabled) then EdgeFlag:=Edge_Raised else
    if (itemState=ODA_SELECT) then EdgeFlag:=Edge_Sunken else EdgeFlag :=Edge_Raised;
    DrawEdge(FCanvas.Handle,R,EdgeFlag,BF_SOFT or BF_TopLeft);
    DrawEdge(FCanvas.Handle,R,EdgeFlag,BF_Soft or BF_BottomRight);
    FCanvas.Pen.Color := clWindowFrame;
    FCanvas.Brush.Color := clBtnFace;
    R:=Rect(1+Integer(FButtonSunk)*2,1+Integer(FButtonSunk)*2,Width-2-Integer(FButtonSunk)*2,height-2-Integer(FButtonSunk)*2);
    if (itemState=ODA_FOCUS) and not(itemState=ODS_DISABLED) then
    begin
        FCanvas.Pen.Color := clWindowFrame;
    FCanvas.Pen.Width := 1;
    FCanvas.Pen.Style := psSolid;
    FCanvas.Brush.Style := bsClear;
    FCanvas.Rectangle(R.Left, R.Top, R.Right, R.Bottom);
    end;
    FCanvas.Handle := 0;
  end;
end;

procedure TAHMButton.CNMeasureItem(var Message: TWMMeasureItem);
begin
  with Message.MeasureItemStruct^ do
  begin
    itemHeight := Height;
    itemWidth := width;
  end;
end;


end.

