Analitcs

Pesquisar no conteúdo do blog.atlabs.com.br

quinta-feira, 26 de novembro de 2015

DELPHI - Testar um arquivo JPG e BMP

Reações: 
// Uses Jpeg, Graphics  (testado em delphi6 - para versões mais novas consultar a unit correspondente)
procedure TForm1.Button1Click(Sender: TObject);
var
  B : TBitmap;
  J : TJPEGImage;
  F : Boolean;
begin
// Testa o arquivo bmp e o jpg mesmo se a extensão estiver alterada
  try
    FreeAndNil(J);
  except
  end;
  Image1.Picture.Assign(nil);
  if OpenPictureDialog1.Execute then
  begin
    B := TBitmap.Create;
    F := False;
    try
      try
      Label1.Caption := 'Imagem BitMap';
      B.LoadFromFile(OpenPictureDialog1.FileName);
      except
        Label1.Caption := 'Não é BitMap';
        F := True;
        Application.ProcessMessages;        
        Sleep(2000);
      end;
      if F then
      begin
        J := TJPEGImage.Create;
        try
          J.LoadFromFile(OpenPictureDialog1.FileName);
          B.Assign(J);
          Label1.Caption := 'Imagem JPG';
        except
          Label1.Caption := 'Não é JPG';
        end;
      end;
      if Assigned(B) then
        Image1.Picture.Assign(B)

    Finally
      FreeAndNil(B);
      if Assigned(J) then
        FreeAndNil(J);
    end;
  end;
end;

quarta-feira, 18 de novembro de 2015

DELPHI - Conectando a um Web Service

Reações: 
Retirado de:
http://www.comunix.net/integracao/delphi1.htm

Url de Testes:
http://suporte.comunix.net/webservices/servicos/transacoes.asmx?WSDL

Delphi usando componente SOAP
Este exemplo pode ser usado tanto em Delphi 6 quanto em Delphi 7. Será demonstrado dois métodos de fazer a chamada ao Web services, uma usando o componente HTTPRIO e fazendo um Typecast e outros usando apenas a Unit que será criada automaticamente.
Crie um novo projeto, adicione dois Tbutton, um Tedits, um TMemo e um HTTPRIO da palheta Webservices.

Importar o WSDL direto do site para conhecer os serviços disponíveis. Utilizando o menu File | New | Other. Na Guia WebServices selecione a opção WSDL Importer.

Uma tela Wizard será aberta solicitando o endereço do WSDL.
Endereço de teste
Digitar http://suporte.comunix.net/webservices/servicos/transacoes.asmx?WSDL e clicar em Next.

Será exibido o código gerado. Clicar em Finish e salvar arquivo gerado com o nome de transacoes.pas.

Inserir no final do arquivo transacoes.pas a linha que esta em vermelho caso ela não exista.
initialization
  InvRegistry.RegisterInterface(TypeInfo(WebServiceSoap), 'http://suporte.comunix.net/webservices/servicos/transacoes.asmx/', 'utf-8');
  InvRegistry.RegisterDefaultSOAPAction(TypeInfo(WebServiceSoap), 'http://suporte.comunix.net/webservices/servicos/ConsultarSaldo0907');
  InvRegistry.RegisterInvokeOptions(TypeInfo(ServicosSoap), [ioDefault, ioDocument, ioHasReturnParamNames, ioHasNamespace]);
end.
Em seu formulário adicione a unit transacoes.pas que acabou de ser criada utilizando o menu File | Use Unit.
Configure no Object Inspector as propriedades do HTTPRIO1 escolhendo as opções na ordem WSDLLocation, Service e Port.

No evento OnClick do Button1 colocar o seguinte código:
procedure TForm1.btnValidarCartaoClick(Sender: TObject);
var
CamposValidacao:RetornoValidacaoCartao;
begin
  CamposValidacao := (HTTPRIO As ServicosSoap).ValidacaoCartao0108(000,0000000,00000001,00000000),'1234567890',Cartão com 16 digitos);

if CamposValidacao.CodigoRetorno = 0 then
begin

edit1.Text := CamposValidacao.NomeEmpresa;

edit2.text := CamposValidacao.NomeAssociado;
{e assim para todos os campos de retorno}
end
else
edit3.text := CamposValidacao.Mensagem
end;

Exemplo de como enviar uma venda com produtos, caso a venda não tenha produtos o array tem que ser enviando zerado, e a quantidade de produtos também.

