Saturday, December 29, 2007

Instanciação dinâmica - VCL e VCL.NET

Utilizo bastante a instanciação dinâmica de classes em bibliotecas e projetos Delphi. Algumas vezes a partir do nome da classe, outras a partir da classe propriamente dita. No meu caminho de migração - ou melhor, compatibilização - de algumas bibliotecas para a VCL.NET criei duas funções utilitárias que me permitem trabalhar com o mesmo fonte tanto para Win32 quanto para .NET. A unit segue abaixo. Um projeto completo mostrando a utilização pode ser encontrado aqui.

unit uCreateInstance;

interface

uses
  Classes, SysUtils;

function CreateInstance(AClass: TClass): TObject; overload;
function CreateInstance(AClassName: string): TObject; overload;

implementation

function CreateInstance(AClass: TClass): TObject;
begin
   {$IFDEF CLR}
   Result := Activator.CreateInstance(AClass.ClassInfo); // .NET
   {$ELSE}
   Result := AClass.Create; // Win32
   {$ENDIF}
end;

function CreateInstance(AClassName: string): TObject;
var
   AClass: TClass;
begin
   AClass := GetClass(AClassName);
   if not Assigned(AClass) then
     raise Exception.Create('A classe "' + AClassName + '" não está registrada.');
   Result := CreateInstance(AClass);
end;

end.

Wednesday, December 26, 2007

Quanto mais eu uso o C#...

...mais eu gosto do Pascal e do Delphi!!!!
Francamente. Um tanto de coisa na linguagem é feita para agradar os adoradores do C++ que não podem viver sem os operadores de incremento, ou para rivalizarem com o Java no quesito "quem consegue escrever código com menos linhas". O que, na prática, contribui pouco para o que realmente importa. EMO, clareza de código e facilidade de manutenção é muito, mas muito mais importante, do quê "quem escreve menos código para criar uma classe".

Veja só que beleza de código:

int i = 1;
i = i++;
i = i > 1 ? ++i : --i;
label1.Text = i.ToString();

Qual será o texto do label1????
.
.
.
Tem certeza???
.
.
.
Levou mais de 2 segundos para chegar ao resultado? Então tem algo errado com o código certo? Este tipo de aberração de código é que a linguagem, pela sua estrutura cheia de operadores "mágicos", permite escrever. Claro que a turma do C# vai me dizer "mas o cara que escreveu isto é um asshole!" ou "os operadores são poderosíssimos quando bem usados!". Tudo isto é verdade, claro, mas existem as linguagens que exigem ou reforçam boas práticas, e as que não o fazem. O C# é uma delas.

Mas fazer o quê. Para VS2005 acho melhor mesmo o Chrome!

Monday, December 24, 2007

So this is Christmas

Tem cada uma que a gente lê que desanima... Esta foi mais uma. Não sei quantos "artigos" do Danny Thorpe eu li. Acho que tenho mais idade que ele, mas quando eu era iniciante na informática, ele já escrevia livros.
Aí segue a história: Uma pena realmente, perder este monte de mentes a cada ano.

Thats too bad

Sunday, December 23, 2007

TIOBE Index

Final de ano está aí. E vale uma olhada no TIOBE Index que "mede" a popularidade das linguagens de programação. Para quem não conhece, atenção: Não é um número "cientificamente comprovado"! Mas dá para ter uma idéia do que está acontecendo por aí.

O Delphi está em 11a posição perdendo uma posição para o Ruby (não é novidade) e para o JavaScript (não que eu considere JavaScritp uma linguagem de fato! ). De qualquer forma o número "bom" disso é que o share do Delphi aumentou 0.10 no último ano. Pouco mas eu sinceramente esperava uma queda!

O IDE e a velha paleta

Há bastante tempo uso o plug-in DDevExtensions para o BDS 2006 que, entre outras coisas, me permite ter a "velha paleta" de componentes de volta. Para quem quiser baixar e testar: DDevExtensions. Aproveite e baixe também o DelphiSpeedUp no mesmo site! Este link acima contém a versão oficial. Quem quiser ser um "beta tester" pode baixar os snapshot builds do DDevExtensions, tanto quanto do DelphiSpeedUp no seguinte link: Snapshot Builds. Eu uso e recomendo!

Engraçado é que não conheço sequer um desenvolvedor - desenvolvedor MESMO, não aqueles que só abrem o Delphi para estudar para certificação - que goste de paleta introduzida no BDS 2005 e continuada nas demais versões do Delphi. No Delphi Day online dia 7/12/2007 lembro-me de ter ouvido o Andreano Lanusse dizer mais ou menos "acostume-se com ela pois vai continuar assim!". O pessoal da CodeGear poderia rever isto aí na próxima versão. Pelo menos deveria poder deixá-la como o DDevExtensions faz e assim agradar os desenvolvedores que, assim como eu, preferem a IDE com a paleta antiga.

E preferir a paleta antiga não é "picuinha". A paleta antiga tem 2 vantagens importantes EMO:

1- Ocupa uma faixa estreita acima. Desta forma não torna minúscula a área disponível para quem ainda escreve CÓDIGO (CodeGear tem a ver com isto não? )

2- Permite ver os ícones dos componentes e escolhê-los sem ter que digitar seus nomes

A busca ao digitar é feita exclusivamente num Edit que pode ser colocado onde bem se desejar.

Monday, December 17, 2007

DataSnap.NET - Parte III

Recebi hoje os fontes dos projetos de Ondrej Kelle (http://tondrej.blogspot.com):

1) ASP.NET replacement of CodeGear's httpsrvr.dll

2) WinForms .NET replacement of CodeGear's Scktsrvr.exe

Ambos em C# (BDS 2006). Vou verificar e colocar para rodar em breve!

Obrigado Ondrej!

Saturday, December 15, 2007

Sunday, December 9, 2007

RemObjects & Pascal for VisualStudio

Há muito acompanho o que a empresa RemObjects vem fazendo no mundo do desenvolvimento (www.remobjects.com). Atualmente, ando olhando um pouco mais a fundo os produtos desta empresa. Além do DataAbstract (vulgo Vinci, o original RemObjects), tem o Chrome, que nada mais é que o Pascal para Visual Studio, incluindo o 2005 e 2008.
O primeiro RemObjects eu usei há muito, quando lançado. Hoje olho para ele com outros olhos, uma vez que a perspectiva de desenvolvimento corporativo e em multicamadas é, aparentemente, bem amplo. Não pude deixar de ver também o Chrome - Pascal para VS - e aí é que a coisa complica.... O Object Pascal é, de fato, adorado pelos seus usuários porquê nós de fato achamos que linhas de código como estas

static void Main(string[] args)
{
   int i = 0;
   i = i++;
}

diferentemente do que pensam os fanáticos por C++ e C# (o códito compila em ambos, com resultados diferentes!), nunca, nunca mesmo, irão contribuir para que o código fonte seja mais claro, que a qualidade do software seja mais garantida, que meu trabalho seja mais fácil ou mais bem feito, e que eu chegue mais cedo em casa! E ponto final.

A partir do momento que a RemObjects começa a transformar o ObjectPascal num híbrido eu, particularmente, começo a ficar desconfiado.

Quem quiser, tire a prova: Chrome Language Features

Vou até olhar mais profundamente, mas... com certeza tenho minhas restriçôes.

Friday, December 7, 2007

CodeGear Delphi Day - 7 Dezembro

Acabei de assistir ao Delphi Day online. De novo tive a mesma impressão que tive há pouco mais de um mês na Borcon 2007: Me parece que a CodeGear não vê o Delphi em ambiente corporativo/sistemas distribuídos. Batem na tecla Client/Server e desktop. E claro, ECO e ASP.NET.
Acho que já passou da hora deles abrirem o olho. Muita gente desenvolveu grandes sistemas multi-camadas em Delphi/Win32 ao longo de vários anos, principalmente com o surgimento do Midas/DataSnap. Agora não tem para onde correr. Se vai ter que jogar tudo fora e reescrever, porquê manter em Delphi? Porquê não ir para o VisualStudio?

Será que só eu que enxergo isto?

ATENÇÃO CODEGEAR: Passou da hora de ter um DataSnap.NET!!!! ACORDEM!!!


Tuesday, December 4, 2007

DataSnap.NET - Parte II: Aguardando o código

Continuando sobre o DataSnap.NET...

Escrevi para o TOndrej que mantém o excelente blog sobre programação & Delphi http://tondrej.blogspot.com solicitando o código que ele desenvolveu para criar servidores DataSnap.NET. Ele ficou de me enviar o código, em C# segundo está no blog. Assim que o tiver nas mãos vou dar uma bela fuçada! Seria um belo ponto de partida para um framework funcional. Apesar que... eu obviamente iria criar código em Delphi.NET, BDS 2006 ou RAD Studio 2007, pois o suporte a C# é mínimo.

 

Como NÃO programar um componente Trial/Shareware

Ultimamente tenho tido certa necessidade de “brincar” com os DCU’s de alguns componentes comerciais. “Brincar” aí significa disassemblá-los mesmo, e se possível alterar diretamente o DCU.
Isto pode ser necessário, por exemplo, quando você não possui o código fonte de um componente descontinuado pelo seu desenvolvedor, ou então quando é necessário ter certo nível de “engenharia reversa”.

Inevitavelmente me vem à cabeça uma outra possibilidade: quebrar algum mecanismo de proteção contra execução de componentes shareware, o que obviamente é ilegal e não recomendável. Um mecanismo comum de desenvolvedores de componentes shareware Delphi é checar se o IDE do Delphi está sendo executado. Se estiver, o componente executa normalmente. Caso contrário, a execução é abortada ou alguma nag screen é exibida.

A forma mais infantil de criar este mecanismo de proteção é criar uma função única de checagem e/ou verificação que retorna algum tipo de resultado, geralmente booleano. Quem desenvolve componentes em versões trial nunca deveria fazer isto a não ser que queria que seus DCU’s sejam quebrados até por crackers amadores.

Recentemente disassemblei um componente e encontrei um código deste tipo:

function CheckProtection: boolean;
var
  Reg: TRegistry;
begin
  result := False;
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    Reg.OpenKey('My Software Key', False);
    if Reg.ValueExists('RegistryKey') then
      Result := True;
  finally
    Reg.Free;
  end;
end;

procedure TMyQuery.InternalPost;
begin
  if not CheckProtection then
  begin
    ShowMessage(‘Versão Demo. Bla Bla Bla’);
    Abort;
  end;
  // o código normal do componente “fucional” continua
  inherited InternalPost;
end;

O código não é exatamente assim, claro. É só uma reconstrução resumida do que faz o componente, deduzido a partir da dissecação do seu DCU.
O mais engraçado aqui é que não importa o código da função CheckProtection, muito menos o código que é executado depois da chamada, caso ela retorne False. Se eu modificar 3 bytes no DCU, este código NUNCA será executado.

Disassemblando o DCU gerado para o código em Pascal acima teríamos algo do tipo:

