terça-feira, 27 de novembro de 2012

Como exibir GIF animado no Delphi

Como exibir um GIF animado no Delphi 

Esta dica é de como exibir um GIF no Delphi e ativar a sua animação

Como exibir um GIF no TImage

O TImage do Delphi é capaz de exibir um GIF, mas tem um pequeno truque.
Primeiro adicione o seu TImage ao formulário.
Agora se você tentar carregar um GIF irá ocorrer um erro, para o TImage suportar o GIF adicione a unit GIFImg a clausula uses do formulário. Simples assim :D

Exibir a animação do GIF

Agora você poderá carregar o GIF no TImage sem problemas, no entanto esta será estático.
Para ativar a animação utilize o seguinte código

TGIFImage(image1.Picture.Graphic).Animate := True;

Muito bem agora o seu GIF estará animado com animação sendo exibida em loop

Como evitar o Flicker do GIF (Imagem piscando)


Provavelmente ao exibir a imagem esta ficará piscando.
Para resolver este problema você deve setar as seguintes propriedades:

image1.Proportional := False;
image1.Stretch      := True;

Muito bem, com estas dicas será fácil colocar um GIF animado no seu programa. Até a próxima

3 comentários:

terça-feira, 20 de novembro de 2012

XML Data Binding no Delphi - Parte 3

Como alterar o Arquivo XML em Delphi

Continuando o projeto iniciado na parte 1
Agora veremos como alterar o arquivo XML inserindo novos dados e salvando este arquivo para uso posterior.

Interface 

Continuando o projeto, adicione dois TEdit, um para o Nome do Contato e outro para o Telefone do Contato. Adicione também um botão para inserir os dados no XML.



Visualizar o Contato

 Adicione o seguinte código no evento OnClick do TButton.

var Agenda  : IXMLAgendaType;
    Contato : IXMLContatoType;
    Arquivo : TStringList;
begin
  Agenda  := Loadagenda('agenda.xml');
  Contato := Agenda.Add();
  Contato.Id := Agenda.ChildNodes.Count;
  Contato.Nome := edNome.Text;
  Contato.Fone := edTelefone.Text;

  Arquivo := TStringList.Create;
  Arquivo.Add(Agenda.XML);
  Arquivo.SaveToFile('agenda.xml');
  Arquivo.Free;
 

Explicação do Código 

Primeiramente carregamos novamente o XML para um Objeto como no artigo anterior.
O Método Add do nosso objeto retorna um novo Objeto do tipo IXMLContatoType onde iremos setar o Nome e Telefone do contato.
Depois utilizamos um TStringList para salvar novamente o XML para o arquivo.
Experimente agora utilizar o botão Visualizar e  veja que o nosso novo contato irá aparecer também.

Outros Métodos disponibilizados

  • Remove(const Node: IXMLNode) : Permite remover do XML o node passado como parâmetro.
  • Count : Retorna o número de nós filhos(contatos)
  • Clear : Permite limpar a lista de contatos

 Webservices

Neste exemplo utilizamos um arquivo salvo localmente, mas é possível utilizar o Data Binding também recebendo um XML de um WebService e acessando diretamente suas propriedades, sem necessidade de ler e salvar Nós do arquivo XML.

Até a próxima



0 comentários:

quarta-feira, 14 de novembro de 2012

XML Data Binding no Delphi - Parte 2

Como acessar o Arquivo XML em Delphi

Continuando o projeto iniciado na parte 1
Agora veremos como abrir o arquivo XML e visualizar os dados presentes neste.

Interface

Crie um novo projeto no Delphi com esta aparência utilizando um TButton e um TMemo.
Salve o arquivo XML na mesma pasta do executável para simplificar o código.
Adicione a unit gerada pelo Data Binding a cláusula Uses do formulário.

Visualizar os contatos

 Adicione o seguinte código no evento OnClick do TButton.

var Agenda  : IXMLAgendaType;
    Contato : IXMLContatoType;
    idx     : Integer;
begin
  // Ler dados do arquivo XML
  Agenda := Loadagenda('agenda.xml');
  // Limpar o texto do Memo
  mmContatos.Lines.Clear;
  // Ler cada um dos contatos salvos
  for idx := 0 to Agenda.ChildNodes.Count -1 do
  begin
    Contato := Agenda.Contato[idx];
    // Adicionar ao Memo os dados do contato
    mmContatos.Lines.Add('Contato: ' + Contato.Nome + ' Telefone: ' + Contato.Fone);
  end;

Ao executar o projeto e clicar no TButton o formulário deverá ficar assim.


Na próxima parte veremos como adicionar um novo contato e salvar os dados no arquivo para utilização posterior

0 comentários:

XML Data Binding no Delphi - Parte 1

