unit ComboDigEdit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Mask, ToolEdit;

type
  TNotation = (ntHEX,ntDEC);

  TComboDigEdit = class(TComboEdit)
  private
    FNotation:TNotation;
    FMax:Longint;
    FValue:Longint;
    FOldValue:Longint;
    { Private declarations }
    Procedure SetNotation(Avalue:TNotation);
    function  GetNotation:TNotation;
    procedure SetMaxValue(Avalue:Longint);
    procedure SetValue(Avalue:Longint);
    function  GetValue:Longint;
    procedure UpdateText;
    procedure UpdateValue;
  protected
    procedure KeyPress(var Key: Char);override;
    procedure ButtonClick; override;
    procedure Change; override;
    procedure DoExit; override;

  public
    procedure ValidateEdit;override;
    constructor Create(AOwner: TComponent); override;
  published
    property Notation:TNotation read GetNotation write SetNotation;
    property MaxValue:Longint read FMax write SetMaxvalue;
    property Value:Longint read GetValue write SetValue;
  end;

procedure Register;

implementation

{$R CDE.res}

constructor TComboDigEdit.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Text:='0';
  FValue:=0;
  FOldValue:=FValue;
  FNotation:=ntHEX;
  FMax:=$7FFFFFFF;
  Glyph.LoadFromResourceName(Hinstance,'BM_HEX');
end;

procedure TComboDigEdit.SetNotation(Avalue:TNotation);
begin
  FNotation:=Avalue;
  case FNotation of
  ntHex: Glyph.LoadFromResourceName(Hinstance,'BM_HEX');
  ntDec: Glyph.LoadFromResourceName(Hinstance,'BM_DEC');
  end;
  UpdateText;
end;


function TComboDigEdit.GetNotation:TNotation;
begin
  Result:=FNotation;
end;

procedure TComboDigEdit.SetMaxValue(Avalue:Longint);
begin
  FMax:=Avalue;
  if FMax<Value then
    value:=FMax;
end;

procedure TComboDigEdit.SetValue(Avalue:Longint);
begin
  if Avalue>FMax then
    FValue:=FMax
  else
    FValue:=Avalue;
  UpdateText;
end;

function TComboDigEdit.GetValue:Longint;
begin
//  Change;
  UpdateValue;
  Result:=FValue;
end;


procedure TComboDigEdit.UpdateText;
begin
  if Notation=ntHEX then
  begin
    Text:=Format('%x',[FValue]);
  end
  else
  begin
    Text:=IntToStr(FValue);
  end
end;

procedure TComboDigEdit.UpdateValue;
begin
  if Text='' then
  begin
    FValue:=0;
    text:='0';
    exit;
  end;
  if Notation=ntHEX then
  begin
    FValue:=StrToInt('$'+Text);
  end
  else
  begin
    FValue:=StrToInt(Text);
  end;
end;


procedure TComboDigEdit.ButtonClick;
begin
  Change;
  UpdateValue;

  if Notation=ntHEX then
    Notation:=ntDec
  else
    Notation:=ntHex;
  inherited;
end;

Procedure TComboDigEdit.Change;
begin
  inherited;
  if Text='' then exit;
  UpdateValue;
end;

Procedure TComboDigEdit.ValidateEdit;
begin
  inherited;
end;


Procedure TComboDigEdit.DoExit;
begin
  UpdateValue;
  inherited;
end;


procedure TComboDigEdit.KeyPress(var Key: Char);

  procedure Check(var Key: Char);
  var txt:string;
      FNum:Longint;
  begin
    txt:=Text;
    if SelLength<>0 then
    begin
      Delete(txt,SelStart+1,SelLength);
    end;
    Insert(Key,txt,SelStart+1);
    try
      if Notation=ntHEX then
      begin
        FNum:=StrToInt('$'+Txt);
      end
      else
      begin
        FNum:=StrToInt(Txt);
      end;
      If Cardinal(FNum)>Cardinal(FMax) then
      begin
        Key:=chr(0);
        exit;
      end;
      if Notation=ntHEX then
      begin
        if Length(txt)>Length(Format('%x',[FMax])) then
        begin
          Key:=chr(0);
          exit;
        end;
      end
      else
      begin
        if Length(txt)>Length(IntToStr(FMax)) then
        begin
          Key:=chr(0);
          exit;
        end;
      end

    except
      Key:=chr(0);
    end;
  end;

begin
  inherited;
  if Key in [Chr($20)..Chr($FF)] then
  begin
    FOldValue:=FValue;
    if Notation=ntHEX then
    begin
      if not(Key in ['0'..'9','a'..'f','A'..'F']) then
        Key:=chr(0)
      else
      begin
        if Key in ['a'..'f'] then Key:=UpperCase(Key)[1];
        Check(Key);
      end;
    end
    else
    begin
      if not (Key  in ['0'..'9']) then
        Key:=chr(0)
      else
        Check(Key);
    end;
  end;
end;


procedure Register;
begin
  RegisterComponents('Samples', [TComboDigEdit]);
end;

end.
