CASSIC
Criando um Componente Visual

  Iremos criar um componente semelhante ao TEdit, mas o nosso componente só aceitará valores numéricos. Ele também terá métodos como o Extenso que nos trará o valor digitado escrito por extenso.

  Repita todos os procedimentos do componente anterior mudando apenas as opções abaixo:

  Ancestor Component: TCustomEdit
  Class Name: TNumEdit
  Pallete Page: CursoDelphi
  Unit File Name: NumEdit.pas

  Inclua o código abaixo:

01
unit NumEdit;
02
 
03
interface
04
 
05
uses
06
   SysUtils, Classes, Controls, StdCtrls, Dialogs;
07
 
08
type
09
   TNumEdit = class(TCustomEdit)
10
   private
11
       { Private declarations }
12
       procedure cmEnter(var message: TcmEnter); message cm_Enter;
13
       procedure cmExit(var message: TcmExit); message cm_Exit;
14
       procedure FormatarValor;
15
       procedure DesformatarValor;
16
       function VrCentena(I_Valor: Integer): string;
17
       function GetExtenso: string;
18
   protected
19
       { Protected declarations }
20
       procedure KeyPress(var Key: Char); override;
21
   public
22
       { Public declarations }
23
       constructor Create(AOwner: TComponent); override;
24
   published
25
       { Published declarations }
26
       property Decimal: Integer;
27
       property Moeda: string;
28
       property Valor: Currency;
29
       property Extenso: string;
30
       property Monetario: Boolean;
31
       property OnChange;
32
       property OnClick;
33
       property OnContextPopup;
34
       property OnDblClick;
35
       property OnDragDrop;
36
       property OnDragOver;
37
       property OnEndDock;
38
       property OnEndDrag;
39
       property OnEnter;
40
       property OnExit;
41
       property OnKeyDown;
42
       property OnKeyPress;
43
       property OnKeyUp;
44
       property OnMouseDown;
45
       property OnMouseMove;
46
       property OnMouseUp;
47
       property OnStartDock;
48
       property OnStartDrag;
49
   end;
50
 
51
procedure Register;
52
 
53
Implementation
54
 
55
procedure Register;
56
begin
57
   RegisterComponents('CursoDelphi', [TNumEdit]);
58
end;
59
 
60
end.

     Nas linha 12 e 13 temos duas mensagens de componente, nestas linhas temos o cm_Enter que corresponde ao evento OnEnter do componente, enquanto que cm_Exit corresponde ao evento OnExit do mesmo.  Após este esclarecimento pressione Ctrl+Shift+C e continue entrando com o código mostrado:

001
unit NumEdit;
002
 
003
interface
004
 
005
uses
006
   SysUtils, Classes, Controls, StdCtrls, Dialogs;
007
 
008
type
009
   TNumEdit = class(TCustomEdit)
010
   private
011
       FValor: Currency;
012
       // FExtenso: string;
013
       FMoeda: string;
014
       FDecimal: Integer;
015
       FMonetario: Boolean;
016
       procedure SetDecimal(const Value: Integer);
017
       // procedure SetExtenso(const Value: string);
018
       procedure SetMoeda(const Value: string);
019
       procedure SetMonetario(const Value: Boolean);
020
       procedure SetValor(const Value: Currency);
021
       { Private declarations }
022
       procedure cmEnter(var message: TcmEnter); message cm_Enter;
023
       procedure cmExit(var message: TcmExit); message cm_Exit;
024
       procedure FormatarValor;
025
       procedure DesformatarValor;
026
       function VrCentena(I_Valor: Integer): string;
027
       function GetExtenso: string;
028
   protected
029
       { Protected declarations }
030
       procedure KeyPress(var Key: Char); override;
031
   public
032
       { Public declarations }
033
       constructor Create(AOwner: TComponent); override;
034
   published
035
       { Published declarations }
036
       property Decimal: Integer read FDecimal write SetDecimal;
037
       property Moeda: string read FMoeda write SetMoeda;
038
       property Valor: Currency read FValor write SetValor;
039
       // property Extenso: string read FExtenso write SetExtenso;
040
       property Extenso: string read GetExtenso;
041
       property Monetario: Boolean read FMonetario
042
           write SetMonetario;
043
       property OnChange;
044
       property OnClick;
045
       property OnContextPopup;
046
       property OnDblClick;
047
       property OnDragDrop;
048
       property OnDragOver;
049
       property OnEndDock;
050
       property OnEndDrag;
051
       property OnEnter;
052
       property OnExit;
053
       property OnKeyDown;
054
       property OnKeyPress;
055
       property OnKeyUp;
056
       property OnMouseDown;
057
       property OnMouseMove;
058
       property OnMouseUp;
059
       property OnStartDock;
060
       property OnStartDrag;
061
   end;
062
 
063
procedure Register;
064
 
065
implementation
066
 
067
procedure Register;
068
begin
069
    RegisterComponents('CursoDelphi', [TNumEdit]);
070
end;
071
 
072
{ TNumEdit }
073
 
074
procedure TNumEdit.cmEnter(var message: TcmEnter);
075
begin
076
   DesformatarValor;
