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