Classes em Delphi

Delphi

12/05/2010

Bom dia! Estou aprendendo um pouco de OO com delphi e criei uma classe simples para validar os campos de um form. Como não conheço muito de OO gostaria de saber se estou no caminho certo e se tem alguma coisa que eu esqueci ou que possa ser melhorada. Segue abaixo a classe e sua utilização:
unit uValidar;

interface

uses
Windows, SysUtils, Forms, Classes, Controls;

type
  TValidar = class
private
  FGravar: Boolean;
  function getGravar:Boolean;
public
  function Data(Data: String; ShowMsg: Boolean; Menssagem: String; Componente: TObject = nil): Boolean;
  function CampoObrigatorio(Campo: String; ShowMsg: Boolean; Menssagem: String; Componente: TObject = nil): Boolean;
  property Gravar: Boolean read getGravar;
  constructor Create;
  end;

implementation

{ TValidar }

// *****************************************************************************
// Função para validaçáo de campo obrigatório
// *****************************************************************************
function TValidar.CampoObrigatorio(Campo: String; ShowMsg: Boolean;
  Menssagem: String; Componente: TObject): Boolean;
begin
  if  Campo = '' then
    begin
    FGravar:= false;
    Result := false;
    if (Componente is TWinControl) then
      TWinControl(Componente).SetFocus;
    if ShowMsg then
      Application.MessageBox(Pchar(Menssagem), 'Atenção',MB_ICONINFORMATION + MB_OK);
    end
  else
    Result:=True;
end;

// *****************************************************************************
// Constructor para inicialização da variável FGravar
// *****************************************************************************
constructor TValidar.Create;
begin
FGravar := True;
end;

// *****************************************************************************
// Função para validaçáo de datas
// *****************************************************************************
function TValidar.Data(Data: String; ShowMsg: Boolean; Menssagem: String; Componente: TObject = nil): Boolean;
var
Aux:  TDateTime;
begin
  if (TryStrToDate(Data,Aux))then
    begin
    Result := True
    end
  else
      begin
      Result := False;
      FGravar := False;
      if (Componente is TWinControl) then
        TWinControl(Componente).SetFocus;
      if ShowMsg = True then
        Application.MessageBox(Pchar(Menssagem), 'Atenção',MB_ICONINFORMATION + MB_OK);
      end;
end;

// *****************************************************************************
// Função para ler a variável FGravar
// *****************************************************************************
function TValidar.getGravar: Boolean;
begin
  Result := FGravar;
end;

end.

 
------------------------------------------------------------------------------------------------------------------------------

Abaixo a utilização:
procedure TForm1.Button1Click(Sender: TObject);
var
  Validar : TValidar;
begin
Validar := TValidar.Create();
Validar.Data(Edit1.Text,true,'Data Inválida',Form1.Edit1);
if Validar.Gravar then
  ShowMessage('Gravar')
else
  ShowMessage('Não Gravar');
FreeAndNil(Validar);
end;


Desde já, muito Obrigado!
Walter Desidera

Walter Desidera

Curtidas 0

Melhor post

Raimundo Melo

Raimundo Melo

12/05/2010

Olá, boa tarde, fico feliz em saber que tem alguém realmente querendo aprender....
Eu fiz algumas melhorias que podem ser válidas, vc disse que ainda está começando...darei algumas dicas de melhorias..
Por exemplo....Eu percebi q essa classe TValidar, poder ter métodos estáticos...ou seja...vc não precisa instanciar a classe para ter acesso aos métodos....

Eu fiz algumas melhorias....

A classe ficaria assim...

Type  TValidar = classpublic  Class function Data(Data: String; ShowMsg: Boolean;
 Menssagem: String; 
 Componente: TObject = nil): Boolean;//Método estático.  
 
 Class function CampoObrigatorio(Campo: String; ShowMsg: Boolean; Menssagem: String;
  Componente: TObject = nil): Boolean;//Método estático.  
  constructor Create;
 end;


a implementação da classe ficaria assim..

{ TValidar }
// *****************************************************************************// Função para validaçáo de campo obrigatório// *****************************************************************************