077
   Self.SelectAll;
078
   inherited;
079
end;
080
 
081
procedure TNumEdit.cmExit(var message: TcmExit);
082
begin
083
   Self.Text := Trim( Self.Text );
084
   if ( Self.Text = '-' ) or ( Self.Text = '+' )
085
       then Self.Text := Self.Text + '0';
086
   if ( Self.Text = '' ) then Self.FValor := 0
087
   else Self.FValor := StrToFloat( Self.Text );
088
   FormatarValor;
089
   inherited;
090
end;
091
 
092
constructor TNumEdit.Create(AOwner: TComponent);
093
begin
094
   inherited;
095
   Self.FDecimal := CurrencyDecimals;
096
   Self.FMoeda := CurrencyString;
097
   Self.FValor := 0;
098
   Self.FMonetario := True;
099
   Self.Text := '0';
100
   FormatarValor;
101
end;
102
 
103
procedure TNumEdit.DesformatarValor;
104
var
105
   Formato: string;
106
begin
107
   Formato := '%.' + IntToStr(Self.FDecimal) + 'f';
108
   Self.Text := Format(Formato, [Self.FValor]);
109
end;
110
 
111
procedure TNumEdit.FormatarValor;
112
var
113
   Formato: string;
114
begin
115
   Formato := '%.' + IntToStr(Self.FDecimal) + 'n';
116
   Self.Text := Format(Formato, [Self.FValor]);
117
end;
118
 
119
function TNumEdit.GetExtenso: string;
120
var
121
   Cifra: array[1..4, 1..2] of string;
122
   S_Valor, Retorno, PosNeg: string;
123
   IValor: integer;
124
begin
125
   S_Valor := Format('%f', [Self.FValor]);
126
   if ( StrToFloat(S_Valor) < 0 ) then PosNeg := ' - Negativo'
127
   else PosNeg := '';
128
   S_Valor := StringReplace(S_Valor, '-', '', [rfReplaceAll]);
129
   Result := 'Zero';
130
   if ( StrToFloat( S_Valor ) = 0 ) then Exit;
131
   if( Length( S_Valor ) > 12 ) then
132
       begin
133
           MessageDlg('Valor máximo válido "999.999.999,99"',
134
               mtError, [mbOk], 0);
135
           Exit;
136
       end;
137
   Cifra[01,01] := ' Milhão';
138
   Cifra[01,02] := ' Milhões';
139
   Cifra[02,01] := ' Mil';
140
   Cifra[02,02] := ' Mil';
141
   Cifra[03,01] := ' Real';
142
   Cifra[03,02] := ' Reais';
143
   Cifra[04,01] := ' Centavo';
144
   Cifra[04,02] := ' Centavos';
145
   Retorno := '';
146
   S_Valor := Copy('000000000,00', 1, 12 -
147
       Length( S_Valor )) + S_Valor;
148
   if ( StrToFloat( Copy(S_Valor, 11, 2) ) > 0 ) then
149
       begin
150
           IValor := StrToInt( Copy(S_Valor, 11, 2) );
151
           Retorno := VrCentena( IValor );
152
           if ( IValor = 1 ) then Retorno := Retorno + Cifra[04,01]
153
           else Retorno := Retorno + Cifra[04,02];
154
       end;
155
   if ( StrToFloat( Copy(S_Valor, 1, 9) ) <> 0 ) then
156
       begin
157
           if ( Length( Retorno ) > 0 )
158
               then Retorno := ' e ' + Retorno;
159
           if ( FMonetario ) then
160
               begin
161
                   if ( StrToFloat( Copy(S_Valor, 1, 9) ) = 1 )
162
                       then Retorno := Cifra[03,01] + Retorno;
163
                   if ( StrToFloat( Copy(S_Valor, 1, 9) ) > 1 )
164
                       then Retorno := Cifra[03,02] + Retorno;
165
               end;
166
       end;
167
   if ( StrToFloat( Copy(S_Valor, 7, 3) ) > 0 ) then
168
       begin
169
           IValor := StrToInt( Copy(S_Valor, 7, 3) );
170
           Retorno := VrCentena( IValor ) + Retorno;
171
       end;
172
   if ( StrToFloat( Copy(S_Valor, 4, 6) ) >= 1000 ) then
173
       begin
174
           IValor := StrToInt( Copy(S_Valor, 4, 3) );
175
           if ( StrToFloat( Copy(S_Valor, 7, 3) ) > 0 )
176
               then Retorno := ' e ' + Retorno;
177
           Retorno := VrCentena( IValor ) + Cifra[02,01] + Retorno;
178
       end;
179
   if ( StrToFloat( Copy(S_Valor, 1, 9) ) >= 1000000 ) then
180
       begin
181
           IValor := StrToInt( Copy(S_Valor, 1, 3) );
182
           if ( StrToFloat( Copy(S_Valor, 4, 6) ) > 0 )
183
               then Retorno := ' e ' + Retorno;
184
           if ( IValor = 1 ) then Retorno := Cifra[01,01] + Retorno
185
           else Retorno := Cifra[01,02] + Retorno;
186
           Retorno := VrCentena( IValor ) + Retorno;
