Simulando digitação de horas no Firemonkey

Veja neste artigo como simular um componente TDateTime para o Firemonkey, já que a ferramenta atual não apresenta tal componente. O método pode sair um pouco da visão do que tratamos de simples, mas pode ser tratado como uma boa alternativa para que possamos agradar nossos usuários.

Neste artigo iremos simular um componente TDateTimePicker para o Firemonkey, já que a ferramenta atual não apresenta tal componente. O método pode sair um pouco da visão do que tratamos de simples, mas pode ser tratado como uma boa alternativa para que possamos agradar nossos usuários.

Em primeiro momento, quando me deparei com a falta do TDateTimePicker no Firemonkey logo fui correndo ver se o TEdit apresentava a propriedade de MaskEdit e novamente fiquei frustrado. Mas as decepções ainda não acabaram, pois nem a edição de máscara do field no ClientDataSet funciona no TEdit. Não querendo desistir do Firemonkey, consegui desenvolver a solução abaixo e resolvi compartilhar com os estudiosos de Firemonkey.

A solução envolve a junção de quatro componentes: TGroupBox, TEdit, TLabel e TButton. Assim, vamos então adicionar ao nosso formulário os componentes abaixo e mudar as seguintes propriedades:

TGroupBox (Qde = 1):
Name: GrpHora;
Height: 49;
Width: 129;

TEdit (Qde = 3): //adicionar dentro do GrpHora;
Name: EdtHora | EdtMinuto | EdtSegundo;
Font | Size: 11;
Height: 22;
KeyBoardType: vktNumberPad //somente números;
TextAlign: taCenter;
Width: 30;

Tlabel (Qde = 2): //adicionar dentro do GrpHora;
AutoSize: True;
Font | Size: 11;
Height: 19;
Text: “:” //não incluir as aspas;
TextAlign: taLeading;
VertTextAlign: taCenter;

TButton(Qde = 1): //adicionar dentro do GrpHora;
Font | Size: 11;
Font | Style | FsBold: True;
Height: 22;
Text: “OK”//não incluir as aspas;
TextAlign: TaCenter;
Width: 33;

Todos esses componentes deverão ser ajustados conforme configuração da figura abaixo:


Figura 1: Simulação de Componente de Hora

A máscara de Interface com o usuário está feita, agora vamos aos códigos para conexão com o banco de dados. Para não perder o foco, vou considerar um banco de dados qualquer que tendo sua conexão feita e intermediada por um componente TClientDataSet (CDSHora) possui um field (Coluna) denominado ‘HORA’. Vamos linkar um componente TDataSource a este ClientDataSet e o denominaremos de DSHORA. Todos esses componentes estarão presentes em um DataModule denominado ‘DM’.

Nas declarações públicas do formulário, vamos criar uma variável TDateTime denominada “Hora” e uma procedure de Mudança de Hora (Mudanca_de_Hora). Esta procedure tem o objetivo de atualizar a variável hora, toda vez que os valores dos Edits forem alterados.

Listagem 1: Declaração de variáveis

public { Public declarations } var Hora: TDateTime; procedure Mudanca_da_Hora;

Implementando, então, a procedure:

Listagem 2: Implementação o método Mudanca_da_Hora

procedure TFrm1.Mudanca_da_Hora; var hh, mm, ss: string; begin if EdtHora.Text = '' then begin hh := '00'; end else begin hh := EdtHora.Text; end; if EdtMinuto.Text = '' then begin mm := '00'; end else begin mm := EdtMinuto.Text; end; if EdtSegundo.Text = '' then begin ss := '00'; end else begin ss := EdtSegundo.Text; end; Hora := StrToTime(concat(hh, ':', mm, ':', ss)); end;

Para que essa mudança de hora ocorra, devemos chamar a procedure no evento OnChange dos 3 componentes TEdit (EdtHora | EdtMinuto | EdtSegundo):

Listagem 3: Evento OnChange dos edits

