quarta-feira, 14 de novembro de 2012

Delphi - Pegar o diretório padrão do "Arquivos de Programas"


uses registry;

procedure TForm1.Button1Click(Sender: TObject);
var Reg : TRegistry;
begin
 Reg := TRegistry.Create;
 Reg.RootKey := HKEY_LOCAL_MACHINE;
 Reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion', False);
 ShowMessage(Reg.ReadString('ProgramFilesDir'));
 Reg.CloseKey;
 Reg.Free;
end;

C# - Criando um Componente TextBox personalizado



Muitas vezes necessitamos utilizar um componente diferente ou com alguma funcionalidade a mais em nossas aplicações, na maioria dos casos devemos realizar esta tarefa herdando de um componente principal ou até mesmo o criando do zero, escrevendo-o diretamente da classe “Object”. Podemos manipular suas propriedades e métodos até chegar ao resultado que desejamos. Na linguagem C# isto se torna uma tarefa fácil e prática, sendo que neste artigo vou criar um “TextBox” personalizado contendo validações de CPF, CNPJ e PIS usando o método “OnValidating()”. Reescreverei métodos e propriedades como: “OnLostFocus()”, “OnGotFocus()” e ”ForeColor” para dar uma impressão um pouco mais interessante ao usuário. Será necessário também criar uma classe “Tipo” para trabalharmos com o Tipo de validação necessária. Para esta tarefa achei mais prático utilizar um “combobox” acoplado nas suas propriedades.

Criando o Componente

Inicie o Microsoft Visual Studio e crie um novo projeto como “Class Libary”. (Não se preocupe que disponibilizarei todo o código fonte)
Clique com o botão direito sobre a solução e escolha “Add/New Item...”. Criaremos uma classe do início. Ver Figura 01.


Figura 01: Criar uma classe para o TextBox.

Vou abordar assuntos já mencionados em assuntos anteriores, primeiramente importe algumas bibliotecas úteis ao longo do desenvolvimento.

using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;

System.Windows.Forms: Assembly que contém a classe TextBox.
System.Drawing: Assembly responsável pela troca de cores dos componentes.
System.ComponentModel: Classes responsáveis pela manipulação e conversão de dados dos componentes.
O primeiro passo ao criar uma classe é definir o atributo como “Public”, para podermos visualizá-la em qualquer parte do projeto e logo em seguida usar o recurso de herança para a classe “TextBox”. Defina também o “Constructor” e “Destructor” do componente. Especificamente neste artigo não precisei utilizá-los, mas recomendo sempre a criação do mesmo.

//Herança de Classes
public class TextBoxTheClub: TextBox
{
    //Definindo o Contructor
    public TextBoxTheClub()
    {

    }

    //Definindo o Destructor
    ~TextBoxTheClub()
    {

    }

Vou reescrever os métodos “OnLostFocus()”, “OnGotFocus()” e a propriedade “ForeColor” sendo respectivamente responsáveis por perder o foco, receber o foco e mudar cor da fonte, que neste caso defini como “DarkBlue”.

//Sobrescrever a propriedade cor da Fonte
public override Color ForeColor
{
     get
     {
         return Color.DarkBlue;
     }
     set
     {
         base.ForeColor = value;
     }
}

//Sobrescrever o evento ao receber o foco
protected override void OnGotFocus(EventArgs e)
{
     base.OnGotFocus(e);
     this.BackColor = System.Drawing.Color.LightYellow;
}

//Sobrescrever o evento ao perder o foco
protected override void OnLostFocus(EventArgs e)
{
     base.OnLostFocus(e);
     this.BackColor = Color.White;
}

public class Tipo : StringConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
     {
            return true;
     }
          
public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
       {
return new StandardValuesCollection(new string[] { "CPF", "CNPJ", "PIS" });
       }
}

Foi necessário criar uma pequena classe denominada Tipo, herdando da “StringConverter”. Usaremos o “Override” do método “GetStandardValuesSupported” responsável por indicar se o conversor oferece ou não suporte a um conjunto de valores, retornando um booleano e o método “GetStandardvalues()“ que possibilita a manipulação de uma coleção de dados, que no caso específico identificamos como: CPF, CNPJ e PIS.

[TypeConverter(typeof(Tipo)), Category("validação")]

public string TipoValidacao
{
      get;
      set;
             
Para identificarmos o tipo de validação foi necessário criar uma propriedade “TipoValidacao” usando os operadores “Get” e “Set”, pois através deles que podemos recuperar e atribuir os valores descritos acima. Graças a esta propriedade que conseguimos manipular as configurações propostas pelo desenvolvedor.
 
protected override void OnValidating(System.ComponentModel.CancelEventArgs e)
{
     base.OnValidating(e);

     if (this.Text.Length > 0)
     {
           if (TipoValidacao == "CPF")
           {
                  if (ValidarCpf(this.Text) == true)
                  {
                        MessageBox.Show("CPF Válido!!");
                  }
                  else
                  {
                        MessageBox.Show("CPF Inválido!!");
                        this.Focus();
                  }
           }
           else if (TipoValidacao == "CNPJ")
           {
                 if (ValidarCnpj(this.Text) == true)
                 {
                       MessageBox.Show("CNPJ Válido!!");
                 }
                 else
                 {
                       MessageBox.Show("CNPJ Inválido!!");
                       this.Focus();
                 }
           }
           else if (TipoValidacao == "PIS")
           {
                if (ValidarPis(this.Text) == true)
                {
                      MessageBox.Show("PIS Válido!!");
                }
                else
                {
                      MessageBox.Show("PIS Inválido!!");
                      this.Focus();
                }
           }
     }
}

O evento “Onvalidating()” é executado no momento que saímos do Textbox, ou seja, o validamos. Este evento será responsável por chamar as funções de validações de CPF, CNPJ e PIS. No primeiro momento verificamos se o campo está preenchido com a propriedade “length” e logo em seguida usamos a propriedade pública “TipoValidacao” identificando o que o desenvolvedor deseja validar. Por final chamamos a função desejada. Não entrarei em detalhes como foram montadas as funções pelo fato deste artigo abordar a criação de componentes. Segue em seguida as funções “ValidarCpf()”, “ValidarCnpj()” e “ValidarPis()”.

public static bool ValidarCnpj(string cnpj)
{
    int[] multiplicador1 = new int[12] { 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 };
    int[] multiplicador2 = new int[13] { 6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 };
    int soma;
    int resto;
    string digito;
    string tempCnpj;
    cnpj = cnpj.Trim();
    cnpj = cnpj.Replace(".", "").Replace("-", "").Replace("/", "");
       if (cnpj.Length != 14)
             return false;
    tempCnpj = cnpj.Substring(0, 12);
       soma = 0;
    for (int i = 0; i < 12; i++)
        soma += int.Parse(tempCnpj[i].ToString()) * multiplicador1[i];
    resto = (soma % 11);
    if (resto < 2)
        resto = 0;
    else
        resto = 11 - resto;
    digito = resto.ToString();
    tempCnpj = tempCnpj + digito;
    soma = 0;
    for (int i = 0; i < 13; i++)
        soma += int.Parse(tempCnpj[i].ToString()) * multiplicador2[i];
    resto = (soma % 11);
    if (resto < 2)
        resto = 0;
    else
        resto = 11 - resto;
    digito = digito + resto.ToString();
    return cnpj.EndsWith(digito);
}

public static bool ValidarCpf(string cpf)
{
    int[] multiplicador1 = new int[9] { 10, 9, 8, 7, 6, 5, 4, 3, 2 };
    int[] multiplicador2 = new int[10] { 11, 10, 9, 8, 7, 6, 5, 4, 3, 2 };
    string tempCpf;
    string digito;
    int soma;
    int resto;
    cpf = cpf.Trim();
    cpf = cpf.Replace(".", "").Replace("-", "");
    if (cpf.Length != 11)
         return false;
    tempCpf = cpf.Substring(0, 9);
    soma = 0;

    for (int i = 0; i < 9; i++)
        soma += int.Parse(tempCpf[i].ToString()) * multiplicador1[i];
    resto = soma % 11;
    if (resto < 2)
        resto = 0;
    else
        resto = 11 - resto;
    digito = resto.ToString();
    tempCpf = tempCpf + digito;
    soma = 0;
    for (int i = 0; i < 10; i++)
        soma += int.Parse(tempCpf[i].ToString()) * multiplicador2[i];
    resto = soma % 11;
    if (resto < 2)
        resto = 0;
    else
        resto = 11 - resto;
    digito = digito + resto.ToString();
    return cpf.EndsWith(digito);
}

public static bool ValidarPis(string pis)
{
    int[] multiplicador = new int[10] { 3, 2, 9, 8, 7, 6, 5, 4, 3, 2 };
    int soma;
    int resto;
    if (pis.Trim().Length != 11)
        return false;
    pis = pis.Trim();
    pis = pis.Replace("-", "").Replace(".", "").PadLeft(11, '0');

    soma = 0;
    for (int i = 0; i < 10; i++)
        soma += int.Parse(pis[i].ToString()) * multiplicador[i];
    resto = soma % 11;
    if (resto < 2)
        resto = 0;
    else
        resto = 11 - resto;
    return pis.EndsWith(resto.ToString());
}

Prontinho, acabamos de criar um pequeno componente utilizando o C#, Salve o projeto e o compile. Ver Imagem 02.

Figura 02: Compilando.

A Instalação

Clique com o botão direito na “Toolbox” e escolha “Choose Items...” para adicionar a .dll criada anteriormente. Figura 03.


Figura 03: Instalando o Componente.

No botão “Browse...” localize no diretório onde foi salvo, por exemplo:
C:\Diretorio\TextBoxTheClub\bin\Debug\TextBoxTheClub.dll

Figura 04: Adicionando no ToolBox.

A Imagem 05 mostra o “TextBoxTheClub” instalado corretamente na palheta de componentes.

Figura 05: “TextBoxTheClub” localizado na “ToolBox”.

Criando um exemplo prático

Para testá-lo basta encará-lo como um TextBox comum, mas com algumas funcionalidades a mais. Para isto crie um novo Projeto e adicione alguns “TextBoxTheClub” no formulário. Ver Imagem 06.

Figura 06: Criando um exemplo.

Clicando nas propriedades podemos conferir o tipo de validação que foi programado. Aproveite e escolha uma de cada tipo. Ver Imagem 07.

Figura 07: Tipo de Validação (CPF, CNPJ e PIS).

Rodando a aplicação podemos conferir a execução das funções no evento “Onvalidating()”, a troca de cor de acordo com o foco e o tipo pré-definido da cor da fonte. Ver Imagem 08 o exemplo em Run-Time.

Figura 08: Exemplo em Run-Time.

Conclusão

A criação de componentes se torna uma prática muito recomendada na programação Orientada a Objetos, sendo muito utilizada desde o início dos tempos. O principal intuito deste artigo foi de demonstrar que através de pequenos conceitos conseguimos economizar tempo e código no decorrer do desenvolvimento de aplicações. Abordei assuntos como: Herança de Classes, Sobrescrita de métodos e propriedades, criação de classes auxiliares e funções estáticas. Existem diversas formas e mecanismos para se desenvolver um componente, procurei neste artigo simplificar o máximo possível afim de um aprendizado maior. Fica assim, um grande abraço e até o mês que vem!

C# - Criando Classes e Objetos



Nesta importante etapa abordarei um conceito geral de Classes e Objetos na linguagem C# aproveitando para descrever os tipos mais importantes ao decorrer do nosso aprendizado. Na Programação Orientada a Objetos (POO) tudo é baseado em classes e objetos, sendo que o conceito é universal e imprescindível, qualquer que seja a linguagem em que esta seja aplicada. A POO procura estabelecer um modelo de programação que aproxima o desenvolvedor do mundo real.  Seguiremos enfatizando os principais conceitos e posteriormente um exemplo prático do uso de Classes e Objetos.

Conceito Geral de Classes e Objetos

Uma classe é uma unidade do sistema e dentro dela estão definidos atributos e métodos, que são respectivamente as informações que uma classe pode armazenar e ações que elas podem desempenhar.
Para ficar mais fácil o entendimento, um atributo possui as mesmas funcionalidades de uma variável, assim como um método o mesmo que um procedimento ou função. A diferença fundamental entre classe e objeto reside no fato da classe conter as definições do que essa nova unidade irá fazer e o objeto ser um caso especial de uma classe. É importante saber que enquanto existe apenas uma definição de classe, podem existir diversos objetos baseados numa classe.

A imagem 01 ilustra de uma forma mais didática o que estou descrevendo.

Figura 01: Classe e Objeto.

Conceito de Atributos

Na realidade, os denominados atributos nada mais são do que as variáveis da classe, os locais que guardarão as informações referentes aquela classe. Quando um objeto é criado a partir de uma classe, neste momento os atributos passam a ter informações específicas assumindo estados especiais, ou seja, de uma forma geral este é o momento onde são atribuídos os valores. Existem dois tipos de atributos, os que permitem acesso externo ao da classe e os que não permitem, são denominados respectivamente de “Públicos” e “Privados”.  Aproveitando este tópico, falaremos de um recurso importante da POO, o Encapsulamento de dados, que significa uma proteção às suas propriedades.  De uma forma geral, estes conceitos são melhores compreendidos seguindo o exemplo a seguir.

Exemplo:

//Declaração do atributo do tipo “string” e “private” private string nome;


A linguagem C#, junto com o Visual Studio possui inúmeros macetes que nos auxilia diariamente. Podemos então encapsular estas propriedade com a ajuda do “Refactor”, clicando com o botão direito em “nome” escolhendo “Refactor/Encapsulate Field...”
Ver Figura 02.
Figura 02: Refactor/Encapsulate Field.

Logo após aparecerá uma janela com os seguintes dizeres. Ver Imagem 03.

Figura 03: Encapsulate Field.

Por padrão a Propriedade “nome” virá com a primeira letra em maiúsculo, isto serve para diferenciar da propriedade privada criada anteriormente. Clique no botão “Ok” para prosseguir com o código a seguir.

//Encapsulamento do atributo Público Nome
public string Nome
{
      get
      {
           return nome;
      }
      set
      {
           nome = value;
      }
}

Deixamos o atributo “Nome” dinâmico, pois poderemos retornar e atribuir valores dinamicamente com os operadores “Get” e “Set” respectivamente, permitindo criar regras e lógicas para acesso a dados e público permitindo uma visibilidade e acessibilidade externa à Classe. Usaremos este recurso para fins didáticos, sem nenhuma regra adicional.

Conceito de Métodos

São as funções e Procedimentos dentro da classe. Realizam operações sobre as informações contidas nos atributos de uma classe. Os métodos podem ser entendidos como mensagens trocadas entre diferentes objetos. Assim como os atributos, os métodos também podem ser do tipo público ou privado.

Exemplo:

//Declaração do método Cadastrar(), do tipo “void” e “public”

public void Cadastrar()
{
      MessageBox.Show("Cadastrando sócio... ");       
}

Métodos do tipo “void” podem ser comparados aos procedimentos, ou seja, não retornam nenhum valor. Já para retornar algum dado veremos o exemplo a seguir.

Exemplo:


//Declaração do método ConfirmarCadastro(), do tipo “bool” e “public”

public bool ConfirmarCadastro(int tipo)
{
      if (tipo == 1)
          return true;
      else
          return true;
}

O método criado anteriormente está retornando um valor do tipo Booleano utilizando a cláusula “return”, que significa retorno.

Construtores e Destrutores

Toda classe criada deverá possuir dois métodos: o Construtor (Construct) que é chamado no momento quando instanciamos a Classe e o Destrutor (Destruct) quando liberamos o objeto criado por esta classe da memória.
No C# temos o denominado “Garbage Collector”, trocando em miúdos seria um “Coletor de Lixos”. Ele é responsável pela destruição de todo objeto que não é mais utilizado, sendo um recurso capaz de oferecer uma solução automatizada ao gerenciamento de memória.

Exemplo:


//Construtor
public Socio()
{
    MessageBox.Show("Objeto Criado com sucesso!");
}



//Destrutor
~Socio()da classe
{

}

O método Construtor será invocado quando instanciamos a Classe “Socio” e para fins de aprendizado achei interessante demonstrar a sintaxe do Destrutor, que normalmente não precisamos nos preocupar, pois contamos com o recurso “Garbage Collector” citado anteriormente.

Tipos de Classes

Na Programação Orientada a Objetos contamos com diversos tipos de classes como: Públicas, Privadas, Protegidas, Estáticas, Abstratas, Seladas, Herdadas entre outras, sendo que todas possuem recursos que se encaixam ao decorrer da análise do projetista. Nesta etapa abordarei os principais conceitos referentes a este assunto

Pública (Public)

As classes públicas, assim como os atributos e métodos, permitem que qualquer pessoa instancie objetos. O nome da classe é precedido pelo nível de acesso (public) seguindo pela palavra chave “class”.

Exemplo:

public class Socio
{
   // Códigos da Classe
}

Neste caso temos uma classe pública chamada “Socio”.

Privada (Private)

Seguindo a mesma lógica dos atributos e métodos, as classes privadas não permitem acesso externo. A sintaxe de criação pode ser conferida a seguir.
Exemplo:

private class Socio
{
   // Códigos da Classe
}
Ou
class Socio
{
   // Códigos da Classe
}

Existem duas maneiras para declaração de classes privadas, a primeira utilizando a palavra “private” e a segunda sem nenhuma referência. Com o exemplo citado anteriormente fica mais fácil a visualização.

Instanciáveis

Este tipo de classe é o mais utilizado, ou seja, toda vez que precisarmos criar um objeto, é necessário instanciá-lo, podendo assim criar vários objetos desta mesma classe.

Exemplo de criação:

Public class Socio
{
   //atributos estáticos
  
   private string nome;
    
   public string Nome
   {
        get { return nome;}
        set { nome = value;}
   }
}

Exemplo de utilização:

Socio soc = new Socio();
soc.Nome = "Thiago Montebugnoli";

Estáticas

Quando utilizamos estes tipos de classes, deveremos por obrigação, possuir todos os atributos como estáticos. A principal característica destas classes é não permitir realizar a instância de um objeto, ou seja, quando for utilizá-la basta fazer referência aos membros para poder trabalhar com os mesmos.
Exemplo de criação:

Public static class Socio
{
   //atributos estáticos
  
   private static string nome;
    
   public static string Nome
   {
        get { return Socio.nome;}
        set { Socio.nome = value;}
   }
}

Exemplo de utilização:


Socio.nome = “Thiago Montebugnoli”

Na sua utilização basta atribuir o valor desejado. Como foi dito anteriormente, a instancia já é criada automaticamente quando executamos o programa, podendo ser utilizada em todos os pontos do software. A principal vantagem no uso desta classe é a automatização na criação da instância.

Criando um Exemplo prático

Crie uma aplicação “Windows Forms” e adicione um botão no formulário. A tela deverá ficar idêntica a Imagem 04.

Figura 04: Tela de Exemplo.

A partir de agora irei detalhar todas as etapas de como se deve criar uma classe e usá-la logo em seguida, para isto clique em cima da solução e com o botão direito escolha “Add/New Item...” e na região esquerda em “Visual C# Items” escolha “Code” e em seguida “Class”. Aproveite e clique no botão “Add”. Ver Imagem 05.

Figura 05: Adicionando uma Classe no projeto.

O Visual Studio por padrão cria apenas o namespace “Classes”, e a classe “Socio”. Vou criar uma classe pública e logo em seguida instanciá-la. A Imagem 01 nos ilustra de uma forma clara de como irá ficar nossa classe “Socio” e o código abaixo abrange de uma forma prática todas as etapas explicadas anteriormente.

//Namespaces utilizados
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Classes
{
   //Classe pública
    public class Socio
    {
        //Construtor da classe
        public Socio()
        {
            MessageBox.Show("Objeto Criado com sucesso!");  
        }

        //Destrutor da classe
        ~Socio()
        {

        }

        //Atributos/Propriedades Privadas Encapsuladas
        private string nome;
        private string cpf;
        private string rg;
        private DateTime nascimento;
        private string telefone;
        private string endereco;

        //Atributos/Propriedades Públicas Encapsuladas
        public string Nome
        {
            get { return nome;}
            set { nome = value;}
        }
       
        public string Cpf
        {
            get { return cpf; }
            set { cpf = value; }
        }

        public string Rg
        {
            get { return rg; }
            set { rg = value; }
        }

        public DateTime Nascimento
        {
            get { return nascimento; }
            set { nascimento = value; }
        }

        public string Telefone
        {
            get { return telefone; }
            set { telefone = value; }
        }

        public string Endereco
        {
            get { return endereco; }
            set { endereco = value; }
        }

        //Métodos públicos
        public void Cadastrar()
        {
MessageBox.Show(string.Format("Cadastrando sócio...\r\nNome: {0}, - Rg: {1}, Cpf: {2}",nome,rg,cpf));  
        }

        public bool ConfirmarCadastro(int tipo)
        {
            if (tipo == 1)
                return true;
            else
                return true;
        }

        public bool ValidarSocio(int tipo)
        {
            if (tipo == 1)
                return true;
            else
                return true;
        }

        public void Alterar()
        {
            MessageBox.Show("Alterando sócio...");
   
        }
    }
}


No formulário criado iremos instanciar um objeto da classe “Socio” e logo em seguida o código comentado correspondente.

private void button1_Click(object sender, EventArgs e)
{
     //Instanciando um objeto
     Socio soc = new Socio();

     //Inserindo atributos
     soc.Nome = "Thiago Montebugnoli";
     soc.Rg = "41.999.999-9";
     soc.Cpf = "312.999.999-99";
     soc.Nascimento = DateTime.Parse("15/11/1984");
     soc.Telefone = "(14) 9999-9999";
     soc.Endereco = "Rua Fulano de Tal, 999";
    
     //Invocando métodos
     soc.Cadastrar();

     if (soc.ConfirmarCadastro(1))
         MessageBox.Show("Cadastro Confirmado!");

     if (soc.ValidarSocio(1))
         MessageBox.Show("Sócio Validado!");
          
     soc.Alterar();
}

O primeiro passo foi criado o objeto “soc” usando a palavra reservada “new”, logo em seguida definimos os atributos e invocamos os métodos. A Figura 06, 07 e 08 nos dá uma boa idéia do funcionamento de uma classe em “Run-Time” .

Figura 06: Passo 01 - Construtor.


Figura 07: Passo 02 – Atribuindo Valores e Executando Métodos.


Figura 08: Passo 03 – Executando Métodos.

Conclusão

Neste artigo procurei separar em duas etapas, a primeira com conceitos básicos de Programação Orientada a Objetos (POO) e a outra com um exemplo prático e de fácil entendimento. Vou continuar com conceitos e dicas sobre este assunto nos próximos artigos.
Abraços e até o mês que vem!