Como Utilizar XML Data Binding no Delphi

Este post é sobre como utilizar o XML Data Binding no Delphi, ou seja como acessar os dados presentes em um arquivo xml como um objeto com métodos e propriedades.
Neste primeira parte iremos criar o arquivo XML que usaremos como base para uma agenda.

Criando o arquivo XML modelo

Primeiro vamos criar um arquivo XML para utilizar o assistente de Data Binding do Delphi para gerar as classes autimaticamente
"Agenda.xml"
<?xml version="1.0" encoding="UTF-8"?>
<agenda>
<contato>
<id>1</id>
<nome>Contato 1</nome>
<fone>(99)9999-9999</fone>
</contato>
<contato>
<id>2</id>
<nome>Contato 2</nome>
<fone>(11)1111-1111</fone>
</contato>
</agenda>


Crie um arquivo utilizando este código e salve com o nome Agenda.xml.
Vá no menu File -> New -> Other.
Na tela que irá aparecer selecione Delphi Projects -> XML -> XML  Data Binding.


No assistente que irá aparecer selecione o arquivo xml que você criou e avance até o Delphi gerar a unit com o código de acesso.


Na próxima parte iremos visualizar os dados do nosso arquivo XML.

0 comentários:

quarta-feira, 31 de outubro de 2012

Como Ordenar uma Lista de Objetos (TObjectList)

Ordenação  de TObjectList

Muitas vezes utilizamos listas de objetos (TObjectList) para agrupar clientes, contatos, produtos, etc.
Pode ser que os dados sejam adicionados a lista sem uma ordenação lógica, ordenação esta que pode vir a ser necessária.
A classe TObjectList possui o método Sort que possui a seguinte assinatura:

procedure Sort(Compare: TListSortCompare);

O parâmetro Compare é do tipo TListSortCompare que deve ser uma função com a seguinte assinatura

TListSortCompare = function (Item1, Item2: Pointer): Integer;

Como vocês podem ver, para ordenar a lista será necessário criar uma função de ordenação utilizando a regra que desejarmos.

Exemplo de função de ordenação

Para exemplificar vou criar uma classe Item, uma lista de Itens(TItemList) e duas funções de ordenação.


type
  TItem = class(TObject)
  private
    FName: string;
    FID: Integer;
    procedure SetID(const Value: Integer);
    procedure SetName(const Value: string);
  public
    property ID   : Integer read FID write SetID;
    property Name : string read FName write SetName;
  end;

  TItemList = class(TObjectList)
  public
    function Add(AObject: TItem): Integer;
  end;

function SortAscending(Item1, Item2: Pointer): Integer;
var Obj1 : TItem;
    Obj2 : TItem;
begin
  Obj1 := TItem(Item1);
  Obj2 := TItem(Item2);
  if Obj1.ID > Obj2.ID then
    Result := +1
  else
    if Obj1.ID < Obj2.ID then
      Result := -1
    else
      Result := 0;
end;

function SortDescending (Item1, Item2: Pointer): Integer;
var Obj1 : TItem;
    Obj2 : TItem;
begin
  Obj1 := TItem(Item1);
  Obj2 := TItem(Item2);
  if Obj1.ID > Obj2.ID then
    Result := -1
  else
    if Obj1.ID < Obj2.ID then
      Result := +1
    else
      Result := 0;
end;

Agora um exemplo de utilização das classes e funções. Será utilizado um laço para gerar aleatoriamente 10 ID diferentes para preencher um componente Memo na ordem de geração e depois em Ordem Crescente e Decrescente.

var Item : TItem;
    List : TItemList;
    idx  : Integer;
    ID   : Integer;
begin
  Memo1.Lines.Clear;
  Memo1.Lines.Add('Ordem de Geração');
  List := TItemList.Create;
  for idx := 1 to 10 do
  begin
    ID := Random(99) + 1;
    Item := TItem.Create;
    Item.ID := ID;
    Item.Name := Format('Item%.3d', [ID]);
    List.Add(Item);
    Memo1.Lines.Add(Format('ID=%.3d', [Item.ID]));
  end;

  Memo1.Lines.Add('=====');
  Memo1.Lines.Add('Ordem Ascendente');
  List.Sort(SortAscending);
  for idx := 0 to List.Count -1 do
  begin
    Item := List[idx] AS TItem;
    Memo1.Lines.Add(Format('ID=%.3d', [Item.ID]));
  end;

  Memo1.Lines.Add('=====');
  Memo1.Lines.Add('Ordem Descendente');
  List.Sort(SortDescending);
  for idx := 0 to List.Count -1 do
  begin
    Item := List[idx] AS TItem;
    Memo1.Lines.Add(Format('ID=%.3d', [Item.ID]));
  end;
end;