Class function TValidar.CampoObrigatorio(Campo: String; ShowMsg: Boolean;  Menssagem: String; Componente: TObject): Boolean;
    begin  
        if  Campo = '' then    
            begin    
                Result := false;
                if (Componente is TWinControl) then
                  TWinControl(Componente).SetFocus;
                if ShowMsg then
                  Application.MessageBox(Pchar(Menssagem), 'Atenção',MB_ICONINFORMATION + MB_OK);
                end
              else
                Result:=True;
            end;

// *****************************************************************************// Constructor para inicialização da variável FGravar// *****************************************************************************

constructor TValidar.Create;
begin
   Inherited Create(); //Chama o método Create da super Classe, no caso, TObject.//FGravar := True;
end;

// *****************************************************************************// Função para validaçáo de datas// *****************************************************************************
Class function TValidar.Data(Data: String; ShowMsg: Boolean; Menssagem: String; Componente: TObject = nil): Boolean;
varAux:  TDateTime;
begin
  if (TryStrToDate(Data,Aux))then
    begin
        Result := True
    end
  else
    begin
      Result := False;
      if (Componente is TWinControl) then
        TWinControl(Componente).SetFocus;
      if ShowMsg = True then
        Application.MessageBox(Pchar(Menssagem), 'Atenção',MB_ICONINFORMATION + MB_OK);
      end;
end;


E um exemplo de uso...seria assim..

procedure TForm1.Button1Click(Sender: TObject);
begin
    if TValidar.Data(Edit1.Text,true,'Data Inválida',Form1.Edit1) then //Como disse, não precisa instanciar a classe, basta chamar o NomeDaClasse.NomeMétodo.  
        ShowMessage('Gravar')
    else  
        ShowMessage('Não Gravar');
    end;
end.


Mts vezes usar métodos estáticos tbm resolvem nossos problemas....
Espero ter ajudado....flw
GOSTEI 2

Mais Respostas

Marco Salles

Marco Salles

12/05/2010

Olhe Rick , acho que dá para melhorar bem sua classe
 
são vários pontos que apesar da simplicidade da classe pode ser atacado para futuras referencias
 
por exemplo
 
vc passa um Componente  , para que ele receba o foco

function TValidar.CampoObrigatorio(Campo: String; ShowMsg: Boolean;
  Menssagem: String; Componente: TObject): Boolean;

e na implementação do método vc usa o operador Is e seguidamente vc usa o Operador as
 
A pergunta que lhe faço é ... Pq ao inves de usar o Componente: TObject pq não vc define
Componente: TWincontrol . Assim vc não precisa fazer esta conversão
 
 
Uma outra duvida que eu tenho é vc definir uma propriedade cujo controle depende de outros métodos
Por exemplo , algumem que utiliza a sua classe executar

procedure TForm1.Button1Click(Sender: TObject);
var
validar:TValidar;
begin
validar:=TValidar.Create;
try
  if validar.Gravar then
    Showmessage('Grava ou Não ???')
  else
    Showmessage('Pq não Grava');
finally
  validar.Free;
end;
end;

 
meio sem sentido isto, mas é o que vc fez...
GOSTEI 1
Walter Desidera

Walter Desidera

12/05/2010

Bom dia! Muito obrigado pessoal por disponibilizarem um
pouco do seu tempo para me ajudar... Ainda estou começando... Bem vocês me
deram boas idéias para melhorar a minha classe... Mais a idéia que eu tinha
para esta classe é um pouco diferente da de vocês...

Bem seria assim:

Uma classe que fornece métodos para validação em uma tela de cadastro por
exemplo:

Crio uma instancia e chamo um método qualquer dela, por exemplo:

Validar.Data(Edit1.Text,true,'Data Inválida',Form1.Edit1);


Esta função devolve um booleano para uma propriedade Gravar, em seguida no
final do código eu apenas testo se essa variável continua True e só assim
efetuo as alterações no banco. Sendo que a property Gravar é Read Only, só os
métodos internos da classe podem alterar e usar este valor...

