home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 April / Chip_2002-04_cd1.bin / zkuste / delphi / kolekce / d3456 / PBEDIT.ZIP / PBBinHexEdit.pas < prev    next >
Pascal/Delphi Source File  |  2002-01-19  |  14KB  |  511 lines

  1. {Author:    Poul Bak}
  2. {}
  3. {Copyright ⌐ 1999 - 2002 : BakSoft-Denmark (Poul Bak). All rights reserved.}
  4. {}
  5. {http://home11.inet.tele.dk/BakSoft/}
  6. {Mailto: baksoft-denmark@dk2net.dk}
  7. {}
  8. {Component Version: 6.00.00.00}
  9. {}
  10. {PBBinHexEdit is a special Edit-component for Binary, Hexadecimal and integer
  11.  editing, display and conversion.}
  12. {}
  13. {Supports Windows 95, 98 and NT.}
  14. {Supports Default-Button click.}
  15. {Supports Cancel-button click.}
  16.  
  17. unit PBBinHexEdit;
  18.  
  19. interface
  20.  
  21. uses
  22.     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  23.     StdCtrls;
  24.  
  25. type
  26. {Number = standard integer format.}
  27. {Binary = number with only 0 and 1 like '0110'.
  28. {HexaDecimal = number with hexadecimal format like $7FFFFFFF.}
  29.     TBaseFormat = (Number, Binary, HexaDecimal);
  30.  
  31. {Author:    Poul Bak}
  32. {}
  33. {Copyright ⌐ 1999 - 2002 : BakSoft-Denmark (Poul Bak). All rights reserved.}
  34. {}
  35. {http://home11.inet.tele.dk/BakSoft/}
  36. {Mailto: baksoft-denmark@dk2net.dk}
  37. {}
  38. {Component Version: 6.00.00.00}
  39. {}
  40. {PBBinHexEdit is a special Edit-component for Binary, Hexadecimal and integer
  41.  editing, display and conversion.}
  42. {}
  43. {Supports Windows 95, 98 and NT.}
  44. {Supports Default-Button click.}
  45. {Supports Cancel-button click.}
  46.     TPBBinHexEdit = class(TCustomEdit)
  47.     private
  48.         { Private declarations }
  49.         FAlignment: TAlignment;
  50.         FBaseFormat : TBaseFormat;
  51.         FEnter : Boolean;
  52.         FInvalidEntry: TNotifyEvent;
  53.         FMaxValue: Integer;
  54.         FMinValue: Integer;
  55.         FVersion: String;
  56.         function BinToInt(B : string): integer;
  57.         function FormatText(Value: Integer; NFormat: TBaseFormat): string;
  58.         function GetAsInteger: Integer;
  59.         function GetAsBin: string;
  60.         function GetAsHex: string;
  61.         function IntToBin(I : integer): string;
  62.         procedure InvalidEntry;
  63.         procedure SetAlignment(Value: TAlignment);
  64.         procedure SetAsInteger(Value: Integer);
  65.         procedure SetAsBin(Value: string);
  66.         procedure SetAsHex(Value: string);
  67.         procedure SetBaseFormat(Value: TBaseFormat);
  68.         procedure SetMaxValue(Value: Integer);
  69.         procedure SetMinValue(Value: Integer);
  70.         procedure SetVersion(Value: String);
  71.         procedure WMGetDlgCode(var Msg : TWMGetDlgCode); message WM_GETDLGCODE;
  72.         procedure WMPaste(var Message: TMessage); message WM_PASTE;
  73.     protected
  74.         { Protected declarations }
  75.         procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  76.         procedure DoEnter; override;
  77.         procedure DoExit; override;
  78.         procedure KeyDown(var Key: Word; Shift: TShiftState); override;
  79.         procedure KeyPress(var Key: Char); override;
  80.         procedure KeyUp(var Key: Word; Shift: TShiftState); override;
  81.     public
  82.         { Public declarations }
  83.         constructor Create(AOwner: TComponent); override;
  84.         procedure CreateParams(var Params: TCreateParams); override;
  85.     published        { Published declarations }
  86. {Set Alignment to: taLeftJustify, taCenter or taRightJustify.}
  87. {Default : taLeftJustify.}
  88. {Supports Windows 95, 98 and NT.}
  89.         property Alignment: TAlignment read FAlignment write SetAlignment;
  90. {Set or access the value as a binary string: 1010101010}
  91.         property AsBin: string read GetAsBin write SetAsBin;
  92. {Set or access the value as an integer type (normal number)}
  93.         property AsInteger: Integer read GetAsInteger write SetAsInteger;
  94. {Set or access the value as a Hexadecimal string: $FFFFFFFF}
  95.         property AsHex: string read GetAsHex write SetAsHex;
  96. {Default: True.}
  97. {Set AutoSelect to True to select all text when you set focus:}
  98. {Notice that when you set focus using the mouse, all text is also selected -
  99. unlike standard Delphi components that only selects all when setting focus with <tab>.}
  100. {When a form has a defaultbutton and you press <enter>, the click event
  101. triggers and focus is returned to the edit control which autoselects all.}
  102.         property AutoSelect;
  103.         property AutoSize;
  104. {BaseFormat is the edit- and displaytype}
  105.         property BaseFormat: TBaseFormat read FBaseFormat write SetBaseFormat;
  106.         property BorderStyle;
  107.         property Color;
  108.         property Ctl3D;
  109.         property DragCursor;
  110.         property DragMode;
  111.         property Enabled;
  112.         property Font;
  113.         property HideSelection;
  114.         property MaxLength;
  115. {Set MaxValue to prevent users from entering values greater than MaxValue.
  116. OnInvalidEntry triggers when the edit component looses focus.
  117. When MaxValue and MinValue are both zero, they have no effect.}
  118.         property MaxValue: Integer read FMaxValue write SetMaxValue;
  119. {Set MinValue to prevent users from entering values less than MinValue.
  120. OnInvalidEntry triggers when the edit component looses focus.
  121. When MaxValue and MinValue are both zero, they have no effect.}
  122.         property MinValue: Integer read FMinValue write SetMinValue;
  123.         property OnChange;
  124.         property OnClick;
  125.         property OnDblClick;
  126.         property OnDragDrop;
  127.         property OnDragOver;
  128.         property OnEndDrag;
  129.         property OnEnter;
  130.         property OnExit;
  131. {Is called when the user enters a value greater than MaxValue or smaller
  132. than MinValue.}
  133.         property OnInvalidEntry: TNotifyEvent read FInvalidEntry write FInvalidEntry;
  134.         property OnKeyDown;
  135.         property OnKeyPress;
  136.         property OnKeyUp;
  137.         property OnMouseDown;
  138.         property OnMouseMove;
  139.         property OnMouseUp;
  140.         property OnStartDrag;
  141.         property ParentColor;
  142.         property ParentCtl3D;
  143.         property ParentFont;
  144.         property ParentShowHint;
  145.         property PopupMenu;
  146.         property ReadOnly;
  147.         property ShowHint;
  148.         property TabOrder;
  149.         property TabStop;
  150. {Read only}
  151.         property Version: String read FVersion write SetVersion;
  152. {Set Visible to False if you just need the conversion routines.}
  153.         property Visible;
  154.     end;
  155.  
  156. procedure Register;
  157.  
  158. implementation
  159.  
  160. uses Clipbrd;
  161.  
  162. constructor TPBBinHexEdit.Create(AOwner: TComponent);
  163. begin
  164.     inherited Create(AOwner);
  165.     Width := 100;
  166.     FAlignment := taCenter;
  167.     FEnter := False;
  168.     FMaxValue := 0;
  169.     FMinValue := 0;
  170.     FBaseFormat := HexaDecimal;
  171.     FVersion := '6.00.00.00';
  172.     AsInteger := 0;
  173.     Text := FormatText(0, FBaseFormat);
  174. end;
  175.  
  176. procedure TPBBinHexEdit.CreateParams(var Params: TCreateParams);
  177. const
  178.     Alignments: array[TAlignment] of Word = (ES_LEFT, ES_RIGHT, ES_CENTER);
  179. begin
  180.     inherited CreateParams(Params);
  181.     Params.Style := Params.Style or ES_MULTILINE or Alignments[FAlignment];
  182. end;
  183.  
  184. procedure TPBBinHexEdit.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  185. begin
  186.     inherited MouseDown(Button, Shift, X, Y);
  187.     if (Button = mbLeft) or (ssLeft in Shift) then
  188.     begin
  189.         if FEnter = True then
  190.         begin
  191.             FEnter := False;
  192.             if AutoSelect then SelectAll;
  193.         end;
  194.     end;
  195. end;
  196.  
  197. procedure TPBBinHexEdit.DoEnter;
  198. begin
  199.     inherited DoEnter;
  200.     if csLButtonDown in ControlState then FEnter := True;
  201.     if AutoSelect then SelectAll;
  202. end;
  203.  
  204. procedure TPBBinHexEdit.DoExit;
  205. begin
  206.     inherited DoExit;
  207.     if (FMinValue <> 0) and (FMaxValue <> 0)
  208.         and ((AsInteger < FMinValue) or (AsInteger > FMaxValue)) then InvalidEntry;
  209. end;
  210.  
  211. procedure TPBBinHexEdit.KeyDown(var Key: Word; Shift: TShiftState);
  212. begin
  213.     inherited KeyDown(Key, Shift);
  214.     FEnter := False;
  215.     if not ReadOnly then
  216.     begin
  217.         if Key in [VK_DELETE] then if (SelStart = 0)
  218.             and ((Text[1] in ['$']) or (SelLength = length(Text))) then
  219.         begin
  220.             if (FBaseFormat = HexaDecimal) then
  221.             begin
  222.                 Text := '$0';
  223.                 SelStart := 1;
  224.             end
  225.             else
  226.             begin
  227.                 Text := '0';
  228.                 SelStart := 0;
  229.             end;
  230.             Key := 0;
  231.             SelLength := 1;
  232.         end;
  233.     end;
  234. end;
  235.  
  236. procedure TPBBinHexEdit.KeyUp(var Key: Word; Shift: TShiftState);
  237. begin
  238.     inherited KeyUp(Key, Shift);
  239.     if not ReadOnly then
  240.     begin
  241.         if (FBaseFormat = HexaDecimal) then
  242.         begin
  243.             if (Text = '') or (Text = '$') then
  244.             begin
  245.                 Text := '$0';
  246.                 SelStart := 1;
  247.                 SelLength := 1;
  248.             end
  249.             else if Text[1] <> '$' then
  250.             begin
  251.                 Text := '$' + Text;
  252.                 SelStart := SelStart + 2;
  253.                 SelLength := 0;
  254.             end;
  255.         end
  256.         else if Text = '' then
  257.         begin
  258.             Text := '0';
  259.             SelStart := 0;
  260.             SelLength := 1;
  261.         end;
  262.     end;
  263. end;
  264.  
  265. procedure TPBBinHexEdit.KeyPress(var Key: Char);
  266. var
  267.     Fl : Extended;
  268. begin
  269.     if (Key in [#13, #27]) then
  270.     begin
  271.         MessageBeep(0);
  272.         Key := #0;
  273.         Exit;
  274.     end;
  275.     inherited KeyPress(Key);
  276.     if Key in [#3] then Exit;
  277.     if ReadOnly then
  278.     begin
  279.         MessageBeep(0);
  280.         Key := #0;
  281.         Exit;
  282.     end;
  283.     if (Key in [#8, #22, #24]) then Exit
  284.     else if (FBaseFormat = HexaDecimal) then
  285.     begin
  286.         if Key in ['a'..'f'] then Key := Chr(Ord(Key) - 32);
  287.         if (Key in ['$']) then
  288.         begin
  289.             Text := '$0';
  290.             Key := #0;
  291.             SelStart := 1;
  292.             SelLength := 1;
  293.         end
  294.         else if not (Key in ['0'..'9','A'..'F']) then Key := #0
  295.         else if (Length(Text) >= 9) and (SelStart >= 9) then Key := #0
  296.         else if (Length(Text) >= 9) and (SelLength = 0) then
  297.         begin
  298.             if (SelStart < 1) then SelStart := 1;
  299.             SelLength := 1;
  300.         end;
  301.     end
  302.     else if (FBaseFormat = Binary) then
  303.     begin
  304.         if not (Key in ['0','1']) then Key := #0
  305.         else if (Length(Text) >= 32) and (SelStart >= 32) then Key := #0
  306.         else if (Length(Text) >= 32) and (SelLength = 0) then SelLength := 1;
  307.     end
  308.     else
  309.     begin
  310.         if not (Key in ['0'..'9','-']) then Key := #0
  311.         else if (Key = '-') and (pos('-', Text) = 0) then SelStart := 0
  312.         else if (Key = '-') and (pos('-', Text) = 1) then
  313.         begin
  314.             Text := copy(Text, 2, Length(Text) - 1);
  315.             Key := #0;
  316.         end
  317.         else if (((Length(Text) >= 10) and (Pos('-', Text) = 0))
  318.             or (Length(Text) >= 11)) and (SelStart >= 10) then Key := #0
  319.         else if (((Length(Text) >= 10) and (Pos('-', Text) = 0))
  320.             or (Length(Text) >= 11)) and (SelLength = 0) then SelLength := 1
  321.         else
  322.         begin
  323.             if (SelStart < 1) and (Text[1] = '-') and (SelLength = 0) then SelStart := 1;
  324.             Fl := StrToFloat(copy(Text, 1, SelStart) + Key + copy(Text,
  325.                 SelStart + SelLength + 1, Length(Text) - SelStart - SelLength - 1));
  326.             if (Fl > 2147483647.0) or (Fl < -2147483648.0) then Key := #0;
  327.         end;
  328.     end;
  329. end;
  330.  
  331. function TPBBinHexEdit.GetAsInteger: Integer;
  332. begin
  333.     if (FBaseFormat = Binary) then Result :=  BinToInt(Text)
  334.     else Result := StrToInt(Text);
  335. end;
  336.  
  337. function TPBBinHexEdit.GetAsBin: string;
  338. begin
  339.     Result := FormatText(AsInteger, Binary);
  340. end;
  341.  
  342. function TPBBinHexEdit.GetAsHex: string;
  343. begin
  344.     Result := FormatText(AsInteger, HexaDecimal);
  345. end;
  346.  
  347. procedure TPBBinHexEdit.SetAsInteger(Value: Integer);
  348. begin
  349.     if csDesigning in ComponentState then
  350.     begin
  351.         If (Value > FMaxValue) and ((FMaxValue <> 0) or (FMinValue <> 0)) then InvalidEntry;
  352.         If (Value < FMinValue) and ((FMaxValue <> 0) or (FMinValue <> 0)) then InvalidEntry;
  353.     end;
  354.     if Text <> FormatText(Value, FBaseFormat) then Text := FormatText(Value, FBaseFormat);
  355. end;
  356.  
  357. procedure TPBBinHexEdit.SetAsBin(Value: string);
  358. begin
  359.     if AsInteger <> BinToInt(Value) then AsInteger := BinToInt(Value);
  360. end;
  361.  
  362. procedure TPBBinHexEdit.SetAsHex(Value: string);
  363. begin
  364.     if AsInteger <> StrToInt(Value) then AsInteger := StrToInt(Value);
  365. end;
  366.  
  367. procedure TPBBinHexEdit.SetAlignment(Value: TAlignment);
  368. var
  369.     SelSt, SelLe : integer;
  370. begin
  371.     if FAlignment <> Value then
  372.     begin
  373.         SelSt := SelStart;
  374.         SelLe := SelLength;
  375.         FAlignment := Value;
  376.         RecreateWnd;
  377.         SelStart := SelSt;
  378.         SelLength := SelLe;
  379.     end;
  380. end;
  381.  
  382. procedure TPBBinHexEdit.SetMaxValue(Value: Integer);
  383. begin
  384.     if (FMaxValue <> Value) and (Value >= FminValue) then
  385.     begin
  386.         FMaxValue := Value;
  387.     end;
  388. end;
  389.  
  390. procedure TPBBinHexEdit.SetMinValue(Value: Integer);
  391. begin
  392.     if (FMinValue <> Value) and (Value <= FmaxValue) then
  393.     begin
  394.         FMinValue := Value;
  395.     end;
  396. end;
  397.  
  398. procedure TPBBinHexEdit.InvalidEntry;
  399. begin
  400.     if assigned(FInvalidEntry) then FInvalidEntry(Self)
  401.     else Application.MessageBox('Value out of range!', 'Invalid Entry', MB_ICONWARNING + MB_OK);
  402. end;
  403.  
  404. procedure TPBBinHexEdit.SetVersion(Value: String);
  405. begin
  406.     { Read only! }
  407. end;
  408.  
  409. procedure TPBBinHexEdit.SetBaseFormat(Value: TBaseFormat);
  410. var
  411.     Asi : integer;
  412. begin
  413.     if FBaseFormat <> Value then
  414.     begin
  415.         Asi := AsInteger;
  416.         FBaseFormat := Value;
  417.         Text := FormatText(AsI, FBaseFormat);
  418.     end;
  419. end;
  420.  
  421. function TPBBinHexEdit.FormatText(Value: Integer; NFormat: TBaseFormat): string;
  422. begin
  423.     if NFormat = Number then Result := IntToStr(Value)
  424.     else if NFormat = Binary then Result := IntToBin(Value)
  425.     else Result := '$' + IntToHex(Value, 8);
  426. end;
  427.  
  428. function TPBBinHexEdit.IntToBin(I : integer): string;
  429. var
  430.     b, t, c : integer;
  431. begin
  432.     Result := '';
  433.     if I < 0 then
  434.     begin
  435.         Result := Result + '1';
  436.         c := I + 2147483647 + 1;
  437.     end
  438.     else c := I;
  439.     t := 1073741824;
  440.     repeat
  441.         b := c - t;
  442.         if b >= 0 then
  443.         begin
  444.             Result := Result + '1';
  445.             c := b;
  446.         end
  447.         else if c <> I then Result := Result + '0';
  448.         t := trunc(t / 2);
  449.     until t = 0;
  450.     if Result = '' then Result := '0';
  451. end;
  452.  
  453. function TPBBinHexEdit.BinToInt(B : string): integer;
  454. var
  455.     b1: string;
  456.     t : comp;
  457.     a : char;
  458.     ok : boolean;
  459.     t1 : integer;
  460. begin
  461.     ok := True;
  462.     b1 := B;
  463.     Result := 0;
  464.     if b1 = '' then exit;
  465.     for t1 := 1 to length(b1) do if not (b1[t1] in ['0', '1']) then ok := False;
  466.     if ok then
  467.     begin
  468.         t := 1;
  469.         repeat
  470.             a := b1[length(b1)];
  471.             if a = '1' then Result := Result + trunc(t);
  472.             if (t = -1073741824 * 2) then exit
  473.             else if t = 1073741824 then t := -1073741824 * 2
  474.             else t := t * 2;
  475.             b1 := copy(b1, 1, length(b1) - 1);
  476.         until b1 ='';
  477.     end;
  478. end;
  479.  
  480. procedure TPBBinHexEdit.WMPaste(var Message: TMessage);
  481. var
  482.     X, P: integer;
  483.     S: String;
  484.     W: Word;
  485. begin
  486.     P := SelStart;
  487.     Text := Copy(Text, 1, SelStart)
  488.         + Copy(Text, SelStart + SelLength + 1, Length(Text) - SelStart - SelLength);
  489.     SelStart := P;
  490.     SelLength := 0;
  491.     S := Clipboard.AsText;
  492.     for X := 1 to Length(S) do
  493.     begin
  494.         W := Ord(S[X]);
  495.         Perform(WM_CHAR, W, 0);
  496.     end;
  497. end;
  498.  
  499. procedure TPBBinHexEdit.WMGetDlgCode(var Msg: TWMGetDlgCode);
  500. begin
  501.     Msg.Result := DLGC_WANTCHARS or DLGC_WANTARROWS;
  502. end;
  503.  
  504. procedure Register;
  505. begin
  506.     RegisterComponents('PB', [TPBBinHexEdit]);
  507. end;
  508.  
  509. end.
  510.  
  511.