Arquivos da categoria : Rad Studio


Restaurar “Welcome Page” do Delphi 1

As vezes a “Welcome Page” do Delphi simplesmente some, no Delphi 2009 isto acontecia o tempo todo, a partir do Delphi 2010 isto melhorou, mas as vezes quando eu fecho algum grupo de projetos o problema ocorre novamente, e podemos ver o “TEmbarcadero.Create” em vermelho no topo.

Para restaurar a página não é necessário reiniciar o Delphi, basta clicar com o botão direito do mouse na “Welcome Page” e em “Modo de Navegação”.

Delphi Welcome Page

Delphi - Restaurar Welcome Page


Delphi 2010 DBX com SQL Server 2008 3

Há alguns dias eu postei o artigo Configurando DBX para acessar o MS SQL Server 2000 e 2005 no Delphi 2010, hoje o Bob Swart postou em seu blog o artigo Delphi/C++Builder 2010 DBX4 and SQL Native Client sobre o mesmo assunto com um complemento explicando a solução para o erro:

“DBX Error: Driver could not be properly initialized. Client library may be missing, not installed properly, or of the wrong version.”

A solução para este erro é bem clara lendo esta mensagem, se você pretende se conectar ao SQL Server 2008, precisa instalar o cliente para 2008.

No site da Microsoft você encontra o download do cliente nativo para SQL Server 2008:


Visão Geral

O Feature Pack é uma coleção de pacotes de instalação autônoma que agregam valor ao SQL Server 2008. Ele inclui as últimas versões de:

  • Componentes redistribuíveis para SQL Server 2008.
  • Provedores complementares para SQL Server 2008.
  • Componentes de compatibilidade com versões anteriores para SQL Server 2008.


Pré-requisitos

Sistemas Operacionais com Suporte:

  • Windows Server 2003 Service Pack 2;
  • Windows Server 2008;
  • Windows Vista Service Pack 1;
  • Windows XP Service Pack 3;
  • Windows 7 Service Pack 1.


Atenção

Se você usar o SQL Server 2008 no Windows 7, você precisa instalar o Service Pack 1, caso contrário você pode encontrar erros de compatibilidade, como problemas de permissão e não ser possível alterar tabelas existentes.


BDE Install para Windows 64bit 53

Postei no Code Central um instalador para o BDE que funciona para Windows 32bit e Windows 64bit.

O link para download é http://cc.embarcadero.com/item/27573.

O crédito pelo instalador é do Edmar Frazão.

Atenção: O BDE foi descontinuado, então ele não terá atualizações. Por exemplo, nunca terá suporte a Unicode.

Você não deve iniciar o desenvolvimento de novas aplicações com BDE. Considere migrar seus sistemas existentes de BDE para dbExpress.

Atualização 20/abril/2010:

Agradeço a colaboração do Anderson Cabrini e do Cristiander.


Como criar um VCL Form sem .dfm? 5

As vezes precisamos criar um Form em tempo de execução, a partir de uma classe especializada de TForm, apenas com métodos, criando os componentes dinamicamente, ex:

type
  TMyForm = class(TForm)
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

E nos deparamos com o erro:

Project MyProject.exe raised exception class EResNotFound with message ‘Resource TMyForm not found’.

Solução:

  • Crie o formulário chamando o método TMyForm.CreateNew().
begin
  FMyForm:= TMyForm.CreateNew(Application);
  FMyForm.AlphaBlend:= True;
  FMyForm.AlphaBlendValue:= AlphaBlendValue;
  FMyForm.FormStyle:= fsStayOnTop;
end;

Atenção:

  • Este formulário não pode criado automaticamente pelo projeto.
  • Não pode ser criado pelos métodos Application.CreateForm() ou TMyForm.Create().

Email com Indy “Socket error 11004″ 2

Sempre tem alguém perguntando a solução para este erro quando vai mandar Email com o Indy, então vou tentar postar a explicação mais simples para que seja possível entender o erro e como resolver.

Socket error 11004 ou WSANO_DATA, significa que a resolução de nome, tradução de www.dominio.com.br para o número IP, foi encontrada no servidor de DNS, mas não retornou nenhum dado. Isto significa que o servidor de nomes (DNS) está incorreto ou está mal configurado.