Programei desta forma porque não queria ficar fazendo if's na implementação dos
métodos; ficando desta forma:

procedure TForm1.Button1Click(Sender: TObject);

var
Validar : TValidar;

begin

Validar := TValidar.Create();


Com métodos estáticos eu tenho que testar com if's se deu certo ou não, com a
property eu  não preciso porque ela q verifica se eu posso ou não gravar
as alterações, já que esse valor é retornado a ela quando a função é chamada.
Desse modo posso validar vários campos de uma vez...

Validar.Data(Edit1.Text,true,'Data de Nascimento Inválida',Form1.Edit1); </span>

Validar.Data(Edit2.Text,true,'Data de Cadastro Inválida',Form1.Edit2);

Validar.Data(Edit3.Text,true,'Data LALALA Inválida',Form1.Edit3);

Validar.Data(Edit4.Text,true,'Data BLABLABLA Inválida',Form1.Edit4);

Validar.Data(Edit5.Text,true,'Data TATATA Inválida',Form1.Edit5);</span>

if Validar.Gravar then

    ShowMessage('Gravar') 

Aqui usei um exemplo de um método simples, não vou chamar nenhuma menssagem aqui,
seria por exemplo um inherited de uma operação de post, caso a
property gravar ainda fosse verdadeira...

FreeAndNil(Validar);

end; 


Marco você está certo, usar TObject foi um erro, na verdade eu realmente devo
usar TWinControl direto no lugar...

Mais um erro que eu cometi... não crie uma função para abortar caso a property
Gravar seja False, em cada método deveria ter colocado o seguinte código no
inicio:

if Gravar = False then

exit

else

//Código a Validar


Assim se uma validação desse errado eu já nem verificaria os outros campos,
evitando várias mensagens uma atrás da outra...

Bem a principio eu realmente queria simplificar ao máximo o uso da classe, por
isso a property gravar também é opcional, é só é usada quando valido vários
campo de uma só vez.. O componente passado como parâmetro também, porque eu
posso validar um valor do banco ou variável que não esteja associada a um
componente...

Bom pessoal, muito obrigado pela ajuda, gostaria de saber se esta minha idéia foi
mal formulada, mais como eu disse anteriormente estou aprendendo... Qualquer
ajuda é muito bem vinda ;)
GOSTEI 0
Marco Salles

Marco Salles

12/05/2010

 
Vamos concatenas as Idéas..
 
Entendi sua intenção..

Esta função devolve um booleano para uma propriedade Gravar, em seguida no final do código eu apenas testo se essa variável continua True e só assim efetuo as alterações no banco. Sendo que a property Gravar é Read Only, só os métodos internos da classe podem alterar e usar este valor...
 
 
Mas é muito estranho esta property estar aclopada a outros métodos , além do mais seu raciocineo esta
Errado  .. Tente acompanhar
 

Com métodos estáticos eu tenho que testar com if's se deu certo ou não, com a property eu  não preciso porque ela q verifica se eu posso ou não gravar as alterações, já que esse valor é retornado a ela quando a função é chamada. Desse modo posso validar vários campos de uma vez...

Validar.Data(Edit1.Text,true,'Data de Nascimento Inválida',Form1.Edit1); //1
Validar.Data(Edit2.Text,true,'Data de Cadastro Inválida',Form1.Edit2); //2
Validar.Data(Edit3.Text,true,'Data LALALA Inválida',Form1.Edit3); //3
Validar.Data(Edit4.Text,true,'Data BLABLABLA Inválida',Form1.Edit4); //4
Validar.Data(Edit5.Text,true,'Data TATATA Inválida',Form1.Edit5); //45
if Validar.Gravar then
    ShowMessage('Gravar') 


 
Suponha que os passos //1 , //2 , //3 , //4 sejam todos Falsos.. Porém o passo //5 Esta tudo Certo
 
O que que vai acontecer ??? a Propery vai ser True e Vc estar Gravando ... Entende Isto ???
 
Mesmo  que vc Utilize Exit , vc não impede o Compilador de executar as Instruçoes Seguintes
 
