Cesar Romero

Delphi programming

Blaise Pascal Magazine - Edição Especial + 1 ano de Assinatura Grátis

A  Blaise Pascal magazine publicou uma edição especial e gratuíta da revista cobrindo todos os produtos da Embarcadeiro, CodeGear e DatabaseGear.

Mas a grande novidade é que a revista também está disponível para download na área de download de usuários registrados do Delphi 2009, mas baixando do site da CodeGear você ainda ganha 1 ano de assinatura da revista, eu já baixei a minha.

Aproveite pra ver outros brindes disponíveis na área de download, como os componentes da TMS  TMS Smooth Controls, além de outros downloads e atualizações.

Delphi 2009 Update 3 e Update 4 anunciados

Nick Hodges anunciou hoje os Updates 3 e 4 para Delphi 2009  e C++ 2009 .

Atualizações

    • Update 3: IDE, VCL e outras atualizações gerais
    • Update 4: Database

    O download está disponível na página da CodeGear para usuários registrados.

    Links

    Acelerando TCustomSQLDataSet.ExecSQL no Delphi 2007

    O TCustomSQLDataSet.ExecSQL tem um bug no Delphi 2007, que ignora quando uma Query já está preparada. A cada vez que o método é executado, ele refaz todo o processo, tornando as chamadas consecutivas do ExecSQL lentas por não aproveitar o “Prepare”. Este problema está reportado no QC 56985 e foi corrigido no Delphi 2009.

    Se você usa o Delphi 2007, a dica de como resolver este problema foi postada no fórum da CodeGear:

    • Crie uma cópia da unit SqlExpr.pas no diretório do seu projeto
    • Copie o código de TCustomSQLDataSet.ExecSQL do Delphi 2009 para a cópia do SqlExpr.pas, substituindo o código original
    • Adicione a unit SqlExpr.pas ao seu projeto.

    Melhorando o visual do TPanel no modo Dock

    O Delphi suporta Dock de TPanel nativamente através do DockManager, mas o visual padrão não é dos melhores. Isto por que, ele foi implementado de modo que fosse possível personalizar, apenas criando novas classes a partir de TDockTree.

    A VCL implementa a classe TCaptionedDockTree que parece ser utilizada pela própria IDE do Delphi, basta definir a variável global DefaultDockTreeClass para a classe que deseja que seja utilizada no gerenciamento do Dock.

    Na sua aplicação basta adicionar a unit CaptionedDockTree na uses do seu formulário, que se encarregará de melhorar o visual e comportamento do Dock na sua aplicação.

    Veja como fica o header do Panel Dockado no Xananews:

    Antes

    Depois

    Resolvendo associação de arquivos do Excel

    Ontem precisei resolver este problema em um cliente. Removi o Office, limpei o registro do Windows, reinstalei e nada.

    Após pesquisar um pouco, encontrei a solução:

    1. No Excel em Ferramentas | Opções | Geral
      Desmarque a opção “Ignorar aplicativos Externos”.
    2. Execute o shell do windows cmd.exe e digite os comandos:
      “C:\Arquivos de Programas\Microsoft Office\…\Excel.exe” /regserver 
      “C:\Arquivos de Programas\Microsoft Office\…\Excel.exe” /unregserver 

    Note que ”C:\Arquivos de Programas\Microsoft Office\…\Excel.exe” é o caminho completo para o Excel, você pode digitar apenas Excel /regserver, se estiver na pasta do Excel, ou se ele estiver acessivel pelo %PATH.

    O Excel possui várias opções de inicialização, você pode ver uma lista completa destas opções no site de suporte da Microsoft Descrição da inicialização alterna para o Excel.

    Não pesquisei como outros aplicativos do MS Office se comportam neste caso, mas deve ser o mesmo processo.

    WordPress XML-RPC Com Delphi e Indy 10

    O WordPress suporta comunicação remota, atravéz de XML-RPC, ontem ajudei um amigo a criar um aplicativo simples em Delphi, para postar e fazer upload de arquivos com Delphi e Indy 10.

    A minha primeira tentativa foi utilizando o RemObjects, mas ele apresentou alguns bugs, eu corrigi os fontes do RemObjects e consegui fazer a chamada, mas analisando a necessidade, vi que poderia ser feito de forma mais simples, utilizando apenas o Indy e escrevendo alguns poucos métodos.

    Já comecei a escrever um exemplo de como implementar usando o Jazz SDK, a nova versão que está no forno, será um exemplo que acompanhará os fontes, mas por enquanto vou escrever as dicas de como fazer o upload de arquivos, que servirá como base para todas as funções do WordPress descritas na página Codex XML-RPC wp.

    Método remoto para enviar um arquivo: wp.uploadFile

    Parâmetros:

    • int blog_id
    • string username
    • string password
    • struct data
      • string name
      • string type
      • base64 bits
      • bool overwrite

    Resultado:

    • struct 
      • string file
      • string url
      • string  type

    Onde:
    Primeiro o tipo correspondente e segundo o nome do campo.

    Struct se refere a estrutura de um Objeto em Delphi.

    O primeiro passo é montar a requisição, a requisição pode ser montada utilizando TXMLDocument, ou outro gerador de XML Nodes. O formato do XML é o padrão definido para qualquer comunicação XML-RPC, este aqui é o modelo de um XML para a chamada de envio de um arquivo:

    
    <methodCall>
      <methodName>wp.uploadFile</methodName>
      <params>
        <param>
          <value>
            <int>[blog_id value]</int>
          </value>
        </param>
        <param>
          <value>
            <string>[username value]</string>
          </value>
        </param>
        <param>
          <value>
            <string>[password value]</string>
          </value>
        </param>
        <struct>
          <member>
            <name>name</name>
            <value><string>[name filename.ext value]</string></value>
          </member>
          <member>
            <name>type</name>
            <value><string>[type mime datatype]</string></value>
          </member>
          <member>
            <name>bits</name>
            <value><base64>[bits file content]</base64></value>
          </member>
          <member>
            <name>override</name>
            <value><bool>[override value]</bool></value>
          </member>
         </struct>
      </params>
    </methodCall>
    

    As chaves “[" e "]” e a descrição entre elas, devem ser substituídos pelos valores dos conteúdos correspondentes, descritos em Parâmetros acima.

    O blog_id, deve ser recuperado com a chamada remota do método “wp.getUsersBlogs“, a seguir login e senha do usuário, e o struct do arquivo a ser enviado.

    Onde name é o nome do arquivo, com extensão, a extensão é importante pois o WordPress validará se o tipo do arquivo é aceito, pela extensão.

    type é a descrição de tipo mime, de acordo com os tipos aceitos, descritos na página Using Attachments

    bits é o conteúdo do arquivo, codificado no padrão “Encode 64″,  e por fim o override, indica se um arquivo com o mesmo nome deve ou não ser sobrescrito.

    O código em Delphi com Indy para enviar o arquivo fica assim:

    
    procedure WPUploadFile(const FileName: string);
    var
      TargetURL: string;
      DataFile, EncodedData, Request, Response: TMemoryStream;
    begin
      TargetURL:= 'http://www.url_do_blog.com.br/xmlrpc.php';
      DataFile:= TMemoryStream.Create;
      Request:= TMemoryStream.Create;
      Response:= TMemoryStream.Create;
      EncodedData:= TMemoryStream.Create;
      DataFile.LoadFromFile(FileName);
      DataFile.Position := 0;
      try
        EncodeStream(DataFile, EncodedData);
        PrepareRequestXML(Request, EncodedData);
    
        IdHTTTP1.IOHandler:= IdIOHandlerStack1;
        IdHTTTP1.Post(TargetURL, Request, Response);
    
        Response.Position:= 0;
        MemoResponse.Lines.LoadFromStream(Response);
      finally
        Request.Free;
        Response.Free;
        DataFile.Free;
        EncodedData.Free;
      end;
    end;
    

    O método EncodeStream, está na unit EncdDecd. 

    O método PrepareRequestXML, é um método que escrevi para montar o XML Request, de acordo com o código XML acima.

    Os componentes do Indy utilizados foram TIdHTTP e TIdIOHandlerStack, e todo o código da chamada é composto apenas de 2 linhas, o restante é apenas para chamar o código que monta o XML da requisição e receber o resultado, que será mostrado num memo chamado MemoResponse. O correto agora seria cria um objeto, com as propriedades retornadas, que são:

    • file nome do arquivo salvo no servidor
    • url url para acessar a imagem diretamente
    • type tipo do arquivo

    Em breve publicarei um exemplo de como criar postar no WordPress com Delphi, utilizando objetos feitos com o Jazz SDK.

    Simulando KeyPress com PostKeyEx32.

    Esta  semana eu resolvi adicionar a simulação de KeyPress em um aplicativo, precisava simular o “CTRL + F10″ e enviar uma mensagem WM_HOTKEY.

    Para minha surpresa, não era uma tarefa tão simples de codificar, e depois de várias tentativas, consegui enviar o “CTRL + F10″, só que outro aplicativo que tinham registrado F10 também era executado, alterei os parametros e ai o diálogo executar do windows também era executado, e a tecla de atalho para ele é “Tecla Windows + R”, que não tem nada a ver com o “CTRL + F10″, que eu estava enviando.

    Postei a dúvida no Stackoverflow, mas logo em seguida encontrei a solução definitiva, a função PostKeyEx32, a qual vou adicionar neste artigo por que é pequena, e também vou explicar como utilizar.

    
    procedure PostKeyEx32(key: Word; const shift: TShiftState;
      specialkey: Boolean);
    type
      TShiftKeyInfo = record
        shift: Byte;
        vkey: Byte;
      end;
      byteset = set of 0..7;
    const
      shiftkeys: array [1..3] of TShiftKeyInfo =
        ((shift: Ord(ssCtrl); vkey: VK_CONTROL),
        (shift: Ord(ssShift); vkey: VK_SHIFT),
        (shift: Ord(ssAlt); vkey: VK_MENU));
    var
      flag: DWORD;
      bShift: ByteSet absolute shift;
      i: Integer;
    begin
      for i := 1 to 3 do
      begin
        if shiftkeys[i].shift in bShift then
          keybd_event(shiftkeys[i].vkey,
            MapVirtualKey(shiftkeys[i].vkey, 0), 0, 0);
      end; { For }
      if specialkey then
        flag := KEYEVENTF_EXTENDEDKEY
      else
        flag := 0;
      keybd_event(key, MapvirtualKey(key, 0), flag, 0);
      flag := flag or KEYEVENTF_KEYUP;
      keybd_event(key, MapvirtualKey(key, 0), flag, 0);
      for i := 3 downto 1 do
      begin
        if shiftkeys[i].shift in bShift then
          keybd_event(shiftkeys[i].vkey,
            MapVirtualKey(shiftkeys[i].vkey, 0), KEYEVENTF_KEYUP, 0);
      end; { For }
    end; { PostKeyEx32 }
    

    Utilizando a função PostKey32

    Parâmetros

    Key: Código virtual das teclas a simular. Para caracteres imprimíveis utilize o código ansi, (Ord(Caracter)).

    Shift: Estado das teclas modificadoras. É um conjunto para que se possa passar mais de uma tecla (Shift, Control, Alt, Botões do Mouse). TShiftState é declarado na unit Classes.

    SpecialKey: Normalmente deve ser Falso. Defina como Verdadeiro para especificar uma tecla no teclado númerico, por exemplo.

    Descrição

    PostKeyEx32 utiliza keybd_evet para criar uma série de eventos de teclas que combinem com os parâmetros passados. Os eventos serão enviados para o componente/controle em que esteja com o foco.

    Para teclas de caracteres, utilize sempre a versão em maiúsculo. Enviando sem nenhum modificador, o resultado será sempre um caracter minúsculo, enviando com [ssShift] o resultado será maiúsculo.

    Utilizando PostKeyEx32, o código para simular “CTRL + F10″ ficou bem simples

    
      PostKeyEx32(VK_F10, [ssCtrl], False);
    

    Blog do Jazz SDK

    Ontem voltei a atualizar o conteúdo do blog do Jazz SDK, o conteúdo publicado será em inglês, voltado para o público internacional que utiliza o Jazz, sempre que publicar um texto lá, provavelmente estarei publicando a versão em Português aqui.

    Delphi Sets, código legivel e bom desempenho

    Hoje enquanto modelava e implementava Notificação e Estado dos objetos no Jazz, tive a preocupação com a memória utilizada e com o desempenho.  Na versão anterior eu utilizava Sets, mas a notificação e o status necessitavam melhorias.

    Então me ocorreu a idéia de utilizar bit para identificar o Estado, desta forma, um byte seria suficiente para identificar todos os possíveis Estados de um objeto, foi então que postei no stackoverflow uma pergunta sobre como manipular bit “How use bit/bit-operator to control object state?”.  

    A pergunta foi respondida pelo Scott W que ainda deu a dica da pagina sobre Delphi Operators. Outros colegas também responderam sugerindo a utilização de Sets, e entre eles o Engenheiro do Compilador do Delphi Barry Kelly, que ainda explicou como o compilador do Delphi gera assembly para Sets. 

    Informações sobre Sets segundo Barry Kelly:

    Utilizar Sets é a melhor técnica que utilizar operadores de bit. Eles não são mais leves, visto que Sets são compilados com o mesmo código de CPU que operações binárias. 

    A vantagem é que eles são mais seguros por que são verificados pelo compilador, enquanto operadores de bit são todos inteiros.

    Neste caso como terei no máximo 8 itens, eles serão de tamanho máximo de 1 byte

    A versão final utilizando Sets ficou assim,

    Declaração dos possíveis estados:

    
      TStateType = (
        stLoaded    = 0,   // loaded from persistance
        stNative    = 1,   // value loaded and converted to native type
        stSaved     = 2,   // saved
        stChanged   = 3,   // object or member changed
        stDelete    = 4,   // marked to delete
        stNull      = 5    // value is null
      );
    
      TState = Set of TStateType;
    

    Você sabia que é possível definir o valor numérico de um item em Sets?

    Armazenamento das informações:

    
      PDataPackage = ^TDataPackage;
      TDataPackage = record
        Data: TBytes;
        TypeInfo: TMetaInfo;
        State: Byte;
        Instance: TBuffer;
      end;
    

    Estas são as informações enviadas entre cliente e servidor de aplicações para persistência e recuperação dos dados,

    • Data contém os dados em Bytes;
    • TypeInfo será convertido a apenas o nome da classe de implementação dos Metadados;
    • State é apenas 1 Byte, contendo os possíveis valores de TState;
    • Instance será ignorada, pois apenas representa a instância única no cliente ou no servidor, e será utilizada para notificação.

    E para acessar as informações:

    
      TValueType = class(TJazzObject, IValueType, IDataPackage)
      private
        FDataPackage: PDataPackage;
      ...
      end;
    
    function TValueType.IsNull: Boolean;
    begin
      Result:= stNull in TState(FDataPackage^.State);
    end;
    

    Como persistir TState

    
    var
      State: TState;
    begin
      State:= [stChanged];
      FDataPackage^.State:= Byte(State);
    end;
    

    Como TState tem menos de 8 ítens, pode ser persistido utilizando apenas 1 byte.

    Delphi Prism Roadmap

    Nick Hodges anunciou o novo Roadmap do Delphi Prism, se você está usando ou pensa em usar o Delphi Prism para desenvolver para .NET, vale a pena a leitura. Há melhorias planejadas para todas as áreas, destaque para as melhorias planejadas para DataSnap, mais drivers dbExpress, melhorias na linguagem, suporte a .NET 4.0, AOP, Entity Framework support, LINQ Support for Blackfish, melhoria no suporte para Mono.

    Refências