A solução definitiva é corrigir a configuração do DNS, se você tiver acesso administrativo a ele. Mas se isto não for possível então você pode utilizar o número IP diretamente no lugar do nome. Você pode utilizar o utilitário ping do windows, para descobrir o IP do servidor.


E se eu consultar o IP pela minha aplicação antes e passar para o componente Indy?

Você pode fazer uma chamada a API “GetHostByName”, que é utilizada internamente pelos componentes Indy, e terá o mesmo erro, por que a resolução de nomes é executada pelo mesmo servidor DNS.


Qual é a CPU?

Boa dica para descobrir a CPU em que o programa está rodando:

CPU ID

CPU ID Vendor

Fontes:


type
  TCPUVendor = (cvUnknown, cvAMD, cvCentaur, cvCyrix, cvIntel, cvTransmeta,
    cvNexGen, cvRise, cvUMC, cvNSC, cvSiS);

  TCPUVendorStr = string[12];

const
  CPUVendorStr: array [ Low(TCPUVendor) .. High(TCPUVendor)]
    of TCPUVendorStr = ('', 'AuthenticAMD', 'CentaurHauls',
    'CyrixInstead', 'GenuineIntel', 'GenuineTMx86',
    'NexGendriven', 'RiseRiseRise', 'UMC UMC UMC ', 'Geode by NSC',
    'SiS SiS SiS');

function GetCPUVendorStr: string;
function GetCPUVendor: TCPUVendor;

var
  FormCPUID: TFormCPUID;

implementation

{$R *.dfm}

function GetCPUVendorStr: string;
// Note: this code comes from the FastCode project
// (see http://sourceforge.net/projects/fastcode/)
type
  TRegisters = packed record
    EAX: Cardinal;
    EBX: Cardinal;
    ECX: Cardinal;
    EDX: Cardinal;
  end;

  function IsCPUIDAvailable: boolean; register;
  asm
      PUSHFD                 // Save EFLAGS to stack
      POP     EAX            // Store EFLAGS in EAX
      MOV     EDX, EAX       // Save in EDX for later testing
      XOR     EAX, $200000   // Flip ID bit in EFLAGS
      PUSH    EAX            // Save new EFLAGS value on stack
      POPFD                  // Replace current EFLAGS value
      PUSHFD                 // Get new EFLAGS
      POP     EAX            // Store new EFLAGS in EAX
      XOR     EAX, EDX       // Check if ID bit changed
      JZ      @Exit          // No, CPUID not available
      MOV     EAX, True      // Yes, CPUID is available
      @Exit:
  end;

  procedure GetCPUID(const Param: Cardinal; var Registers: TRegisters);
  asm
     PUSH    EBX                         { save affected registers }
     PUSH    EDI
     MOV     EDI, Registers
     XOR     EBX, EBX                    { clear EBX register      }
     XOR     ECX, ECX                    { clear ECX register      }
     XOR     EDX, EDX                    { clear EDX register      }
     DB $0F, $A2                         { CPUID opcode            }
     MOV     TRegisters(EDI).&EAX, EAX   { save EAX register       }
     MOV     TRegisters(EDI).&EBX, EBX   { save EBX register       }
     MOV     TRegisters(EDI).&ECX, ECX   { save ECX register       }
     MOV     TRegisters(EDI).&EDX, EDX   { save EDX register       }
     POP     EDI                         { restore registers       }
     POP     EBX
  end;

var
  VendorStr: TCPUVendorStr;
  Registers: TRegisters;
begin
  if (IsCPUIDAvailable) then
  begin
    // Call CPUID function 0
    GetCPUID(0, Registers);
    // Get CPU vendor
    SetLength(VendorStr, 12);
    Move(Registers.EBX, VendorStr[1], 4);
    Move(Registers.EDX, VendorStr[5], 4);
    Move(Registers.ECX, VendorStr[9], 4);

    Result:= string(VendorStr);
  end
  else
    Result := 'cvUnknown';
end;