procedure TFPrincipal.VenderClick(Sender: TObject);
var
NSU_Guest: string;
ValorVenda: Real;
nK:Integer;
CamposVenda:RetornoDaVenda;
CamposProdutos:ArrayOfCamposEspelhoCupom;
begin
{gerando NSU para a venda}
NSU_Guest := FormatDateTime('DD',Now) + FormatDateTime('HHMM',Now);
ValorVenda := Valor_Autorizar.Value;
{setando o tamanho do vetor com a quantidade de produtos}
SetLength(CamposProdutos,StrToInt(Edit1.Text));
{Adicionado os produtos no vetor}
for nK := 0 to Length(CamposProdutos) - 1 do
begin
CamposProdutos[nK] := CamposEspelhoCupom.Create;
CamposProdutos[nK].CodigoDeBarras := '1234567890123456';
CamposProdutos[nK].Quantidade := 1;
CamposProdutos[nK].ValorVendaComDesconto := 900;
CamposProdutos[nK].ValorVendaSemDesconto := 1000;
CamposProdutos[nK].DescricaoDoProduto := 'DELPHI 7';
CamposProdutos[nK].DataDaReceita := '03122011';
CamposProdutos[nK].NumeroDareceita := '1234567890';
CamposProdutos[nK].TipoDoDocumento := '12345678';
CamposProdutos[nK].NumeroDoDocumento := '87654321';
CamposProdutos[nK].NomeDoPrescritor := 'COMUNIX SOFTWARE';
end;
{enviando a venda}
CamposVenda := (HTTPRIO As ServicosSoap).Vender0308(ConfCODIGOOPERADORA.AsInteger,ConfCODIGOESTABELECIMENTO.AsInteger,ConfTERMINAL.AsString,ConfCODIGOINTEGRADOR.AsString,ConfCHAVEDIARIA.AsString,NSU_Guest,textCartao.Text, TiposVendasCODIGO.AsInteger,ValorVenda,Parcelas.AsInteger,Cupom.Text,0,000000,Length(CamposProdutos),0,CamposProdutos);
{Verificando se a venda foi realizada com sucesso}
if CamposVenda.CodigoRetorno = 0 then
begin
Autorizacao.Text := CamposVenda.NumeroDaAutorizacao;
(HTTPRIO As ServicosSoap).ConfirmacaoDeTransacao3501(ConfCODIGOOPERADORA.AsInteger,ConfCODIGOESTABELECIMENTO.AsInteger,ConfTERMINAL.AsString,ConfCODIGOINTEGRADOR.AsString,ConfCHAVEDIARIA.AsString,01,CamposVenda.NumeroDaAutorizacao);
end
else
begin
ShowMessage(CamposVenda.Mensagem);
end;
end;

quinta-feira, 12 de novembro de 2015

WINDOWS - Windows Service Monitor - Monitoração de serviço

Reações: 
Para monitorar serviços

DELPHI - Remote Data Module - Comunicação entre ClientDataSet em Data Modulo Remoto

Reações: 
Retirado de:
http://www.delphigroups.info/2/c8/468842.html

Comunicação entre ClientDataSet em Data Modulo Remoto


There are three different avenues to accomplish this: 
1. If it is a parameterized query, you can use the 
   IProvider.SetParams call.  Assuming you have 2 parameters 
   (Param1 and Param2).  The following code fragment 
   demonstrates matching by index, Value1 goes to the first 
   parameter, etc... 
ClientDataSet1.Provider.SetParams(VarArrayOf(Value1, Value2)); 
Or matching by param name: 
var 
  V: Variant; 
  ParamCount: Integer; //used for ease of reading 
begin 
  ClientDataSet1.Close; 
  ParamCount := 2; 
  V := VarArrayCreate([0, ParamCount - 1], varVariant); 
  V[0] := VarArrayOf(['Param1',Value1]); 
  V[1] := VarArrayOf(['Param2',Value2]); 
  ClientDataSet1.Provider.SetParams(V); 
  ClientDataSet1.Open; 
end; 
For more example code see \demos\midas\setparam. 
2. If you want to change the SQL, then you can use the 
   IProvider.DataRequest method. 
On the Client; 
CDS.Data := CDS.Provider.DataRequest('select * from customer'); 
On the server, you must use a TProvider object, and assign 
the OnDataRequest event; 
function TForm1.Provider1DataRequest(Sender: TObject; 
  Input: OleVariant): OleVariant; 
begin 
  //assumes DataSet is a TQuery. 
  Provider1.DataSet.Close; 
  Provider1.DataSet.SQL.Text := Input; 
  Provider1.DataSet.Open; 
  Result := Provider1.Data; 
