Revista Do Linux
 
EDIÇÃO DO MÊS
 CD do Mês

 Capa
 Entrevista
 Corporativo
 Programação
 Segurança
 Ferramenta
 Produto
 Hardware
 

Aplicações Delphi para o Kylix

Uma grande contribuição do Kylix é a possibilidade de portar as aplicações escritas em Delphi do Windows para o Linux. Apesar de todos os pontos fortes do Linux na área de servidores, existe a necessidade de mais aplicativos para uso diário nas empresas (contabilidade, folha de pagamento, controle de estoque e contas a pagar). O Kylix trouxe o empurrão que faltava para que o Linux tivesse mais aceitação nos desktops corporativos. Neste artigo, vamos ver como portar uma aplicação escrita em Delphi para o Kylix. Considere aqui as aplicações escritas em Delphi 5. O

Delphi 6 permite escrever programas portáveis sem nenhuma modificação.

VCL e CLX

O Delphi usa uma biblioteca baseada na API e controles do Windows, chamada VCL (Visual Component Library). A VCL é difícil de ser portada para outros ambientes, e a solução encontrada pela Borland foi usar a biblioteca Qt como base para sua nova biblioteca de componentes, a CLX. A Qt é bastante usada e portável para diversos ambientes.

À primeira vista, os componentes da CLX e da VCL são iguais e a maneira de trabalho é a mesma. Isso foi feito para aproveitar a experiência dos desenvolvedores Delphi e minimizar o choque da mudança de ambiente. Internamente, a biblioteca foi reescrita, removendo a dependência do Windows.

O desenvolvedor Delphi encontrará um ambiente de trabalho conhecido ao abrir o Kylix (Figura 1), com uma paleta de componentes semelhante ao Delphi.

Bancos de Dados (BD)

Aqui está uma das grandes diferenças entre o Delphi e o Kylix. A BDE do Delphi, a engine de bancos de dados, embora flexível e capaz de se ligar a diversos BD, é grande e pesada, impondo uma camada muito espessa entre a aplicação e o BD. No Kylix, a Borland substituiu a BDE por algo mais leve e rápido, o dbExpress.

O dbExpress é uma camada fina e rápida entre o BD e a aplicação, trazendo pouca sobrecarga ao sistema. É uma engine de acesso a dados unidirecional, baseada em SQL. Isso quer dizer que só se podem movimentar os dados em uma direção, como se estivéssemos criando um relatório, não se pode acessar um registro do BD já lido.

Baseada em SQL, não há na primeira versão acesso à base de dados desktop como Paradox ou dBase. Isso não é uma perda muito grande, pois o Interbase da Borland teve seus fontes abertos e pode ser distribuído gratuitamente. Além disso, existem drivers para MySql, Oracle e DB/2 e drivers de terceiros para acesso a ODBC. Isso possibilita o acesso a qualquer base de dados que tenha drivers ODBC, como PostgreSQL ou MS-SQL.

A limitação do acesso unidirecional pode ser contornada com o uso da tecnologia multicamadas do Delphi, o Midas. Usualmente, o acesso a BD é feito em duas camadas: o cliente e o servidor de BD (figura 2). O acesso multicamadas incorpora uma ou mais aplicações intermediárias que, por sua vez, acessam o cliente, que acessa o servidor, como mostra a figura 3.

Na realidade, apenas um componente da tecnologia Midas é usado: o TClientDataset. Na primeira versão não está disponível o acesso multicamadas. Esse componente recebe os dados de um provedor de dados (componente TDatasetProvider), que se interliga à fonte de dados, como mostra a Figura 4. Essa fonte de dados pode fornecer os dados de diversas maneiras: TCP/IP, http, ou mesmo DCOM, em ambiente Windows.

No Kylix, o provedor de dados recebe as informações do cliente de BD e transmite ao TClientDataset, que é um componente flexível, permitindo acesso multidirecional aos dados, além de atualizações em lote e possibilidade de desfazer as últimas modificações, entre outras vantagens. A Figura 5 mostra como é feito esse tipo de acesso.

Ao portar uma aplicação que usa acesso a dados, basta substituir os componentes de acesso (TTable, TQuery) pelos componentes unidirecionais (TSqlTable, TSqlQuery), incluindo um TDatasetProvider e um TClientDataset, ligando-se esse ao TDatasource, que fará a ligação com os componentes de interface com o usuário. Outra opção é substituir os componentes do Delphi pelo TSqlClientDataset, que engloba o componente unidirecional, o TDatasetProvider e o TClientDataset num só componente.

Convertendo programas que usam a API Windows

Os programas Delphi que usam apenas componentes da VCL devem ser convertidos sem problemas. Mais grave será se a API do Windows tiver sido usada diretamente. A menos que se use a WineLib (biblioteca que emula as funções da API do Windows), os programas deverão sofrer modificações.

O Linux dá duas opções para essa conversão: usar a API do Qt diretamente ou então a API da LibC, a biblioteca padrão C. O Kylix permite utilizar tanto uma como a outra, como se fossem funções nativas do Kylix.