187
       end;
188
   Result := Retorno + PosNeg;
189
end;
190
 
191
procedure TNumEdit.KeyPress(var Key: Char);
192
begin
193
   inherited;
194
   if ( Key in [',','.'] ) then
195
       begin
196
           Key := DecimalSeparator;
197
           if ( Pos(DecimalSeparator, Self.Text) > 1 ) then Key := #0;
198
       end
199
   else if ( Key in [#43, #45] ) then Self.Text := ''
200
   else if not( Key in ['0'..'9', #8, #13, #43, #45] )
201
       then Key := #0;
202
end;
203
 
204
procedure TNumEdit.SetDecimal(const Value: Integer);
205
begin
206
   FDecimal := Value;
207
end;
208
 
209
{
210
procedure TNumEdit.SetExtenso(const Value: string);
211
begin
212
   FExtenso := Value;
213
end;
214
}
215
 
216
procedure TNumEdit.SetMoeda(const Value: string);
217
begin
218
   FMoeda := Value;
219
end;
220
 
221
procedure TNumEdit.SetMonetario(const Value: Boolean);
222
begin
223
   FMonetario := Value;
224
end;
225
 
226
procedure TNumEdit.SetValor(const Value: Currency);
227
begin
228
   FValor := Value;
229
end;
230
 
231
function TNumEdit.VrCentena(I_Valor: Integer): string;
232
var
233
   IValor: array[1..3] of Integer;
234
   Unidade, Dezena, DezVinte, Centena: array[1..9] of string;
235
   SValor, Retorno: string;
236
begin
237
   Result := '';
238
   if ( I_Valor = 0 ) then Exit;
239
   if ( I_Valor = 100 ) then
240
       begin
241
           Result := 'Cem';
242
           Exit;
243
       end;
244
   SValor := Copy( '000', 1, 3 - Length(
245
       IntToStr( I_Valor ) ) ) + IntToStr( I_Valor );
246
   IValor[01] := StrToInt( Copy( SValor, 1, 1 ) );
247
   IValor[02] := StrToInt( Copy( SValor, 2, 1 ) );
248
   IValor[03] := StrToInt( Copy( SValor, 3, 1 ) );
249
   Unidade[01] := 'Um';
250
   Unidade[02] := 'Dois';
251
   Unidade[03] := 'Três';
252
   Unidade[04] := 'Quatro';
253
   Unidade[05] := 'Cinco';
254
   Unidade[06] := 'Seis';
255
   Unidade[07] := 'Sete';
256
   Unidade[08] := 'Oito';
257
   Unidade[09] := 'Nove';
258
   Dezena[01] := 'Dez';
259
   Dezena[02] := 'Vinte';
260
   Dezena[03] := 'Trinta';
261
   Dezena[04] := 'Quarenta';
262
   Dezena[05] := 'Cinqüenta';
263
   Dezena[06] := 'Sessenta';
264
   Dezena[07] := 'Setenta';
265
   Dezena[08] := 'Oitenta';
266
   Dezena[09] := 'Noventa';
267
   DezVinte[01] := 'Onze';
268
   DezVinte[02] := 'Doze';
269
   DezVinte[03] := 'Treze';
270
   DezVinte[04] := 'Quatorze';
271
   DezVinte[05] := 'Quinze';
272
   DezVinte[06] := 'Dezeseis';
273
   DezVinte[07] := 'Dezesete';
274
   DezVinte[08] := 'Dezoito';
275
   DezVinte[09] := 'Dezenove';
276
   Centena[01] := 'Cento';
277
   Centena[02] := 'Duzentos';
278
   Centena[03] := 'Trezentos';
279
   Centena[04] := 'Quatrocentos';
280
   Centena[05] := 'Quinhentos';
281
   Centena[06] := 'Seiscentos';
282
   Centena[07] := 'Setecentos';
283
   Centena[08] := 'Oitocentos';
284
   Centena[09] := 'Novecentos';
285
   Retorno := '';
286
   if ( IValor[01] > 0 ) then
287
       begin
288
           Retorno := Centena[ IValor[01] ];
289
           if ( IValor[02] + IValor[03] > 0 ) then Retorno :=
290
               Retorno + ' e ';
291
       end;
292
   if ( IValor[02] = 1 ) and ( IValor[03] <> 0 )
293
       then Retorno := Retorno + DezVinte[ IValor[03] ]
294
   else
295
       begin
296
           if ( IValor[02] > 0 ) then
297
               begin
298
                   Retorno := Retorno + Dezena[ IValor[02] ];
299
                   if( IValor[03] > 0 ) then Retorno := Retorno + ' e ';
300
               end;
301
           if ( IValor[03] > 0 ) then Retorno :=
302
               Retorno + Unidade[ IValor[03] ];
303
       end;
304
   Result := Retorno;
305
end;
306
 
307
end.

     Entre com um arquivo DCR e um bitmap para o novo componente (Figura 1). Depois acrescente este componente ao nosso pacote dê um Build. Não é preciso chamar o Install do pacote uma vez que o mesmo já está instalado.


Figura 1 – Imagem do componente TNumEdit