end; 
For more example code see \demos\midas\adhoc. 
3. Create you own interface function that executes the SQL 
   statement. 
In the RemoteDataModule: 
a. Edit | Add To Interface  "procedure ExecSQL(SQL: 
   WideString);"   This will add a procedure to your 
   interface. 
b. On the server, code the new procedure: 
procedure RemoteData.ExecSQL(SQL: WideString); 
begin 
  { Query1 is kept in the RemoteDatamodule for this purpose} 
  Query1.SQL.Text := SQL; 
  Query1.ExecSQL; 
end; 
c. On the client, call the new procedure: 
RemoteServer1.AppServer.ExecSQL('Delete from deal details 
where dealnumber=1'); 

segunda-feira, 9 de novembro de 2015

DELPHI - Ponteiros e alocação dinâmica

Reações: 

Retirado de: http://blog.joaomorais.com.br/2008/08/23/ponteiros.html

Ponteiros e alocação dinâmica


Tem um ditado que diz: Eu não sei, mas tenho o telefone de quem sabe. Trabalhar com ponteiros é muito parecido com isto, mas o ditado fica assim: Eu não sei, mas tenho o endereço de quem sabe.
Alguns tipos de variáveis são chamadas de Ponteiro porque elas apontam para algum endereço de memória. Isto aparentemente complica a vida do programador, pois além de tratar da informação é necessário tratar também do endereço da informação. E não é só isto: basta uma variável ponteiro fazendo referência a uma área que não lhe diz respeito, e na melhor das hipóteses a aplicação emitirá uma Violação de acesso à memória. O lado bom é que sistemas operacionais modernos (para não dizer decentes) seguram o tranco e não deixam você destruir outras aplicações ou ele próprio. Nos tempos do DOS era muito comum ter que recorrer ao gabinete e disparar um reset via hardware.
Os novos tipos de dados do Object Pascal visam transformar ponteiros em algo mais simples, mais fácil de usar, ainda mais útil, e por vezes são tratados de forma tão transparente que muitas pessoas passam anos trabalhando com eles sem saber. Quer um bom exemplo? Ansi string (a string padrão do compilador Delphi, do FPC em modo delphi ou com a diretiva $H habilitada) é um ponteiro para string que é alocada e desalocada sozinha pelo compilador.
Segue alguns conceitos sobre o tema.
VARIÁVEIS ESTÁTICAS
São as variáveis da forma tradicional, que guardam a própria informação, e o compilador faz o tratamento de onde esta informação será guardada (pode ser um registrador do processador ou parte da pilha de chamadas). Não há preocupação com alocação nem liberação deste espaço por parte do programador.
var
  A: Longint;
  { A é uma variável do tipo Longint, ocupará 4 bytes, e a alocação deste espaço é tratada pelo compilador }
ALOCAÇÃO DINÂMICA
Entende-se por alocação dinâmica a criação e destruição de espaço na memória, em tempo de execução, para armazenamento e manipulação de informação. É de responsabilidade do programador desalocar toda memória que vier a alocar durante a execução do seu aplicativo, a menos que o próprio compilador faça isto. Também é dever do programador saber quando o compilador fará isto 😉 .
PONTEIROS
Entende-se por ponteiros os tipos de variáveis que apontam para uma área da memória. Ponteiros podem apontar para:
  • Áreas com informação, tal como uma variável;
  • Uma rotina (procedure, function ou método);
  • Um endereço nulo.
Ponteiros – Áreas com informação
O ponteiro pode ser declarado como:
  • tipado – ele sabe qual o tipo de informação para o qual está apontando.
  • não tipado – ele não sabe para que tipo de dado está apontando. É necessário fazer um typecast para recuperar a informação. Typecast será abordado adiante.
O operador @ (arroba) pode ser usado para atribuir o endereço de uma variável para um ponteiro. Ex.:
  A := @B;
    { A recebe o endereço da variável B }
Ou ainda, um ponteiro pode receber o endereço de uma área de memória alocada especialmente para ele:
  { A - aponta para uma variável do tipo Longint }
  new(A);
    { É alocada uma área na memória, com um total de 4 bytes, e A está apontando para esta nova área }
Neste último caso o programador será responsável por esta área alocada, e deverá desalocar antes de encerrar a execução do seu programa. No primeiro caso isto não é necessário, e sequer deverá ser feito, pois o endereço de memória pertence à variável B que é de responsabilidade do compilador.
Ponteiros – Uma rotina
É possível criar ponteiros especialmente preparados para receber o endereço de uma rotina. Neste caso, um exemplo fala mais sobre a sua utilidade: na programação por eventos, o disparo de um click em um botão gera um evento que deve ser interpretado por uma rotina. Uma variável OnClick possui o endereço da rotina que fará o tratamento deste evento.
Ponteiros – Um endereço nulo
No Pascal é conhecido como nil. Utiliza-se associar um ponteiro à constante nil (A := nil) para que fique claro que este ponteiro não está apontando para informação alguma. Desta forma, torna-se possível a comparação:
if A = nil then
  writeln('Não há informação')
else
  writeln('A está apontando para alguma informação');
DECLARAÇÃO
Declara-se um ponteiro tipado informando o tipo da variável para o qual ele apontará, precedido pelo operador ^ (circunflexo).
var
  A: ^Longint; { A é uma variável ponteiro, e aponta para um Longint }
  B: ^string; { B é uma variável ponteiro e aponta para uma string }
É possível também declarar um ponteiro não tipado, ou seja, que não se sabe exatamente para qual tipo de informação ele irá apontar.
var
  C: Pointer;
  { C é uma variável ponteiro, e pode apontar para qualquer tipo de dado }
Pode-se declarar também um ponteiro à uma procedure ou função.
var
  D: procedure(Arg: Byte);
 
procedure rotina1(Arg: Byte);
begin
  writeln('Rotina 1 recebeu ', Arg);
end;

procedure rotina2(Arg: Byte);
begin
  writeln('Rotina 2 recebeu ', Arg);
end;

begin
  D := @rotina2;
  D(10); { Irá imprimir: 'Rotina 2 recebeu 10' }
end.
RECUPERAÇÃO DOS DADOS
Toda variável ponteiro (inclusive classes) possuem duas formas de se trabalhar – uma é com o endereço para o qual ela aponta, e outra é para a informação que está no respectivo endereço. Exemplo:
var
  A: ^Longint;
  B: Longint;
begin
  { A linha abaixo faz com que A aponte para o endereço de B, é lida assim:
    "A recebe o endereço de B" }
  A := @B;
    { primeira forma - utilizando o endereço para o qual A está apontando }

  { A linha abaixo guarda o valor 5 na área de memória apontada por A, é lida assim:
    "O endereço apontado por A recebe 5" }
  A^ := 5;
    { segunda forma - utilizando a informação apontada por A }

  writeln(B);
end.
Note a diferença no uso da variável. Sem circunflexo, é endereço. Com circunflexo, é a informação apontada por aquele endereço.
TYPECAST
O typecast informa ao compilador o tipo de dado para o qual a variável ponteiro está apontado.
Há situações em que não é possível determinar o tipo exato de um ponteiro em tempo de projeto. Isto é bastante comum em programação orientada a objetos, aonde o ponteiro (a variável de uma determinada classe) pode apontar para uma série de objetos semelhantes, mas não iguais entre si.
Apenas para fins de esclarecimento, segue uma utilização do Typecast. Não é o exemplo mais comum, mas é o mais simples de apresentar, explicar e entender:
var
  A: Pointer;
  B: Longint;
begin
  A := @B;
  B := 10;
  writeln(Longint(A^));
end;
Recordando o exemplo anterior: colocar o circunflexo após a variável ponteiro significa trabalhar com uma variável comum, que em seu conteúdo possui um número, uma string, etc. Isto é possível graças a forma com que o ponteiro é declarado:
var
  A: ^Longint; { Ponteiro para Longint }
begin
  writeln(A^); { Imprime um Longint }
Mas ao criar ponteiros não tipados com o Pointer, o compilador fica sem saber com o que está trabalhando quando o circunflexo é utilizado após a variável.
DESALOCANDO O QUE FOI ALOCADO
Tudo o que foi alocado pelo programador, e que não é controlado pelo compilador, deverá ser desalocado logo que possível.
var
  A: ^Longint;
begin
  New(A); { Aloca uma área na memória para armazenar um Longint }
  A^ := 10; { Coloca o valor 10 nessa nova área da memória }
  Dispose(A); { Desaloca o espaço reservado pela procedure New }
end;
CONCLUSÃO
Estes tópicos abordam tudo o que diz respeito a ponteiros. Conforme colocado, existe mais assunto relacionado devido aos novos tipos de dados do Object Pascal, tal como arrays dinâmicos, classes e interfaces, ansi strings, entre outros. No entanto todos estes tipos trabalham sobre estes conceitos recém abordados, o que muda é a interface do uso e a forma de alocar, acessar e desalocar esta área de memória.

Max Gehringer