E  qual a saida ????
 
Bem , eu sugiro uma mais orientada a objetos  do que este aclopamanento que vc esta fazendo
 
A Idéia e que ao inves de function estes métodos sejam Procedures e que ao Inves de Retornar
Um boolean , devolvam uma Exceção Não Tratada .. Vc mesmo na sua classe Pode definir uma Exceção
Especifica.. < Ai é uma outra dica Boa e fica o codigobem mais legivel
 
Ai Vc Varia
 
try
Validar.Data(Edit1.Text,true,'Data de Nascimento Inválida',Form1.Edit1);  //1
Validar.Data(Edit2.Text,true,'Data de Cadastro Inválida',Form1.Edit2); //2
Validar.Data(Edit3.Text,true,'Data LALALA Inválida',Form1.Edit3); //3
Validar.Data(Edit4.Text,true,'Data BLABLABLA Inválida',Form1.Edit4); //4
Validar.Data(Edit5.Text,true,'Data TATATA Inválida',Form1.Edit5); //45

ShowMessage('Gravar') 
except
On e:SUAEXCECAO do
begin
ShowMessage('Não foi possivel Gravar') 
end;


No fim , gosto muito do método de classes aonde não precisa instanciar a classe , conforme ja foi comentado antes
GOSTEI 0
Walter Desidera

Walter Desidera

12/05/2010

Marco você está certo novamente, não tinha pensado nisso =/

Neste caso minhas funções não retornam uma Boolean e sim
Procedures com uma Exception (vou pesquisar como fazer isso para tentar fazer
um teste aqui...que eu me lembre era algo como "Raise")

Em suma eu estaria levantando uma Exception caso uma das validações não fosse verdadeira,
caso ela fosse gerada anularia as verificações seguintes definidas dentro do
bloco try...except.

Como as mensagens de erro são tratadas por procedimentos, eu
posso simplesmente não fazer nada quando a exception for levantada, usando ela
apenas para abortar a execução do bloco try...except. Quando ocorresse
qualquer erro na validação, ele nunca chegaria ao método de gravação dos dados,
correto?

EDITADO:

Dei uma olhada e vi que poderia usar uma exception silenciosa sem o Dialog do tipo EAbort:

raise EAbort.Create('Data Inválida');


Assim ainda posso usar um MessageBox normalmente que eu usava para mostrar um erro customizado ao usuário...vou  fazer mais alguns testes aqui...
GOSTEI 0
Marco Salles

Marco Salles

12/05/2010

Simplesmente o Abort seria suficiente   Vc so testaria se a exceção levantada fosse do tipo Abort ( Exceção silenciosa)   Ate um Try except   on e:excpetion do // Exceção Mais Geral //   funcionaria , ja que o Abort tb sera capturado pela classe excpetion   Porém qnd sugeri vc criar ou definir uma exceção especifica para sua classe , fica no meu modo de ver mais Orientado a Objeto   Tb não esqueça de pesquisar sobre métodos de class , que acho que se enciaxa muito bem neste proposito   Uma outra dica que lhe dou é sobre um braço da POO ... Que diz o seguinte   Toda classe tem uma unica razão de Existir ..ou a lei da Resposanbilidade Unica Em outras palavras , toda classe deve ter apenas uma única razão para sofre alterações   Não se deve atribuir funçoes para uma classe alem daquela que ela foi projetada . Se  uma classe responsavel por fazer conexão com o banco ela não deve por exemplo executar Sql   entende isto ???    
GOSTEI 0
Walter Desidera

Walter Desidera

12/05/2010

Entendi, seria uma exception customizada própria da classe... vou ter que dar uma olhada nisso...
Então sobre a responsabilidade única da classe, seria para simplificar o código e eliminar as dependências e acoplamentos de várias funcionalidades para uma mesma classe. Cada classe desempenha um único papel...

Mais uma coisa que estive pensando... Quando defino uma class function ou class procedure eu automaticamente reservei memória as qualquer variáveis que eu venha a usar dentro de minhas funções implementadas na classe, ou seja, automaticamente estou usando memória mesmo que eu não chame nenhuma função da classe...