procedure TFrm1.EdtHoraChange(Sender: TObject); begin Mudanca_da_Hora; end; procedure TFrm1.EdtMinutoChange(Sender: TObject); begin Mudanca_da_Hora; end; procedure TFrm1.EdtSegundoChange(Sender: TObject); begin Mudanca_da_Hora; end;

Nota: Você pode, também, ao invés de implementar as 3 procedures com o mesmo código, apenas implementar a procedure no evento OnChange de EdtHora e direcionar os eventos OnChange de EdtMinuto e EdtSegundo para o evento OnChange de EdtHora. Fica a seu critério.

Para que o usuário não precise ficar apertando TAB para passar de um Edit para o outro, achei mais interessante que seja clicado “ENTER” para cumprimento de tal tarefa. Assim sendo...

No Evento OnKeyDown de EdtHora vamos colocar o seguinte procedimento:

Listagem 4: Evento OnKeyDown do EdtHora

if Key = VK_RETURN then begin EdtMinuto.SetFocus; //chamando EdtMinuto ao clicar Enter; inherited; end;

No Evento OnKeyDown de EdtMinuto vamos colocar o seguinte procedimento:

Listagem 5: Evento OnKeyDown do EdtMinuto

if Key = VK_RETURN then begin EdtSegundo.SetFocus; //chamando EdtSegundo ao clicar Enter; inherited; end;

No Evento OnKeyDown de EdtSegundo vamos colocar o seguinte procedimento:

Listagem 6: Evento OnKeyDown do EdtSegundo

if Key = VK_RETURN then begin BtnPost.SetFocus; //chamando BtnPost ao clicar Enter; inherited; end;

Agora, vamos trabalhar com o Banco de Dados sem precisar lidar com LiveBindings.

Primeiramente, vamos declarar as variáveis na sessão Public do Formulário:

Listagem 7: Declaração de variáveis para hora

Public //declaração de variáveis var Hour, Min, Sec, MSec : Word;

Após o comando insert de sua aplicação coloque o seguinte código:

Listagem 8: Definindo valor inicial para os campos

DecodeTime(Time,Hour, Min, Sec, MSec); EdtHora.Text := FormatFloat('00', Hour); EdtMinuto.Text := FormatFloat('00', Min); EdtSegundo.Text := FormatFloat('00', Sec);

E agora, insira o seguinte código após o procedimento de edição (Edit):

Listagem 9: Zerandos os valores da hora ao editar o registro

if (DM.CDSHORA.FieldByName('HORA').IsNull) then begin EdtHora.Text := '00'; EdtMinuto.Text := '00'; EdtSegundo.Text := '00'; end else begin DecodeTime(DM.CDSHORA.FieldByName('HORA_INICIAL').AsDateTime, Hour, Min, Sec, MSec); EdtHora.Text := FormatFloat('00', Hour); EdtMinuto.Text := FormatFloat('00', Min); EdtSegundo.Text := FormatFloat('00', Sec); end;

Vamos interpretar o que acabamos de fazer. Primeiro, verificamos qual o modo que vamos trabalhar. Se estiver em modo de inserção, vai aparecer como sugestão de hora para o usuário, exatamente, a hora que ele resolveu inserir o registro. Se estiver em modo de edição, o sistema verifica se existe algo gravado no campo HORA. Se sim, o sistema resgata esse registro, senão, mostra a hora ’00:00:00’.

E por último, vamos fazer a implementação do botão BTnPost que tem a função de lançar o valor da variável Hora para o Field HORA do banco de dados. No evento Onclick do Botão:

Listagem 10: Evento OnClick do botão para salvar

procedure TFrm1.BtnPostClick(Sender: TObject); begin DM.CDSCONFIG.FieldByName('HORA_INICIAL').AsDateTime := Hora; end;

Desta forma é possível utilizar uma interface que certamente irá agradar o cliente, enquanto aguardamos, é claro, que a Embarcadero desenvolva um componente TDateTime.

Espero que tenham gostado. Um abraço e até o próximo artigo.

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados