Frases…

Dec 15
2010

“Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.”
Martin Golding

vi no twitter do Munif

[Delphi] Criando campos dinâmicos

Dec 06
2010

Bom dia meu povo.

Dia desses precisei criar dinamicamente algumas colunas em um TClientDataset. Normalmente um uso a propriedade FieldDefs por ser mais fácil de manipular e evitar problemas de MemoryLeaks. Mas nesse caso específico eu precisava dos campos como novos objetos, portanto tinham de herdar diretamente de TField. Assim, após algum trabalho, cheguei no resultado abaixo.

procedure CriaField_Integer(cFieldName: String; cDisplayLabel: String; fFieldKind: TFieldKind; nDisplayWidth: Integer; var ds: TClientDataSet; lVisible: Boolean);
begin
    with TIntegerField.Create(Self) do
    begin
        FieldName      := cFieldName;
        Name           := ds.Name + UpperCase(FieldName);
        FieldKind      := fFieldKind;
        Size           := 0;
        DisplayLabel   := cDisplayLabel;
        DisplayWidth   := nDisplayWidth;
        Visible        := lVisible;
        DataSet        := ds;
    end;
end;

procedure CriaField_Boolean(cFieldName: String; cDisplayLabel: String; fFieldKind: TFieldKind; nDisplayWidth: Integer; var ds: TClientDataSet; lVisible: Boolean);
begin
    with TBooleanField.Create(Self) do
    begin
        FieldName      := cFieldName;
        Name           := ds.Name + UpperCase(FieldName);
        FieldKind      := fFieldKind;
        DisplayLabel   := cDisplayLabel;
        DisplayWidth   := nDisplayWidth;
        Visible        := lVisible;
        DataSet        := ds;
    end;
end;

procedure CriaField_DateTime(cFieldName, cDisplayLabel: String; fFieldKind: TFieldKind; nDisplayWidth: Integer; var ds: TClientDataSet; lVisible: Boolean);
begin
    with TDateTimeField.Create(Self) do
    begin
        FieldName     := cFieldName;
        Name          := ds.Name + UpperCase(FieldName);
        FieldKind     := fFieldKind;
        Size          := 0;
        DisplayLabel  := cDisplayLabel;
        DisplayWidth  := nDisplayWidth;
        Visible       := lVisible;
        DataSet       := ds;
    end;
end;

procedure CriaField_Float(cFieldName: String; cDisplayLabel: String; fFieldKind: TFieldKind; nPrecision, nDisplayWidth: Integer; cDisplayFormat: String; var ds: TClientDataSet; lVisible: Boolean);
begin
    with TFloatField.Create(Self) do
    begin
        FieldName     := cFieldName;
        Name          := ds.Name + UpperCase(FieldName);
        FieldKind     := fFieldKind;
        Size          := 0;
        Precision     := nPrecision;
        DisplayLabel  := cDisplayLabel;
        DisplayWidth  := nDisplayWidth;
        DisplayFormat := cDisplayFormat;
        Visible       := lVisible;
        DataSet       := ds;
    end;
end;

Como por aqui não tem muita orientação à objetos, não fiz muita firula, quem sabe eu dou uma melhorada nesse código outro dia, ou vocês mesmos o fazem.

Meu TCC – SOS

Dec 01
2010

Na minha graduação eu criei um controle (extremamente simples) para ordens de serviço (Sistema de Ordens de Serviço, dai a sigla).

Embora eu sempre enxerguei como sendo meu último trabalho acadêmico a maioria dos meus professores vislumbraram que deveria ser o grande trabalho da minha vida. Ledo engano. Bom, fui aprovado, portanto não deve ter ficado tão ruim, principalmente porque apliquei nele diversas práticas que aprendi dentro e fora da instituição e se hoje fosse faze-lo novamente, estou certo de que escreveria uns 30% menos códigos, no mínimo.

De qualquer forma, eu compactei e coloco aqui como anexo. Podem baixar à vontade, só peço que, caso o utilizem de alguma forma como auxílio no seu trabalho, me citem de alguma forma como referência.

Projeto Completo

A documentação eu acrescento um outro dia.

Padrão Builder com Delphi

Oct 06
2010

Voltando a falar de programação, hoje vamos continuar a falar da orientação à objetos dentro do Delphi. Apesar de estar estudando Java já tem algum tempo, eu trabalho com Delphi desde de sua versão 2.0, então fica bem difícil não querer aplicar tudo o que aprendi sobre o assunto na linguagem que tenho mais afinidade.
Read the rest of this entry »

Levantamento de Requisitos

Sep 20
2010

Recentemente, em uma palestra, me perguntaram qual a parte mais importante no planejamento de um software. Na minha humilde opinião eu respondi que além de coisas como manutenabilidade e boa documentação (não muita, mas de qualidade), o que eu achava mais importante é extrair as informações do cliente e até mesmo envolve-lo no processo, como acontece no Scrum.

Naquela ocasião citei uma imagem que exemplifica de maneira sem retoques o que eu estava falando. Quem puder dizer que não é verdade que atire o primeiro código-fonte.

Como mudar a cor da coluna ativa da DBGrid

Sep 17
2010

Eu vou começar uma série de posts, bastante básicos, sobre coisas que já usei em Delphi.

A rotina abaixo deverá ser colocada no evento OnDrawDataCell, e vai mudar a cor da coluna ativa em uma DBGrid.

procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect; Field: TField; State: TGridDrawState);
begin
    if gdFocused in state then
        with TDBGrid(sender).Canvas do
        begin
            Brush.Color := clRed;
            FillRect( cRect );
            TextOut(Rect.Left, Rect.Top, Field.AsString);
        end;
end;

PS: Eu usei isso no Delphi 3.0, mas acho que ainda deve funcionar.

Palestra Noções de Programação

Sep 16
2010

Como prometido, estou publicando a palestra que realizei ontem com a turma de Administração do CESUMAR.
Uma turma bastante atenta e participativa, diga-se de passagem.

Dúvidas, podem colocar nos comentários ou mandar um e-mail para mim.

Criando listas com PHP/MySQL – Paginação

Sep 11
2010

Olá amiguinhos.

Depois de colocar uma listagem bem simples, buscando os dados do banco e montando numa tabela, eu vou colocar o resto da implementação, bem como os arquivos do projeto.

Nesse post vamos criar a lista, pagina, postando para uma página de tratamento fictícia. Vamos usar um pouco de Javascript e CSS, mas não é obrigatório, é só para dar alguma elegância ao projeto.

Como eu fiz esse artigo meio que de encomenda para um amigo, que não queria usar Ajax, eu não isso aqui. Portanto pense nisso antes das críticas :D .
Read the rest of this entry »

Criando listas com PHP/MySQL

Aug 30
2010

Hoje resolvi variar um pouco. Como estou ajudando um amigo no seu TCC, escrevi para ele uma função bem legal, pelo menos eu achei, depois me falem o que acharam. Eu vou colocar ela aqui em duas etapas. Nessa primeira, vamos criar uma lista, somente passando uma tabela do banco. A assinatura da função vai ficar mais ou menos assim:

<?php
	include_once('conexao.php');
	include('funcoes.php');

	CriarLista('Estado');
?>

A conexão é bem simples, faça como quiser.
Já a função, baseia-se na instrução SQL: SHOW FULL COLUMNS FROM TB_CLIENTE. Essa instrução retorna uma lista com os campos: Field, Type, Collation, Null, Key, Default, Extra Privileges e Comment. Para nós, nesse momento só interessam Field e Comment. Explico. Pegaremos os campos que retornam nessa SQL e com eles, comporemos a nova SQL com os campos que a primeira retornou, ficou claro?
Nos comments da tabela em questão, eu coloquei a descrição dos campos, tipo o campo EST_CODIGO tem o comentário “Código”.
Read the rest of this entry »

Orientação à Objetos em Delphi (Parte 1 e 1/2)

Aug 27
2010

Apesar do povo no twitter querer me massacrar quando digo que o Delphi é uma linguagem (muito boa por sinal), há muito que ele não trata mais de Pascal com uma IDE bonitinha. Mas como eu respondi lá, isso é uma questão comercial, que pouco me importa, afinal, não ganho ou perco um centavo com isso. Quanto a linguagem ser boa, não há dúvidas, com ela eu construi minha casa, estou pagando o carro, os meus treinamentos, a educação do meu filho…

Piadas à parte, vamos ao ponto, no último post que eu tratei sobre o assunto (Orientação à Objetos) a coisa ficou meio descontextualizada, principalmente por se tratar de uma palestra que fiz aqui na Produtec. Assim, vou tentar simplificar um pouco mais o conceito, sem necessariamente entrar na conversa com o banco.
Primeiro vamos imaginar um problema. Alguém lhe fez a solicitação:

Criar uma classe Lampada, que tenha como ser ligada, desligada e possa me responder seu atual estado (ON/OFF). Essa pessoa lhe solicitou também um formulário que interagisse com essa classe, acessando os seus métodos.

Então vejamos, temos uma classe mais ou menos como a desenhada abaixo:


Como vemos, teremos então a classe Lampada, que possuirá um atributo privado chamado acesa do tipo boleano e três métodos públicos bastante simples; ligarLampada() muda o atributo acesa para true, desligarLampada() seta o atributo para false e isLampadaLigada() que retorna o estado do atributo. Até aqui bem simples.
Para a implementação eu vou herdar de TControl, por enquanto isso será suficiente, afinal não quero ter que implementar as coisas mais básicas na mão, como a criação do componente e tal. Isso fica mais ou menos assim:

unit uLampada;

interface

uses Controls;

type
  TLampada = class(TControl)
  private
      Facesa: Boolean;
      procedure Setacesa(const Value: Boolean);
      property acesa: Boolean read Facesa write Setacesa;
  public
      procedure LigarLampada;
      procedure DesligarLampada;
      function isLampadaLigada: Boolean;
  end;

implementation

{ TLampada }

procedure TLampada.DesligarLampada;
begin
   acesa := False;
end;

function TLampada.isLampadaLigada: Boolean;
begin
   Result := acesa;
end;

procedure TLampada.LigarLampada;
begin
   acesa := True;
end;

procedure TLampada.Setacesa(const Value: Boolean);
begin
   Facesa := Value;
end;

end.

Percebam aqui algumas particularidades do Delphi. Pra começar, os métodos tem um “tipo”. Métodos que necessitam retornar valores são declarados como function e os que não precisam retornar valor, portanto são somente procedimentos, são assim chamados procedure. Ambos podem receber parâmetros, mas no nosso exemplo não tivemos necessidade. A única diferença é mesmo o retorno.

Para declarar a propriedade acesa, eu simplesmente digitei property acesa:boolean; e pressionei o atalho Ctrl+Shift+C. Isso nos leva a outro ponto legal de destacar que é o encapsulamento. Veja como ficou o código:

  private
      Facesa: Boolean;
      procedure Setacesa(const Value: Boolean);
      property acesa: Boolean read Facesa write Setacesa;

Assim, na prática, o valor será gravado em Facesa (o “F” é padrão do Delphi, não pergunte). Como se percebe ele completou a linha com as cláusulas read e write, determinado assim o Getter e o Setter da propriedade acesa. Portanto quando uma chamada um outro objeto acessar a propriedade acesa, a classe irá ler o valor da variável Facesa e na hora de atribuir o valor, o procedimento Setacesa(const Value: Boolean);.

A cláusula const antes do parâmetro indica que o mesmo não pode ser alterado no corpo do procedimento. Ele pode ser atribuído normalmente na chamada.

Com o procedimento SetAcesa podemos colocar quaisquer tratamentos que se fizerem necessários. Mas isso é assunto para outro post.

Para a aplicação rodar como pedido, devemos criar um formulário que interaja com um objeto da classe criada. Vou não criar muita firula aqui, serão apenas 3 botões, Ligar, Desligar e Status.

Aqui fica mais clara ainda a simplicidade desse sistema. Basta criar uma instância da classe TLampada e fazer com que os botões acessem os seus métodos. Veja como ficou simples.

unit uInterruptor;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, uLampada;

type
  TfrmInterruptor = class(TForm)
    btnLigar: TButton;
    btnDesligar: TButton;
    btnStatus: TButton;
    procedure btnStatusClick(Sender: TObject);
    procedure btnDesligarClick(Sender: TObject);
    procedure btnLigarClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    MinhaLampada: TLampada;
  public
  end;

var
  frmInterruptor: TfrmInterruptor;

implementation

{$R *.dfm}

procedure TfrmInterruptor.btnDesligarClick(Sender: TObject);
begin
   MinhaLampada.DesligarLampada;
end;

procedure TfrmInterruptor.btnLigarClick(Sender: TObject);
begin
   MinhaLampada.LigarLampada;
end;

procedure TfrmInterruptor.btnStatusClick(Sender: TObject);
var
   cMsg: String;
begin
   cMsg := 'A lâmpada ';

   if not MinhaLampada.isLampadaLigada then
      cMsg := cMsg + 'não ';

   cMsg := cMsg + 'está ligada.';
   ShowMessage(cMsg);
end;

procedure TfrmInterruptor.FormCreate(Sender: TObject);
begin
   MinhaLampada := TLampada.Create(Self);
end;

end.

A única dica é criar a MinhaLampada na criação do formulário. Não preciso me preocupar com dispor dela, pois ela foi criada “afiliada” ao form, portanto quando um for para o vinagre o outro vai junto.

Bom pessoal, agora que desaceleramos e começamos de maneira mais básica acho que consegui isolar um pouco mais os conceitos. Acredito que todos entendem que temos uma classe TLampada, com atributos privados, com métodos públicos que nos permitem controlar a lâmpada. Esclarecemos também que o que se manipula posteriormente é a instancia, o objeto MinhaLampada, não a classe. E podemos ter quantas instancias da Lampada criadas dentro da nossa aplicação.

No próximo post sobre o assunto vamos criar um serviço que controle a “energia” do exemplo. Até lá.

Arquivo

Categorias