function CheckProtection: Boolean;
  55                  PUSH EBP
  8B EC               MOV EBP,ESP
  83 C4 F8            ADD ESP,-8
  C6 45 FF 00         MOV BYTE PTR [EBP-1],$00
  B2 01               MOV DL,$01
  A1 00 00 00 00      MOV EAX,DWORD PTR [_Dn_TRegistry{0x102}]
  E8 00 00 00 00      CALL TRegistry.Create{0x103}
  89 45 F8            MOV DWORD PTR [EBP-8],EAX
  BA 02 00 00 80      MOV EDX,$80000002
  8B 45 F8            MOV EAX,DWORD PTR [EBP-8]
  E8 00 00 00 00      CALL TRegistry.SetRootKey{0x104}
  33 C0               XOR EAX,EAX
  55                  PUSH EBP
  68 6E 00 00 00      PUSH CheckProtection{0x10D}+$0000006E
  64 FF 30            PUSH DWORD PTR FS:[EAX]
  64 89 20            MOV DWORD PTR FS:[EAX],ESP
  33 C9               XOR ECX,ECX
  BA 84 00 00 00      MOV EDX,CheckProtection{0x10D}+$00000084
  8B 45 F8            MOV EAX,DWORD PTR [EBP-8]
  E8 00 00 00 00      CALL TRegistry.OpenKey{0x105}
  BA 9C 00 00 00      MOV EDX,CheckProtection{0x10D}+$0000009C
  8B 45 F8            MOV EAX,DWORD PTR [EBP-8]
  E8 00 00 00 00      CALL TRegistry.ValueExists{0x106}
  84 C0               TEST AL,AL
  74 04               JE +4; (0x5 )
  C6 45 FF 01         MOV BYTE PTR [EBP-1],$01
  33 C0               XOR EAX,EAX
  5A                  POP EDX
  59                  POP ECX
  59                  POP ECX
  64 89 10            MOV DWORD PTR FS:[EAX],EDX
  68 75 00 00 00      PUSH CheckProtection{0x10D}+$00000075
  8B 45 F8            MOV EAX,DWORD PTR [EBP-8]
  E8 00 00 00 00      CALL TObject.Free{0xFE}
  C3                  RET NEAR
  E9 00 00 00 00      JMP @HandleFinally{0xFF}
  EB F0               JMP -16; (0x65)
  8A 45 FF            MOV AL,BYTE PTR [EBP-1]
  59                  POP ECX
  59                  POP ECX
  5D                  POP EBP
  C3                  RET NEAR
  FF FF               ? EDI
  FF FF               ? EDI
  0F 00 00            SLDT WORD PTR [EAX]
  00 4D 79            ADD BYTE PTR [EBP+121],CL
  20 53 6F            AND BYTE PTR [EBX+111],DL
  66 74 77            JE +119; (0x103)
  61                  POPA
  72 65               JB +101; (0xF4)
  20 4B 65            AND BYTE PTR [EBX+101],CL
  79 00               JNS 0; (0x94)
  FF FF               ? EDI
  FF FF               ? EDI
  0B 00               OR EAX,DWORD PTR [EAX]
  00 00               ADD BYTE PTR [EAX],AL
  52                  PUSH EDX
  65 67 69 73 74 72 79 4B 65 IMUL DWORD PTR GS:[BP+DI+116],$654B7972
  79 00               JNS 0; (0xA )
end;

O código fonte em Pascal não é grande, mas o código assembly correspondente mete medo em qualquer um, certo? Talvez... Mas... Não importa o tamanho ou a complexidade do assembly da função CheckProtection. Se eu pegar as 2 primeiras linhas:

function CheckProtection: Boolean;
  55                  PUSH EBP
  8B EC               MOV EBP,ESP

E transformá-las em

function CheckProtection: Boolean;
  B0 A1               MOV AL,$01
  C3                  RET NEAR

Teríamos exatamente o código que é gerado se eu tivesse uma função do tipo:

function CheckProtection: Boolean;
begin
  Result := True;
  Exit;
  //  o código a partir daqui nunca será executado
  ...
End;

Ou seja, não importa o que tenha após o EXIT! Ele nunca será executado e a função SEMPRE retornará TRUE. Se o desenvolvedor que trabalhou muitas horas para criar este componente basear seu mecanismo de proteção em algo ingênuo deste tipo... sorry, but... it is cracked!

