segunda-feira, 12 de setembro de 2011

Usando MessageBox

Para que as mensagens apareçam em portugues (na lingua no sistema) não eh necessário a tradução das units.

Invés de usar a função messagedlg eh melhor usar a função MessageBox

Sintax:

MessageBox (Handle, Messagem, Caption, Botoes)
onde

Handle : Endereço do form na memória ; Sempre usu Application.Handle
Messagem : A messagem a ser mostrada
Caption : O titulo da messagem
Botoes : Os Botoes que irao ser mostrados. Na lingua do sistema


MB_ABORTRETRYIGNORE A messagem mostra os tres botoes: Abort, Retry, and Ignore.
MB_OK A messagem mostra um botoao: OK. This is the default.
MB_OKCANCEL A messagem mostra os dois botoes: OK and Cancel.
MB_RETRYCANCEL A messagem mostra os dois botoes: Retry and Cancel.
MB_YESNO A messagem mostra os dois botoes: Yes and No.
MB_YESNOCANCEL A messagem mostra os tres botoes: Yes, No, and Cancel.

Sons
MB_ICONEXCLAMATION, MB_ICONWARNING: Mostra o icone de exclamação e som conrrespondente. Analo aos demais
MB_ICONINFORMATION, MB_ICONASTERISK
MB_ICONQUESTION
MB_ICONSTOP,
MB_ICONERROR,
MB_ICONHAND
Botoes padrao
MB_DEFBUTTON1: Padrao nao precisa ser colocado.
MB_DEFBUTTON2: Coloca o segundo botao como padrao
MB_DEFBUTTON3: Coloca o terceiro botao como padrao
MB_DEFBUTTON4: Coloca o quarto botao como padrao
Respostas
IDABORT
IDCANCEL
IDIGNORE
IDNO
IDOK
IDRETRY
IDYES