function GetCPUVendor: TCPUVendor;
var
  VendorStr: TCPUVendorStr;
begin
  Result:= cvUnknown;
  VendorStr:= AnsiString(GetCPUVendorStr);
  if VendorStr <> 'cvUnknown' then
  begin
    Result := High(TCPUVendor);
    while ((VendorStr <> CPUVendorStr[Result]) and (Result > Low(TCPUVendor))) do
      Dec(Result);
  end;
end;

procedure TFormCPUID.Button1Click(Sender: TObject);
begin
  Button1.Caption:= GetCPUVendorStr;

  if cvIntel = GetCPUVendor then
    MessageDlg('Genuine Intel!', mtInformation, [mbOK], 0);
end;


Melhorando a aparência de imagens desabilitas no TImageList 4

Uma imagem pode explicar melhor o sentido deste post, veja como a aparência dos botões desabilitados da segunda imagem são melhores que da primeira imagem.

Desabled Images

Para deixar as imagens deste jeito eu usei 2 experts, primeiro o expert IDE Gradient para definir a aparência da barra de ferramentas com ou sem gradiente e o expert Delphi Nice Toolbar para melhorar a aparência das imagens.

Mas que tal se aplicar isto para todos os seus programas, além da IDE do Delphi? Para isto é necessário reimplementar parte do código do TImageList, então eu criei um QC para isto no Quality Central:

Report No: 80997            Status: Reported
Better look for TImageList disabled Images
http://qc.codegear.com/wc/qcmain.aspx?d=80997
QCWIN:Defect_No=80997

Se quer ver esta melhoria implementada por padrão no Delphi, vote neste QC, só clicar no link, fazer login com sua conta do EDN e votar, lembre-se que você pode dar até 10 votos por cada QC, se este QC tiver um bom número de votos, você pode ter esta melhoria na próxima versão do Delphi.

Este QC parece ser bem recebido pela comunidade, alguns grandes programadores conhecidos entraram em contato, um deles foi Anders Melander que até enviou um código que já pode ser utilizado nos nossos programas pra melhorar a aparência das imagens desabilitadas. Já que ele mandou o código para que eu incluísse no QC, não vejo problemas em divulgar aqui.

interface

uses
  ...

//---------------------------------------------------------------
//
//      TImageList work around for disabled glyph state
//
//---------------------------------------------------------------
// Insert this declaration before your form is declared to enable the
// workaround.
// This class can be deleted if TImageList is ever fixed.
//---------------------------------------------------------------
type
  TImageList = class(Controls.TImageList)
  protected
    procedure DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer;
      Style: Cardinal; Enabled: Boolean = True); override;
  end;

implementation

uses
  CommCtrl,
  ...;

procedure TImageList.DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer;
  Style: Cardinal; Enabled: Boolean);
var
  i: integer;
  Glyph, Mask: TBitmap;
begin
  if HandleAllocated then
  begin
    if (Enabled) then
    begin
      inherited;
      exit;
    end;

    Glyph := TBitmap.Create;
    try
      Glyph.SetSize(Width, Height);
      Glyph.PixelFormat := pf32bit;
      Glyph.Transparent := (ColorDepth <> cd32Bit);

      // Clear entire glyph - including alpha
      for i := 0 to Glyph.Height-1 do
        FillChar(Glyph.ScanLine[i]^, Glyph.Width*SizeOf(DWORD), $00);

      // Get glyph from imagelist
      ImageList_Draw(Handle, Index, Glyph.Canvas.Handle, 0, 0,
        ILD_TRANSPARENT);

      // Synthesize the disabled glyph image
      // TODO : Increase contrast of desaturated image.
      Desaturate(Glyph, 255);

      if (ColorDepth = cd32Bit) then
      begin
        // Note: Glyph.AlphaFormat should be done after the image has been
        // desaturated; afDefined premultiplies the RGB.
        Glyph.AlphaFormat := afDefined; 
        // Alpha blended glyph
        // Draw glyph with AlphaBlend() via TBitmap.Draw().
        Canvas.Draw(X, Y, Glyph);
      end else
      begin
        // Masked glyph
        Mask := TBitmap.Create;
        try
          Mask.SetSize(Width, Height);
          Mask.Monochrome := True;
          Mask.Canvas.Brush.Color := clWhite;
          Mask.Canvas.FillRect(Rect(0, 0, Width, Height));
          // Get glyph mask from imagelist
          ImageList_Draw(Handle, Index, Mask.Canvas.Handle, 0, 0, ILD_MASK);

          // Draw glyph masked with MaskBlt
          //
          // MakeROP4($00AA0029, SRCCOPY):
          //   if (Mask = 1) then Dest := Dest
          //   if (Mask = 0) then Dest := SRCCOPY (translate black to
          //     TextColor, white to BkColor)
          // For each white pixel in the mask do nothing ($00AA0029 = NOOP).
          // For each black pixel in the mask draw the glyph.
          // Note: The special handling required by palette target devices
          // has not been implemented.
          MaskBlt(Canvas.Handle, 0, 0, Width, Height,
            Glyph.Canvas.Handle, 0, 0,
            Mask.Handle, 0, 0,
            MakeROP4($00AA0029, SRCCOPY));
        finally
          Mask.Free;
        end;
      end;

    finally
      Glyph.Free;
    end;
  end;