Isto é só um exemplo do que é possível fazer com um DCU, e de como não se deve programar um mecanismo de proteção de versão de componente trial ou shareware!

Pode-se fazer outras coisas interessantes com uma DCUs, editando-a diretamente, tipo mudar o timestamp permitindo burlar o erro "A unit XPTO foi compilada com versão diferente da unit ABCD".

Monday, December 3, 2007

Firebird em Windows XP: Primeira conexão muito lenta

Assim como 90% dos Delpheiros também utilizo o Firebird em alguns sistemas - ainda na versão 1.5. Recentemente fui rodar um sistema que estava parado há tempos, e comecei a perceber que a primeira conexão levava minutos. Muitos minutos. Parecia até que travava o Windows XP.

Bem, depois de vasculhar a internet descobri o motivo: A extensão .GDB do arquivo de banco de dados e as interferências do System Restore (Restauração do Sistema) do Windows XP. Toda vez que um arquivo .GDB é acessado/modificado o "System Restore" automaticamente faz uma cópia do mesmo. Quando o arquivo tem poucos Megabytes isto pode ser imperceptível. Mas eu estava trabalhando com um BD de 800 Mb. Como resultado, a primeira conexão - via sistema ou via IBExpert - levava cerca de 5 minutos!

http://support.borland.com/kbshow.php?q=25953

Workaround:

1) Desabilite o System Restore do Windows XP - Não recomendável por razões óbvias

2) Modifique a extensão de seus arquivos Interbase/Firebird. Eu preferi usar esta. Padronizei então meus arquivos .GDB como sendo: Extensão .IB para os Interbase, e extensão .FDB para os arquivos Firebird. E voilá!

 

Monday, November 26, 2007

Filtros em TADODataSet

Descobri recentemente que o TADODataSet e seus descendentes, baseados no ADO Recordset, têm uma peculiaridade na utilização de filtros.

O filtro

  (campo1 = valor1 OR campo1 = valor2) AND campo2 = 'ABCD'

simplesmente não funciona!!!

Não pode haver agrupamento de cláusulas usando o OR e posteriormente agrupando-as com outras cláusulas usando o AND. Teria que reescrever o filtro com:

  (campo1 = valor1 AND  campo2 = 'ABCD')
OR (campo1 = valor2 AND campo2 = 'ABCD')


Isto complica bastante a vida do desenvolvedor que, como eu, criou um "editor visual genérico" de filtros que se aplica a qualquer descendente do TDataSet.
Maneira rápida de fugir do problema: Utilize um ClientDataSet ligado num DataSetProvider, que por sua vez está ligado no ADODataSet (ou ADOQuery) original. E passe a usar o ClientDataSet no lugar do ADODataSet. O primeiro - e também o segundo - exemplo de filtro funciona perfeitamente no ClientDataSet!
Mais uma vez o ClientDataSet se mostrando superior ao ADO Recordset.

Sunday, November 25, 2007

Serialização de Objetos - Parte I

Quem trabalha com C# ou Java certamente irá encontrar em seu caminho a serialização de objetos, de forma mais ou menos rotineira. O interessante é que existem várias bibliotecas em Delphi que implementam métodos e classes para trabalhar com serialização, mas dificilmente encontramos código escrito utilizando este conceito. Uma destas bibliotecas era a Globus que foi depois incorporada pela gigante JEDI JVCL.

O conceito é simples: a partir de uma instância de uma classe qualquer – geralmente descendente de TPersistent – obtêm-se um XML que permita “reconstruir” esta instância mantendo-se todas as suas propriedades. Isto é conseguido fazendo extenso uso da RTTI (Run Time Type Information) para obter todas as propriedades Published da classe (somente as propriedades Published da classe geram informação de RTTI).

O processo de geração do XML que representará a classe é também simples: Percorre-se a lista de todas as propriedades Published da classe, convertendo cada property em um Tag correspondente, da forma:

<nome da propriedade>valor da propriedade</nome da propriedade>

Um TEdit por exemplo poderia ser representado pelo seguinte XML:

<TEdit>
    <Left>27</Left>
    <Top>59</Top>
    <Width>121</Width>
    <Height>21</Height>
    <Tag>1</Tag>
    <Visible>True</Visible>
</TEdit>

Atualmente venho utilizando a JVCL (classe TXMLSerializer) para serializar objetos. De fato, crei uma nova classe baseada na TXMLSerializer da JVCL, para ficar isolado de possíveis mudanças na JVCL - uma vez que da versão 2 para a 3 já ocorreram mudanças significativas, e não posso me dar ao luxo de reescrever código de produção sempre que a JVCL mudar.

O melhor de tudo é que migrei o TXMLSerializer para Delphi.NET (BDS 2006) - possuo um único código fonte para Win32 e .NET - e assim consigo serializar objetos entre aplicações Win32 e .NET, sem problemas, e sem precisar das monstruosidades dos parsers XML da MS, nem no ambiente Win32 nem no ambiente .NET.

Mais sobre este assunto depois!

 

Descobrindo se uma classe descende de uma outra

Criei uma pequena função que me permite dizer se uma classe é descendente de uma outra, utilizando o nome da classe ancestral.

Você pode se perguntar: "Mas qual o objetivo disso? Não é mais fácil usar o operador is?" Por exemplo:

if ActiveControl is TEdit then
  TEdit(ActiveControl).SelectAll;

A resposta é: Depende! O operador is faz uma checagem de tipo dinâmica, mas requer que o TEdit seja conhecido em tempo de compilação e consequentemente requer que o código da classe TEdit esteja linkado no executável. O código acima só compila se a unit StdCtrls (onde está a declaração da classe TEdit) esteja na cláusula uses da unit.

Agora, imagine que você tenha um método onde inúmeras classes podem ser passadas como parâmetro e você não deseja - ou não possa - linkar todas as possíveis classes. Exemplo:

Procedure DoSomething(Instance: TPersistent);

Bem provavelmente você pode pensar: "Mas de quê me serve um método assim se desconheço a classe e não poderei usá-la diretamente?" A resposta é que bem provavelmente você irá utilizar a RTTI diretamente para obter e modificar as propriedades dos objetos referenciados por Instance, assim como faz o nosso conhecido Object Inspector.

Precisei utilizar esta função em algumas classes para saber, por exemplo, se um determinado DataSet era descendente direto do TCustomADODataSet padrão do Delphi, ou de um outro DataSet com linhagem totalmente diferente (TQuery, TSQLQuery), sem ter que linkar com as units ADODB, DBTables e SqlExpr, o que aumentaria consideravelmente o tamanho do meu executável.

Isso me permitiu criar classes de um framework que trabalhavam igualmente bem com ambos os DataSets, SEM QUE O CÓDIGO DE NENHUM DELES FOSSE LINKADO NO MEU EXECUTÁVEL FINAL.

O código é simples e por isto dispensei comentários. Simplesmente faço um loop onde comparo o nome da classe da instância passada como parâmetro com o nome da classe procurada. Se não for igual, passo para o ancestral imediatamente superior e refaço a comparação. Repito até que o resultado seja verdadeiro ou eu chegue ao topo da árvore da hierarquia do objeto.

function PertenceAClasse(const Instance: TObject; ParentClassName: string): boolean;
var
  ParentClass: TClass;
  ObjClassName,
  TargetClassName: string;
begin
    Result := False;
    ObjClassName := UpperCase(Instance.ClassName);
    TargetClassName := UpperCase(ParentClassName);
    ParentClass := Instance.ClassType;
    repeat
      if ObjClassName = TargetClassName then
      begin
        Result := True;
        break;
      end;
      ParentClass := ParentClass.ClassParent;
      if ParentClass <> nil then
       ObjClassName := UpperCase(ParentClass.ClassName);
    until (ParentClass = nil);
end;

Wednesday, November 14, 2007

DataSnap.NET... Thats cool!

Navegando pelos blogs de papas como Dan Miser encontrei o seguinte link

http://tondrej.blogspot.com/2004/10/datasnapnet.html

Really COOL guys!

Há exatos 2 anos venho batendo nesta tecla com o pessoal da CodeGear. Conversei inclusive com o Ramesh Theivendran na Borcon 2005 em SP. Imagine um servidor 100% .NET servindo clientes DataSnap, no matter what, ou seja, clientes Win32 ou .NET.
Imagine poder portar o servidor de aplicações para .NET e manter os clientes ainda em Win32? Migrar quando for mais conveniente?
Além de todo o horizonte que me abriria, iria matar os desenvolvedores VB e C# de inveja, é ou não é?

Porém... O post no blog é de 2004!!! E hoje, mais do que em 2004 EMHO, esta tecnologia seria bem vinda. Vou tentar contato com o autor para saber em que pé ficamos.

Ainda sobre a M$

Esta é só para descontrair... mas fala sério.... como é possível um cara que se deixa fotografar assim acabar se tornando o homem mais rico do mundo? Obviamente falta-lhe "tato" - para dizer pouco - quando se deixou clicar assim, certo? E então? Qual o segredo do sucesso? hehehehe

Here we go Vista?

  • Mood:
A M$ sempre consegue me surpreender. Geralmente pelo lado negativo. O Windows Vista é um destes casos. Na sua instalação e configuração padrão eu achei tão ruim, fiquei tão pouco a vontade que fico pensando se algum dia, quando for forçado a usá-lo, não vou sentir vontade de mudar de profissão... ou talvez ir para a turma do pinguim.

É muito muito chato, muito muito cheio de frescura visual que CANSA, e muito muito pouco produtivo. Depois de usá-lo por algum tempo me senti desiludido! Sinceramente! Senti igual quando tive que admitir que o ICQ estava morto, para glória do MSN Messenger, que até hoje não faz o que o ICQ fazia em 1998... Well, nesta área de TI parece que quase tudo novo piora um pouco o que já existia.

Fico impressionado como o XP alcançou rapidamente um nível de maturidade, para mim, excelente (não sou expert em segurança de SO!). Em mais de 2 anos que o uso não me lembro de ter "dado pau", travado, etc. Como plataforma para DESENVOLVIMENTO Windows, dificilmente será desbancado. Mas é isto. Resistirei enquanto puder!

E despistadamente alguns fabricantes de computadores/notebooks que vêm com Vista O&M instalado estÃo fazendo downgrade do SO... despistadamente para que a turma de Redmont não ouça...

Tuesday, November 13, 2007

Desenvolvimento Windows, futurologia & outras leituras de interesse.

Alguns links que têm muita informação para quem desenvolve aplicações Windows em Delphi. Onde estamos, para onde vamos? Muito bom material.

Is Microsoft expanding the war?
Steve Trefethen

Giving Up on Microsoft
Jeff Atwood

Desktop Applications are Dead
Eugueny Kontsevoy

Desktop Applications are not dead!
Antonio Cangiano

E aí? Morreu ou não morreu?

Wednesday, November 7, 2007

Apresentação na Borcon 2007

Arquitetura multi-camadas e multi-clientes Delphi. Win32 e Intraweb

Aí está o link para o dowload da minha apresentação na Borcon 2007 que teve o título acima.

Recebi alguns e-mails solicitando este material uma vez que o DVD que a Borland/CodeGear distribuiu no evento não continha nenhuma palestra.
Achei isto uma falha terrível da organização. O "evento" em si não termina no final do terceiro dia de apresentação. Todo mundo quer ver o material, inclusive consultar outras palestras que não puderam assistir ao vivo.