A Qt é uma biblioteca de classes C++, incompatível com o Kylix. Para usar essas classes no Kylix, foi feito um "achatamento" delas e a criação de uma unit de importação. Assim, pode-se usar a API do Qt diretamente, criando programas ou componentes que ampliam a funcionalidade do Kylix. É possível inclusive desenvolver programas que apenas a API Qt. A API do Qt é muito extensa e a melhor referência é a sua documentação. Ao examinar as classes, você verá algo como:


QLabel ( QWidget * parent, const char * name=0, WFlags f=0 )

Esse é um dos construtores do componente QLabel. Para usá-lo no Kylix, as seguintes conversões foram feitas:

  • Todo o uso de componentes Qt é feito por meio de um manipulador (handle).
  • Quando se trata de um construtor, ele é traduzido para uma função que retorna o manipulador criado.
  • Nos métodos da classe, o manipulador é passado como o primeiro parâmetro da função.
  • Os métodos são criados usando-se o nome da classe, um sublinhado e o nome do método.

Dessa maneira, esse construtor foi traduzido para o Pascal, na Unit Qt.pas, da seguinte maneira:

function QLabel_create(parent: QWidgetH; name: PAnsiChar; 
f: WFlags): QLabelH; overload; cdecl;

A partir daí, a procedure QLabel_create pode ser usada em qualquer programa e criará um Label em tempo de execução, retornando para o programa um valor de tipo QLabelH, um handle para um QLabel, que pode ser usado no programa. Assim, podemos converter, do Windows, o código que desenha texto inclinado:

procedure TForm1.FormPaint(Sender: TObject);
var
 OldFont,NewFont : hFont;
 LogFont : TLogFont;
begin
// obtém manipulador do fonte do Canvas
 OldFont := Canvas.Font.Handle;
// desenho transparente
 SetBkMode(Canvas.Handle,Transparent);
// preenche LogFont com dados do fonte atual
 GetObject(OldFont,Sizeof(LogFont),@LogFont);
// muda ângulo para 45E 
 LogFont.lfEscapement := 450;
// cria novo fonte
 NewFont := CreateFontIndirect(LogFont);
// seleciona fonte a desenhar
 SelectObject(Canvas.Handle,NewFont);
// desenha texto no meio da janela
 TextOut(Canvas.Handle,ClientWidth div 2,ClientHeight div 2,
'Texto inclinado', 15); // limpa
DeleteObject(SelectObject(Canvas.Handle,
OldFont));
end;

Esse código, usando a API CLXDisplay (nome dado à importação da biblioteca de classes do Qt), ficaria da seguinte maneira:

procedure TForm1.FormPaint(Sender: TObject);
var
DevPoint,PrPoint : TPoint;
begin // desenha no meio da janela
DevPoint.X := ClientWidth div 2;
DevPoint.Y := ClientHeight div 2;
// gira o Canvas 45 graus
QPainter_rotate(Canvas.Handle,-45);
// converte as coordenadas de dispositivo para o modelo
QPainter_xFormDev(Canvas.Handle,
PPoint(@PrPoint),   
PPoint(@DevPoint));
// desenha o texto
Canvas.TextOut(PrPoint.X, PrPoint.Y, 
‘Texto inclinado’);
end;

A figura 6 mostra o programa convertido em execução. Uma conversão como esta tem a vantagem de ser portável para o Delphi 6, bastando para isto recompilar o programa ali. Outra opção de conversão é usar as funções da LibC. Nesse caso, o código não é portável e não será compatível com o Delphi 6. A fonte de documentação para usar as funções da LibC são as páginas man. Encontrada a função desejada, você deve ir à unit Libc.pas e verificar como essa função deve ser usada no Kylix. Por exemplo, para executar um outro programa em Windows você pode usar a função WinExec, como em:

procedure TForm1.Button1Click(Sender: TObject);
begin
if Edit1.Text <> ‘’ then
// se tem algum comando na caixa de edição, executa
 WinExec(PChar(Edit1.Text),SW_SHOWNORMAL);
end;
No Linux, essa função pode ser substituída pela função system, como em:
procedure TForm1.Button1Click(Sender: TObject);
begin
if Edit1.Text <> ‘’ then
// se tem algum comando na caixa de edição, executa
Libc.system(PChar(Edit1.Text));
end;

Note que, tanto num caso como no outro, as funções são usadas como se fossem do próprio Kylix. Basta incluir as units Qt (quando se usam funções CLXDisplay) ou Libc (quando se usam funções da LibC) na cláusula uses da unit, onde você quer usar as funções.

O que será difícil de converter

Os programas que utilizam alguns dos recursos abaixo poderão ter maior dificuldade de conversão:

  • Tecnologias exclusivas Microsoft, como OleAutomation, DCom ou ActiveX.
  • Registro do Windows.
  • API Multimídia do Windows — o componente MediaPlayer não foi convertido.

Todas essas dificuldades podem ser contornadas usando-se diversas tecnologias, como comunicação interprocessos, TCP/IP, CORBA e arquivos de configuração, entre outras, mas sua conversão requer mais trabalho. Porém, 90% das aplicações Delphi poderão ser portadas com pouco trabalho.

Para saber mais

Wine/WineLib: www.winehq.com

Trolltech: www.trolltech.com

Documentação da biblioteca Qt: doc.trolltech.com


A Revista do Linux é editada pela Conectiva S/A
Todos os Direitos Reservados.

Política de Privacidade
Anuncie na Revista do Linux