Este código irá gerar uma saída semelhante a esta:
Ordem de Geração
ID=063
ID=090
ID=078
ID=009
ID=067
ID=026
ID=045
ID=083
ID=027
ID=073
=====
Ordem Ascendente
ID=009
ID=026
ID=027
ID=045
ID=063
ID=067
ID=073
ID=078
ID=083
ID=090
=====
Ordem Descendente
ID=090
ID=083
ID=078
ID=073
ID=067
ID=063
ID=045
ID=027
ID=026
ID=009

Como vocês viram é simples gerar a função de ordenação, seria possível ordenar por data, nome ou qualquer outra propriedade presente nos Objetos da Lista. Até a próxima :D

0 comentários:

segunda-feira, 29 de outubro de 2012

How to call another application from a service

This is a tip of Delphi, but should be the same in other languages

Say you have the following file structure:

folder
-> serviceapp.exe
-> application.exe

If you want to run the application.exe from a function in serviceapp.exe such as:

WinExec (PChar ('application.exe'), SW_MINIMIZE);

This code will not work even both being in the same folder as the service does not run from the directory where the file serviceapp.exe is.

To work you need the following:

ChDir (ExtractFilePath (Application.ExeName));
WinExec (PChar ('application.exe'), SW_MINIMIZE);

The procedure ChDir () change the current directory where the process is active.
Another option is:

WinExec (PChar (ExtractFilePath (Application.ExeName) + 'application.exe'), SW_MINIMIZE);

This way you will run the application.exe file using the full path to the executable.
But in this case the  application.exe still running from another folder, then the option Chdir () is better.

Until next tip: D

0 comentários:

Como chamar programa a partir de um serviço

Esta é uma dica de Delphi, mas deve ser o mesmo em outras linguagens
Digamos que você possua a seguinte estrutura de arquivos:

pasta
-->serviço.exe
-->arquivo.exe

Se você quiser executar o arquivo.exe a partir de uma função de serviço.exe como por exemplo:

WinExec(PChar('arquivo.exe'), SW_MINIMIZE);

Este código não irá funcionar mesmo ambos estando na mesma pasta, pois o serviço não executa do diretório onde está o arquivo serviço.exe.

Para funcionar é necessário o seguinte procedimento:

ChDir(ExtractFilePath(Application.ExeName));
WinExec(PChar('arquivo.exe'), SW_MINIMIZE);

A procedure ChDir() serve para mudar o diretório atual onde o processo está ativo.
Outra opção é:

WinExec(PChar(ExtractFilePath(Application.ExeName) + 'arquivo.exe'), SW_MINIMIZE);

Desta maneira é executado o programa arquivo.exe utilizado o caminho completo do executável.
Mas neste caso arquivo.exe ainda é executado em outra pasta e não onde este se encontra, então a opção Chdir() ainda é mais recomendada.
Até a próxima dica :D

0 comentários:

Debugando no Delphi

Este post é sobre alguns macetes do Debugger do Delphi que ajudam muito na hora de encontrar um erro ou mesmo corrigi-lo.

Erro de Acesso a Memória.


Esse tipo de erro é muito chato.
Primeiramente mostra uma mensagem muito assustadora para o usuário leigo.
Para o desenvolvedor a mensagem não permite saber o que ocasionou o erro.
Felizmente o Delphi permite encontrar a causa do erro com facilidade.
Basta acessar o menu Search -> Find Error.
Na caixa de diálogo que irá aparecer basta digitar o endereço que apareceu quando ocorreu o erro de acesso a memória. Neste exemplo: 0044E292 e clicar no botão OK e o Delphi irá para a linha onde o erro foi gerado.

Evaluate/Modify
Esta opção ajuda muito na hora de descobrir a causa de algum erro ou mesmo alterar o valor de uma variável durante a execução do programa.
Quando a execução do programa estiver parada, por exemplo, definindo um breakpoint.
Acesse o menu Run -> Evaluate/Modify. Este comando irá exibir a seguinte caixa de diálogo
.


Na caixa de edição Expression você pode digitar uma expressão. Por exemplo, supondo que você tenha uma variável linha do tipo string que contém uma linha lida de um arquivo texto e deseja saber o tamanho desta linha. Digite length(linha) e clique em Evaluate. O resultado aparecerá no campo Result.
Agora digamos que você deseja alterar o valor contido nesta variável linha. No campo Expression digite linha e clique em Evaluate. No campo Result aparecerá o valor contido na variável. Agora na caixa de edição New Value digite o novo valor da variável e clique em Modify. Muito útil quando, por exemplo, você descobre a causa daquele laço infinito e deseja continuar testando o programa. Basta alterar o resultado do teste feito no laço e continuar executando o programa normalmente.

0 comentários:

Blogger Template by Clairvo