end;

Para utilizar este código, basta colocar na mesma unit do form onde está o componente TImageList. O compilador vai utilizar esta versão de TImageList.DoDraw no lugar da versão original da VCL.

O código do expert Delphi Nice Toolbar também pode ser utilizado para melhorar a aparência da ToolBar nos seus programas, ele usa o método de “patch” em memória, método utilizado pelo Andreas Hausladen no DelphiSpeedUP e no IDE Fix Pack.


TSQLConnection.Params como ConnectionString 2

Pra quem está acostumado a trabalhar com as tecnologias de banco de dados da Microsoft como ADO, sabe que as configurações de conexão de banco de dados são passadas em uma propriedade chamada ConnectionString, uma linha única contendo todos os parâmetros da conexão separados por ponto e vírgula, diferente da propriedade Params do TSQLConnection, que é uma TStringList.
Ontem eu estava reescrevendo umas classes auxiliares para o TSQLConnection, que agora são especialização de uma classe que salva e carrega as configurações da aplicação em um único arquivo XML, onde cada Objeto é um nó do XML, e cada TSQLConnection tem seu nó XML reservado, mas salvar como TStrings, ficava muito estranho no XML, então fiz umas alterações na minha classe para simular a propriedade ConnectionString.

A primeira alteração foi no método SetSQLConnection, onde eu defino 2 propriedades do Params, “StrictDelimiter = True” e “Delimiter:= ‘;’”.

 
procedure TDBHelper.SetSQLConnection(SQLConnection: TSQLConnection);
begin
  FSQLConnection:= SQLConnection;
  if (FSQLConnection = nil) then
    Exit;
  CloseConnection;
  FSQLConnection.Params.StrictDelimiter:= True;
  FSQLConnection.Params.Delimiter:= ';';
  // <snip>
end;

Em seguida implementei os métodos GetConnectionString e SetConnectionString, interagindo com a propriedade DelimitedText do TStringList.

 
function TDBHelper.GetConnectionString: string;
begin
 Result:= FSQLConnection.Params.DelimitedText;
end;

procedure TDBHelper.SetConnectionString(const Value: string);
begin
  FSQLConnection.Params.DelimitedText:= Value;
end;

A propriedade ConnectionString salva em XML ficou assim:

 
<property name="ConnectionString">
  drivername=FIREBIRD;blobsize=-1;commitretain=False;
  database=D:\DB\HTMCDATA.FDB;localecode=0000;
  Password=masterkey;rolename=RoleName;sqldialect=3;
  isolationlevel=ReadCommitted;user_name=sysdba;waitonlocks=False;
  trim char=True;HostName=localhost;ServerCharSet=WIN1252
</property>

Meu próximo passo neste projeto é adicionar ao sistema, um editor de XML visual que comecei a escrever, ainda não está pronto, mas já me ajuda em algumas tarefas básicas.


XmlViewer


XmlViewer


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 Embarcadero, 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.