Seria como uma variável global no Form principal, sempre alocada para uso mesmo que eu não esteja usando...
Se a classe não for estática, essa memória não é reservada, pois seus métodos não estão disponíveis diretamente, a memória só irá ser alocada caso eu crie um objeto desta classe...

Estou certo???
GOSTEI 0
Marco Salles

Marco Salles

12/05/2010


Entendi, seria uma exception customizada própria da classe... vou ter que dar uma olhada nisso...

 
Isto mesmo
 

Então sobre a responsabilidade única da classe, seria para simplificar o código....
 
 
Cada classe desempenha um único papel...
Isto é um conceito de POO ... Se vc sabe para que serve os bolinhos da classe e se esses bolinhos
estão saindo quimados , então vc modifica , altera , enfim da manuntenção em um lugar especidico
no programa .. E por ai vai todo o conceito de reusabilidade , manuntenção etc e coisa e tal
 

Mais uma coisa que estive pensando... Quando defino uma class function ou class procedure eu automaticamente reservei memória as qualquer variáveis que eu venha a usar dentro de minhas funções implementadas na classe, ou seja, automaticamente estou usando memória mesmo que eu não chame nenhuma função da classe...

 
Bem , não tenho conhecimento para dizer que sim nen dizer que não . As biografias que ja li a respeito de
métodos de classe não levantaram nenhuma informação de como é feito este gerenciamento de
memoria no Delphi . O que ela dizem sçao em suma que um método de classe não é especico a nenhum Objeto
da Classe e sim a propria classe ( em outras palavras são metodos Aplicados a classe e não ao Objetos da classe)
 
Mas não confunda com metodos Estáticos que não tem nada a ver .. Inclusive Metodos de Classe podem Sofrer
Polimorfismo. Apesar de meio abstrato o exemplo abaixo , ele demostar Isto
 

type
  TClasseBase = class
    class procedure Mensagem(); virtual;
  end;
  TClassFilha = class(TClasseBase)
    class procedure Mensagem(); Override;
  end;
class procedure TClasseBase.Mensagem;
begin
showmessage('Classe Base');
end;
{ TClassFilha }
class procedure TClassFilha.Mensagem;
begin
  //inherited;
   Showmessage('Classe Filha')
end;
procedure TForm1.Button1Click(Sender: TObject);
var
obj:TClasseBase;
begin
obj:=TClassFilha.Create;  //POLIMORFISMO
try
 obj.Mensagem;
finally
  obj.Free;
end;
end;

 Seria ate interresante , definir dois programas com uma certa quantidade de métodos. Um Do modo Tradicional
e outro usando o Metodo de classe , de modo que todos esses metodos em ambos os casos fossem compilados
isto é , lolinhas azuis , ou seja em algum lugar do programa referencia-sse esses métodos. Gera-sse esses dois
executaveis e verificasse o Tamanho do mesmo ... Nunca fiz isto... 
GOSTEI 0
Walter Desidera

Walter Desidera

12/05/2010

Entendi, eu estava confundindo
o tipo dos métodos, acreditava que class methods, por exemplo, não usavam
override...