Exemplo
Case MessageBox (Application.Handle, Pchar ('Deseja excluir o arquivo' + #13 + Label1.caption), 'Exclusao de arquivo', MB_YESNOCANCEL+MB_EXCLAMATION+MB_DEFBUTTON2) of
idYes: Procedimento
idNo: Procedimento
idCancel: Procedimento
end;

quinta-feira, 8 de setembro de 2011

Ocultar aplicação da lista de tarefas - CTRL+ALT+DEL

- Declare a função abaixo antes da palavra implementation:

function RegisterServiceProcess(dwProcessID, dwType: Integer): 
  Integer; stdcall; external 'KERNEL32.DLL';

- Coloque dois botões no Form;
- No evento OnClick do Button1 coloque:

RegisterServiceProcess(GetCurrentProcessID, 1);

- No evento OnClick do Button2 coloque:

RegisterServiceProcess(GetCurrentProcessID, 0);

=== Para testar ===

Clique no Button1 e pressione CTRL+ALT+DEL. O seu programa
não aparecerá na lista.

Clique no Button2 e pressione CTRL+ALT+DEL. Agora seu programa
aparecerá na lista.

quarta-feira, 7 de setembro de 2011

Mudar a cor do Edit ao receber o foco

Alguns programas mostram o Edit que está com o foco em uma cor diferente dos demais. 
Como fazer isto em Delphi?
Na seção private do form declare o procedimento abaixo:
  
  private
    procedure MudancaDeFoco(Sender: TObject);
  public
  end;

Na seção implementation, escreva o código do procedimento:

{ Esta rotina será chamada através do evento OnExit (perda do foco)
  de todos os componentes do tipo TEdit que existirem no form. }
procedure TForm1.MudancaDeFoco(Sender: TObject);
var
  I: integer;
  Ed: TEdit;
begin
  { Percorre a matriz de componentes do form }
  for I := 0 to ComponentCount - 1 do
    { Se o componente é do tipo TEdit... }
    if Components[I] is TEdit then
    begin
      { Faz um type-casting pata o tipo TEdit }
      Ed := Components[I] as TEdit;

      { Se o Edit está com o foco... }
      if Ed.Focused then
        Ed.Color := clYellow { Amarelo }
      else
        Ed.Color := clWhite; { Branco }
    end;
end;

No evento OnCreate do Form, coloque o código abaixo:

procedure TForm1.FormCreate(Sender: TObject);
var
  I: integer;
begin
  { Percorre a lista de componentes do form (matriz de componentes)
    e verifica cada componente para saber se é um TEdit. Se for,
    associa o evento OnExit do componente com a procedure
    "MudancaDeFoco". }
  for I := 0 to ComponentCount - 1 do
    if Components[I] is TEdit then
      (Components[I] as TEdit).OnExit := MudancaDeFoco;
end;

No evento OnActivate coloque:

procedure TForm1.FormActivate(Sender: TObject);
begin
  { Esta chamada é necessária para que o estado inicial seja
    controlado. }
  MudancaDeFoco(nil);
end;

Observações

Existem outras técnicas mais profissionais para resolver o problema proposto. Uma alternativa excelente é a criação de um novo componente herdado da classe TEdit (ou TCustomEdit) que implemente a mudança de cor no método DoEnter e DoExit.

Arredondamento financeiro

É muito comum encontrar programadores Delphi que têm dúvidas sobre como arredondar um valor real para "n" casas após o separador decimal. A princípio parece um problema simples, pois o próprio Delphi já possui uma função que arredonda para o inteiro mais próximo, a qual poderia facilmente ser utilizada para arredondar para qualquer quantidade de casas decimais. Exemplo:

{ x receberá o valor de y arredondado para 2 casas após o separador. }
x := Round(y * 100) / 100;

{ z receberá o valor de y arredondado para 3 casas após o separador. }
z := Round(y * 1000) / 1000;
No entanto dois problemas poderão aparecer com os exemplos acima:
  • O arredondamento feito pelo Delphi difere daquele feito pelas calculadores financeiras, bem como bancos de dados como InterBase e FireBird.
  • poderão ocorrer pequenos arredondamentos devido ao modo como o Delphi trata números reais, tais como aparecer 3.9999999... em vez de 4.
A função abaixo resolve estes dois problemas.
{ Esta função faz arredondamento de valores reais para "n" casas
  decimais após o separador decimal, seguindo os critérios das
  calculadoras financeiras e dos bancos de dados InterBase e FireBird.
}
function TBRound(Value: Extended; Decimals: integer): Extended;
var
  Factor, Fraction: Extended;
begin
  Factor := IntPower(10, Decimals);
  { A conversão para string e depois para float evita
    erros de arredondamentos indesejáveis. }
  Value := StrToFloat(FloatToStr(Value * Factor));
  Result := Int(Value);
  Fraction := Frac(Value);
  if Fraction >= 0.5 then
    Result := Result + 1
  else if Fraction <= -0.5 then
    Result := Result - 1;
  Result := Result / Factor;
end;

Consultar por mês de um campo data

Problema:

Tenho um cadastro de clientes com Codigo, Nome, DataNasc, etc.
Preciso fazer uma consulta onde apareceão apenas os clientes
que fazem aniversário em determinado mês. Como fazer?

Solução:

Use uma Query como abaixo:
- Coloque no form os seguintes componentes:
  * TQuery
  * TDataSource
  * TDBGrid
  * TEdit
  * TButton

- Altere as propriedades dos componentes como abaixo:
  * Query1.DatabaseName = (alias do BDE)
  * DataSource1.DataSet = Query1
  * DBGrid1.DataSource = DataSource1
  
- Coloque o código abaixo no evento OnClick de Button1:

  Query1.Close;
  Query1.SQL.Clear;
  Query1.SQL.Add('select * from dCli');
  Query1.SQL.Add('where extract(month from DataNasc) = :Mes');
  Query1.ParamByName('Mes').AsInteger := StrToInt(Edit1.Text);
  Query1.Open;

- Execute. Digite um número de 1 a 12 no Edit e clique no 
  botão.

Observações

Os números de 1 a 12 representam, respectivamente, os meses de Janeiro a Dezembro. Este exemplo foi testado com Delphi4, BDE5 e tabela Paradox7.

DBGrid zebrado

Programe o evento OnDrawColumnCell do DBGrid como abaixo:

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
begin
  if State = [] then
  begin
    if Table1.RecNo mod 2 = 1 then
      DBGrid1.Canvas.Brush.Color := clAqua
    else
      DBGrid1.Canvas.Brush.Color := clWhite;
  end;
  DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

Observação:
O objeto Table1 é da classe TTable (relativa ao BDE), mas esta dica poderá ser usada com outros DataSet's, tais como IBDataSet, ClientDataSet, etc.

domingo, 4 de setembro de 2011

Usando funções no MySQL


Vou tentar passar aqui, um pequeno exemplo de como usar funções do MySQL em nossas instruções SQL.
Em primeiro lugar, certifique-se que você possua instalado uma versão a partir da 5.x do MySQL em seu micro.
No nosso exemplo, criaremos e utilizaremos uma função que retornará a idade do cliente
Crie uma pequena tabela com a seguinte estrutura:

CREATE TABLE `clientes` (
`ID` int(11) NOT NULL auto_increment,
`NOME` varchar(45) default NULL,
`DATANASC` date default NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `ID` (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;



Inclua as linhas abaixo na tabela, ou digite suas próprias informações:


INSERT I NTO `clientes` (`ID`, `NOME`, `DATANASC`) VALUES
(1, 'SILVIO SANTOS', '1971-09-18'),
(2, 'SILLAS SANTOS', '1993-04-27');


Agora, crie a função conforme o exemplo abaixo:


CREATE FUNCTION `idade`(pDATA DATE)
RETURNS varchar(15) CHARSET latin1
NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER
COMMENT ''
Begin
DECLARE vIDADE varchar(30);
IF DATE_FORMAT(NOW( ),'00-%m-%d') >= DATE_FORMAT(pDATA,'00-%m-%d') THEN
SET @idade=DATE_FORMAT(NOW( ),'%Y')-DATE_FORMAT(pDATA,'%Y');
ELSE
SET @idade=DATE_FORMAT(NOW( ),'%Y')-DATE_FORMAT(pDATA,'%Y')-1;
END IF;
RETURN(concat(@idade,' anos'));
end;


Esta função, retornará a idade da pessoa de acordo com o campo DATANASC, da tabela ‘clientes’.
Veja que a função receberá um valor (pDATA, que no nosso exemplo será o campo ‘DATANASC’ de nossa tabela) e fará a subtração da “dat a corrente” pela data do campo DATANASC.
Dentro da função, criamos uma variável (vIDADE), onde armazenaremos o valor a ser retornado pela função. Note também que a função possui retorno do tipo String (RETURNS varchar(30)), que deverá ter o tamanho suficiente para comportar o resultado retornado. Ou seja, se o valor retornado tiver 15 caracteres, o ‘RETURNS’ da função precisa ter tamanho de 15 ou mais caracteres, senão, pode acontecer de não retornar nenhum valor.

Após ter criado a tabela, inserido as linhas na mesma e criado a função, execute a seguinte instrução:


SELECT NOME, idade(DATANASC) IDADE FROM clientes;


No SQL acima, a consulta irá retornar o Nome, e a idade assim: “XX anos”, para cada cliente.

Como você viu, utilizar funções dentro do banco de dados por ser muito mais prático do que fazê-lo dentro da aplicação (me refiro a funções para retorno de dados, claro).

Lembrando que este exemplo é apenas uma base, pois podemos criar funções para qualquer necessdiade, como: calculo de preços, juros de mora, datas, horas, concatenação de campos complexos, junções de tabelas (como nos inner, left e right joins (desde que precise retornar apenas um valor), e muito mais.

Curso de Delphi: 7.Consultas SQL