Download da palestra

Tuesday, November 6, 2007

SystemBuilder da Squadra

A empresa Squadra, de Belo Horizonte, há alguns anos era muito conhecida entre os desenvolvedores Delphi. Era parceira Borland e criava ferramentas para desenvolvimento Delphi como por exemplo o SystemBuilder.

Bem... até hoje está lá no site deles para vender o SystemBuilder versão 3.x, para Delphi 5, 6 e 7. O demo que tem para download é 3.2. O software é protegido contra execução não autorizada, cópia, etc pelo HandProt, outra ferramenta da Squadra.

Um conhecido meu tem um sistema que se utilizou o System Builder para ser desenvolvido e me pediu para estudar a possibilidade de EVOLUÇÃO do sistema. Putz... que arapuca! Como a Squadra parou de desenvolver o SystemBuilder (não há versão para IDE superior ao Delphi 7), e também não tornou o fonte aberto (está aí uma boa idéia pessoal da Squadra!), não há como migrar o sistema para BDS 2006 por exemplo sem ter que reescrevê-lo.

Outra chatisse do SystemBuilder é sua proteção contra cópia. Se você tem um computador desktop e um notebook, prepare-se: Ou compre duas licenças ou use somente um deles. Nos idos de 1997 quando a Squadra vendia o SystemBuilder ainda vá lá. Mas hoje??

Resumo da ópera: Resolvi pegar os .dcu do SystemBuilder e, digamos, dissecá-los, para não dizer disassemblá-los!
Descobri duas coisas bem interessantes: O HandProt me pareceu bem escrito, com segurança redundante, proteção contra debugging, etc. Já o SystemBuilder... Só precisa de um patch de 6 bytes em 1 DCU e voilá! Não que eu tenha feito isto, certo?

Em breve vou detalhar como é feito isto.

Caros leitores, mais sobre Squadra, System Builder e Handprot aqui:

Borcon 2007

Semana passada estive na Borcon 2007, em São Paulo. Estive como participamente e como palestrante - 1st time! Minha palestra foi "Arquitetura multi-camadas e multi-clientes Delphi. Win32 e Intraweb". Pelo feedback que tive parece que foi bem recebida pelos colegas!

Algumas percepções minhas sobre a Borcon este ano:
  • Da CodeGear: David I, Steve Shaughnessy (DBX) e o CEO Jim Douglas. Muito boas apresentações de todos eles. E muito bom ver o CEO vindo ao Brasil falar para a comunidade Delphi.
  • Muito ECO IV, ASP.NET, DBExpress 4 e Blackfish, tudo do novo RAD Studio 2007.
  • O novo DBExpress foi apresentado pelo arquiteto responsável pelo mesmo Steve Shaughnessy. A nova arquitetura do DBX me pareceu 10!
  • Gostei muito do Blackfish, e acredito que desenvolvedores ASP.NET e Desktop que utilizam o Delphi vão gostar também. O deploy é muito simples e acredito que vai ser a "preferência" para este tipo de desenvolvedor. Ainda não sei dos detalhes de LICENÇAS ($) para deploy do Blackfish. Espero que a CodeGear não limite a sua utilização como fez com o Midas, quando foi lançado. Entre pagar pelo Blackfish ou usar o MySQL que já tem em 99% dos web hosts... qual será a opção?
  • Fiquei muito pensativo sobre um gráfico que o Jim mostrou em sua apresentação, onde Delphi e C++ estão no lado do desenvolvimento "Desktop, small & middle-sized", deixando o Enterprise para o "managed code", C#, Java, etc. Levando por este lado a CodeGear quer nos dizer aplicações Win32 (e futuramente 64) acabaram no ambiente corporativo??? Até aí tudo bem... But... O RAD Studio 2007 é puro Delphi e C++. Aí pergunto: O preço do RAD Studio é compatível com ESTE MERCADO???

More comments later