Sobre a exception eu, andei dando uma pesquisada eu eu teria que criar uma nova
classe descendente da classe Exception (<a href="http://cc.embarcadero.com/item/17819" target="_blank" title="EDN">http://cc.embarcadero.com/item/17819</a>),
para poder ter total liberdade para implementar as menssagens que gostaria que
fossem apresentada, ou seja minha classe TValidar só validariao campo,
TMinhaException faria a parte de tratar a exception.

Tambem achei um jeito de minha idéia anterior funcionar corretamente:

Como minha property FGravar era responssável por verificar se tudo tinha
ocorrido corretamente e então gravaria as informações ficando assim

Validar.Data(Edit1.Text,true,'Data de Nascimento Inválida',Form1.Edit1); //False

Validar.Data(Edit2.Text,true,'Data de Cadastro Inválida',Form1.Edit2); //False

Validar.Data(Edit3.Text,true,'Data LALALA Inválida',Form1.Edit3); //False

Validar.Data(Edit4.Text,true,'Data BLABLABLA Inválida',Form1.Edit4); //False

Validar.Data(Edit5.Text,true,'Data TATATA Inválida',Form1.Edit5); //True


Não tinha preparado mais já havia solucionado o problema que você tinha me informado
adicionando o Exit sim, pois:

Caso uma função retorne false para FGravar, as outras funções não vão
ser nem testadas, não tem como porque quando uma está errada a condição

Supomos:

Validar.Data(Edit1.Text,true,'Data de Nascimento Inválida',Form1.Edit1); //False


Retorna Fgravar como False...

No próximo método...

Validar.Data(Edit2.Text,true,'Data de Cadastro Inválida',Form1.Edit2);//True



Não importa se a validação vai dar true ou false, FGravar esta como False, uma
vez False ela não pode se True novamente, só quando uma nova instancia desta
classe for criada, pois a primeira coisa em cada método é verificar se FGravar
está em True para que ele possa validar o próximo campo...

Gravar = False then // Condição falsa, não verifica mais nenhum método a seguir destrói o objeto

exit 

else

//Código a Validar


A idéia de uma exception customizada ficaria mais orientada a objeto, mais a
implementação seria mais complexa e um pouco estranha, vamos ver assim:

try

Validar.Data(Edit1.Text,true,'Data de Nascimento Inválida',Form1.Edit1);  //1

Validar.Data(Edit2.Text,true,'Data de Cadastro Inválida',Form1.Edit2); //2

ShowMessage('Gravar') 

except

On e:SUAEXCECAO do

begin

ShowMessage('Não foi possível Gravar') 

end;


Ou:

try

Validar.Data(Edit1.Text,true,'Data de Nascimento Inválida',Form1.Edit1);


Levanta minmha exception e mostra o que aconteceu e vai direto para o bloco except do try... Mostra a mensagem ("data Inválida"), focus no objeto...

Validar.Data(Edit2.Text,true,'Data de Cadastro Inválida',Form1.Edit2);//2

ShowMessage('Gravar') 

except

On e:SUAEXCECAO do


Quando eu entrasse no bloco except do try, aqui não faria simplesmente nada, já
que quando a exception foi levantada ela já tratou o erro, achei que ficou mais
estranho assim...

O Try e uma exception customizada eliminam minha property FGravar, mais ele faz
o mesmo trabalho, ocorreu uma exception, a exception impede a continuidade da
validação e processo de gravação é abortado...

(Não tem nada a ver com o que eu estou fazendo aqui mais achei muito interessante http://www.delphi3000.com/articles/article_3308.asp)
GOSTEI 0
Marco Salles

Marco Salles

12/05/2010


Sobre a exception eu, andei dando uma pesquisada eu eu teria que criar uma nova classe descendente da classe Exception (http://cc.embarcadero.com/item/17819), para poder ter total liberdade para implementar as menssagens que gostaria que fossem apresentada, ou seja minha classe TValidar só validariao campo, TMinhaException faria a parte de tratar a exception.

 
Acho que esta complicando
 
Antes de proseguir com o exit e com seu raciocineo
 
teste este exemplo
 
Defina na sua Classe

type
  TMinhaExcecao = class(Exception);
 
 
Na sua Classe qnd for conveniente , naqueles lugares aonde vc usa a Booleana para dizer que não Pode gravar
Vc Faz

 raise TMinhaExcecao.Create('MinhaExcecao');
 
 
Com isto esta exceção é levantada e capturada no Bloco Try except do Codigo Principal 
 
procedure TForm1.Button1Click(Sender: TObject);
begin
try
  raise TMinhaExcecao.Create('MinhaExcecao');
except
 on e:TMinhaExcecao do
  Showmessage(e.Message);
 on e:exception do
   Showmessage('Esta excecao não fio criada') //portanto não sera exceutada
end;
end;
GOSTEI 0
Walter Desidera

Walter Desidera

12/05/2010

Não entendi muito
bem a sua idéia, vejamos:

//Defini uma nova exception

type

  TMinhaExcecao = class(Exception);</span><span style="font-size: 10pt;">

class procedure TValidar.CampoObrigatorio(Campo: String; ShowMsg: Boolean;

  Menssagem: String; Componente: TWinControl);

begin

  if  Campo = '' then

    begin

    //FGravar:= false;

    Componente.SetFocus;

    if ShowMsg then

      Application.MessageBox(Pchar(Menssagem), 'Atenção',MB_ICONINFORMATION + MB_OK);

    raise TMinhaExcecao.Create('Campo Obrigatório!'); 
<== Adicionei a exception criada aqui 

end;

end;


Num Botão qualquer:

try

TValidar.CampoObrigatorio(Edit1.Text,True,'Campo Vazio!',Form1.Edit1);

//Aqui a exception foi levantada

except

 on e:TMinhaExcecao do  //Caindo nesse bloco

  Showmessage(e.Message); //Mostrou a mensagem Campo Obrigatório!

 on e:exception do

   Showmessage('Esta exceção não foi criada') //portanto não sera executada

end;


Isso funciona, mesmo que eu chame a exception depois de dar focus e mostrar a minha
menssagem ainda recebo uma menssagem do raise da exception, ou seja duas
menssagens...

Ainda que eu usasse o Abort para ter apenas a minha mensagem , o bloco
try...except é meio estranho, pois quando acontecer uma exceção eu não quero
que ele faça nada...um raise aconteceu ele captura e cai no except

dai no except não faço nada, pq já foi tratado anteriormente no meu método...

Se eu deixa-se apenas com a exception daria certo, mais eliminaria meu
MessageBox...
GOSTEI 0
Marco Salles

Marco Salles

12/05/2010

Não entendi muito bem a sua idéia, vejamos:
  entendeu sim,, fez direitinho  
Isso funciona, mesmo que eu chame a exception depois de dar focus e mostrar a minha menssagem ainda recebo uma menssagem do raise da exception, ou seja duas menssagens
  é so não fazer o Showmessage(e.message)
Try
TValidar(); // e coisa e tal -->> se levantar uma exceção ela sera capturada pelo try except

TValidar(); // e coisa e tal

TValidar(); // e coisa e tal

TValidar(); // e coisa e tal
Showmessage('Gravado')
except 
//Não coloque nada Aqui.. A exceção cai neste bloco que não faz nada...
end;
 
GOSTEI 0
Walter Desidera

Walter Desidera

12/05/2010

Funcionou perfeitamente kra... Entendi a sua idéia, muito simples e prático =D

Testei desta forma também:

class function TValidar.Data(Data: String; ShowMsg: Boolean; Menssagem: String; Componente: TWinControl = nil): Boolean;
var Aux:  TDateTime;
begin
  if (TryStrToDate(Data,Aux))then
    begin
    Result := True
    end
  else
      begin
      Result := False;
      if Componente <> nil then
        Componente.SetFocus;
      if ShowMsg = True then
        Application.MessageBox(Pchar(Menssagem), 'Atenção',MB_ICONINFORMATION + MB_OK);
     Abort;  <=== Ele cancela o processamento dos outros campos também, então não uso o Try...Except
      end;
end;

Validar.Data(Edit1.Text,true,'Data Inválida',Form1.Edit1); Aborta e não continua para o próximo
Validar.Data(Edit2.Text,true,'Data Inválida',Form1.Edit2);


Se deu erro nem valida os outros, e também não recebo um erro do compilador por ter usado um raise... Agora sobre a segurança dessa implementação... Achei uma ótima idéia do try...except é um método mais seguro, um erro ocorre na validação e o processo é abortado imediatamente...

Já  a procedure abort tem um código ASM...

procedure Abort;
function ReturnAddr: Pointer;
  asm
      MOV     EAX,[EBP + 4]
    end;
  begin
    raise EAbort.CreateRes(@SOperationAborted) at ReturnAddr;
  end;

Mais isso é para quando eu tiver mais tempo livre pra entender rsrsrsrs
GOSTEI 0
POSTAR