terça-feira, 20 de julho de 2010

Simulando um keybd_event

Nos meus programas em Delphi, algumas vezes, se fez necessário simular o pressionamento de uma tecla num TEdit que ainda não recebeu o foco.

Por exemplo:

procedure TFormPegaProdutos.DBGrid1KeyPress(Sender: TObject;
var Key: Char);
begin

//Testa se pressionou um tecla valida
if not (key in ['0'..'9','/',#13,#27,'A'..'z']) Then key:=#0;
if key=#27 then close;

//Testa se pressionou um letra
if (key in ['A'..'Z']) or (key in ['a'..'z']) Then
begin
//Abre um painel para digitacao do nome do item a pesquisar
. PanelPesquisa.Top:=80;
. PanelPesquisa.Left:=160;
. PanelPesquisa.visible:=True;
. Palavra1.setfocus;
. if (key in ['a'..'z']) Then Key:=chr(trunc(ord(Key))-32);
. keybd_event(trunc(Ord(Key)),0,0,0);
end;
if key in ['0'..'9'] Then
begin
. PanelVenda.Top:=80;
. PanelVenda.Left:=60;
. PanelVenda.visible:=True;
. ValorUni.Text:=FormatCurr('#0.00',ProTEMPP_VIS.AsCurrency);
. QTD.setfocus;
. keybd_event(trunc(Ord(Key)),0,0,0);
end;

...ou seja, na lista de itens (dbgrid1) o usuario pode abrir um painel de pesquisa de um novo item sem sair da lista, e ainda pode registrar uma venda do item, sem sair da lista, o que é, diga-se de passagem, muito prático.

Mas no lazarus não temos disponivel o keybd_event, então como resolver esse problema?

Criei uma simples procedure:

procedure keybd_event_on(EditControl:TEdit; var key: char);
begin
EditControl.Text:=key+' ';
EditControl.setfocus;
EditControl.SelStart:=1;
EditControl.SelLength:=1;
end;

Pronto!

Agora, posso continuar portando meus programas pro lazarus :-)
Não é por causa de um keybd_event que o projeto vai parar!

procedure TFormPegaProdutos.DBGrid1KeyPress(Sender: TObject;
var Key: Char);
begin

//Testa se pressionou um tecla valida
if not (key in ['0'..'9','/',#13,#27,'A'..'z']) Then key:=#0;
if key=#27 then close;

//Testa se pressionou um letra
if (key in ['A'..'Z']) or (key in ['a'..'z']) Then
begin
//Abre um painel para digitacao do nome do item a pesquisar
. PanelPesquisa.Top:=80;
. PanelPesquisa.Left:=160;
. PanelPesquisa.visible:=True;
. Palavra1.setfocus;
. if (key in ['a'..'z']) Then Key:=chr(trunc(ord(Key))-32);
. keybd_event(trunc(Ord(Key)),0,0,0);
. keybd_event_on(Palavra1,Key);
end;
if key in ['0'..'9'] Then
begin
. PanelVenda.Top:=80;
. PanelVenda.Left:=60;
. PanelVenda.visible:=True;
. ValorUni.Text:=FormatCurr('#0.00',ProTEMPP_VIS.AsCurrency);
. QTD.setfocus;
.//keybd_event(trunc(Ord(Key)),0,0,0);
. keybd_event_on(QTD,Key);
end;

O lazarus não é 100% compativel com o Delphi, mas ao depararmos com problemas como esse, não podemos desistir, sempre tem uma saida.

Seja livre!
Use lazarus/freepascal.

segunda-feira, 19 de julho de 2010

GERAOBJCODE - Simples gerador de codigo OOP

Pra quem esta começando na programação OOP, e não dispõem de nenhuma ferramenta auxiliar para geração de codigos, venho aqui disponibilizar uma ferramenta de minha autoria.

É um programa simples, mas que tem sido muito util pra mim.

GERAOBJCODE





Muito simples de usar, basta informar o nome da classe ou objeto, colocar as variaveis da classe/objeto na caixa codigo fonte do objeto e clicar em gerar propriedades e metodos.


Imagine que será necessário criar propriedades e metodos para os items abaixo:
Nome da classe: TObjetoTeste

Itens que compoem a nossa classe:




Codigo gerado pelo nosso GERAOBJCODE:








Criticas, elogios, deixem a sua mensagem.

Link para download dos fontes:
GERAOBJCODE

Até a próxima.

segunda-feira, 5 de julho de 2010

Build Lazarus com QT - problemas encontrados

Build Lazarus com QT no linux

A ide GTK2 está excelente, porem é muito lenta comparada com a IDE QT, por isso eu recomendo a todos aqueles que precisa de uma IDE mais agil que use o widget QT

Levando em conta que a solução a seguir foi o que resolveu pra mim. Eu uso o lazarus versão svn, e se encontra na pasta
/home/usuario/lazarus29-2svn/lazarus/

Quem instalou o lazarus a partir dos pacotes, normalmente o lazarus esta localizado em /usr/lib/lazarus.

Exclarecido esses pontos, continuemos.


Problemas encontrados

Mensagem de erro:

Unable to find file "osprinters.pas"

Solução:

Abra um terminal e localize a unit osprinters.pas:

no meu caso digitei:
find ~/lazarus29-2svn/lazarus -name "osprinters.pas"

Retornou:

/home/usuario/lazarus29-2svn/lazarus/components/printers/osprinters.pas

Agora abra o /etc/fpc.cfg

Acrescente o path de osprinters a seção searchpath for units

-Fu/home/usuario/lazarus29-2svn/lazarus/components/printers/


Mensagem de erro:

.../printers/osprinters.pas(47,8) Fatal: Can't open include file "qtprinters_h.inc"

Repita o mesmo procedimento, no terminal pesquise o arquivo com o find, e acrescente o path seção searchpath for includefiles de /etc/fpc.cfg assim:

-Fi/home/usuario/lazarus29-2svn/lazarus/components/printers/qt/


Agora é só:

Build LCL
Build IDE with packages

E pronto, problema resolvido.

Seja livre
Use lazarus!

sábado, 3 de julho de 2010

FortesReport4Lazarus323

Comunico a todos que foi criado um novo projeto no sourceforge para o gerador de relatorios FortesReport4Lazarus

Esse projeto baseia-se na versão 3.23 do Fortes Report, mas com algumas melhorias e correções de bugs que foram feitas na versão 3.24 do Fortes4Lazarus:

.Modo draftfilter ok
.Exporta para html,pdf,excel
.Gera os relatorios mais rapidamente que na versão 3.24


A versão do Fortes4lazarus baseado na 3.24 está com um bug, que ainda não sabemos se é no Fortes4Lazarus ou na LCL, por isso recomendo a todos que voltem sua atenção para a versão 3.23.

Em breve estarei disponibilizando um projeto baseado na 3.24, que não finaliza, terminando a aplicação abruptamente, que é nosso bug, para que todos testem e deem sugestões.
O bug só ocorreu no windows, sendo que no linux o mesmo relatório funcionou normalmente.

Ainda não subi os fontes, mas em breve estarão disponiveis para todos.

O projeto Fortes4Lazarus precisa de contribuições para acelerar o desenvolvimento.

Se você é programador e tem um tempo livre, ajude a manter esses projetos, e assim fortalecer mais o nosso querido lazarus/freepascal.


Link para download da versão 3.23 no sourceforge:

FortesReport4Lazarus323

Seja livre
Use Lazarus/freepascal

quinta-feira, 1 de julho de 2010

Nova versão do Fortes4lazarus

Estou disponibilizando a comunidade uma nova versão do gerador de relatorios Fortes4Lazarus.

Essa ferramenta é um fork, uma adaptação, da versão 3.23 do FortesReport para delphi.

Não deixem de informar os bugs, pois tenho pouco tempo para testar toda a funcionalidade dos componentes.

Criticas ou sugestões serão bem vindas.

Link para Download do pacote:

Fortes323forlazarus

Seja livre!
Use lazarus/freepascal.

Até a próxima.

quarta-feira, 30 de junho de 2010

TCustomForm.ShowModal impossible

Explicação:

Você está tentando Showmodal em um form que esta visivel.

o form tem um Visible = True, e é isso que está causando o problema.

Solução:

Altere Visible = True para Visible = False

Pronto. Problema resolvido :-)

Seja livre!
Use lazarus/freepascal

quinta-feira, 24 de junho de 2010

TStringList - Uso da propriedade Values

Nesse post, vou apresentar um exemplo de uso da propriedade Values da classe TStringlist.

É muito comum precisarmos manter uma lista de variaveis totalizando campos numericos. O problema é que toda vez que precisamos de um novo totalizador, temos que criar uma nova variavel no programa.

Uma abordagem mais pratica dessa situação, é utilizar a classe TStringlist.
Nesse caso o TStringlist funcionará como um array, com a vantagem que seus elementos podem ser acessados pelo nome.


A propriedade Values

O TStringlist nos dá a opção de nomear elementos, associando seu respectivo valor, através do metodo Values.

Exemplo:

var
Lista1:TStringlist;
x:integer;
begin
Lista1:=TStringlist.Create;
for x:=1 to 5 do
begin
Lista1.Values['elemento'+inttostr(x)]:=inttostr(x*2);
end;

end;

Resultará em:
elemento1=2
elemento2=4
elemento3=6
elemento4=8
elemento5=10

Para acessar o valor de 'elemento3' basta executar:

Edit1.text:=Lista1.Values['elemento3'];

Que retornará a string '6'.

Pronto! Muito pratico não é mesmo?

Vamos então a um exemplo mais completo.

Para esse caso, criei duas funções:

function GetStringValue(svVar:string):Real;
procedure setStringValue(svVar:string;svValue:Real);

function GetStringValue(svVar:string):Real;
begin
Result:=StrtoFloat(CalcList.Values[svVar]);
end;

procedure setStringValue(svVar:string;svValue:Real);
begin
CalcList.Values[svVar]:=FloatToStr(svValue);
end;

A função GetStringValue retorna um valor convertido no tipo Real, de modo que podemos utilizar como totalizador, ou qualquer uso que desejar.

A função setStringValue cria/atribui um determinado valor a um elemento do Stringlist.

Exemplos:

setStringValue('total1',100); -> cria/atribui valor 100 a um elemento chamado total1

MinhaVariavelFloat:=GetStringValue('total1');-> atribui o 100 a MinhaVariavelFloat;

Agora incrementamos a variavel:

MinhaVariavelFloat:=MinhaVariavelFloat+20;

E atribuimos novamente ao elemento 'total1':
setStringValue('total1',MinhaVariavelFloat);

MinhaVariavelFloat:=GetStringValue('total1'); Resulta em 120

Espero que essas funções sirvam para você leitor, tanto quanto serviu pra mim.

Qualquer duvida, sugestão ou critica, fiquem a vontade para comentar.

Abaixo, o codigo fonte do nosso exemplo:

unit testa_strings_values0;
{$mode objfpc}{$H+}
interface

uses
   LCLIntf, LCLType, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, Buttons, StdCtrls, ComCtrls;

type

   { TForm1 }

   TForm1 = class(TForm)
      calcular: TButton;
      box_varlist: TComboBox;
      box_operation: TComboBox;
      Criar_variavel: TButton;
      Edit_calcval: TEdit;
      Edit_valor1: TEdit;
      Edit_var1: TEdit;
      GroupBox1: TGroupBox;
      GroupBox2: TGroupBox;
      Label10: TLabel;
      Label11: TLabel;
      Label7: TLabel;
      Label8: TLabel;
      Label9: TLabel;
      ListBox1: TListBox;
      Memo1: TMemo;
      PageControl1: TPageControl;
      TabSheet1: TTabSheet;
      procedure calcularClick(Sender: TObject);
      procedure Criar_variavelClick(Sender: TObject);
      procedure FormCreate(Sender: TObject);
      function GetStringValue(svVar:string):Real;
      procedure setStringValue(svVar:string;svValue:Real);
   private
      { Private declarations }
   public
      { Public declarations }
   end;

var
   Form1: TForm1;
   CalcList:TStringlist;

implementation

{$R *.lfm}


procedure TForm1.calcularClick(Sender: TObject);
var
V1,V2,V3:Real;
begin
Memo1.lines.add(   'Valor inicial...:'+CalcList.Values[box_varlist.Text]);
V1:=GetStringValue(box_varlist.Text);
V2:=StrToFloat(Edit_CalcVal.Text);

if box_operation.ItemIndex=0 then
begin
   Memo1.lines.add('Valor a somar...:'+Edit_CalcVal.Text);
   V3:=V1+V2;
end;

if box_operation.ItemIndex=1 then
begin
   Memo1.lines.add('Valor a subtrair:'+Edit_CalcVal.Text);
   V3:=V1-V2;
end;
setStringValue(box_varlist.Text,V3);
ListBox1.Items.Values[box_varlist.Text]:=FloatToStr(V3);
V1:=GetStringValue(box_varlist.Text);
Memo1.lines.add(' *-*-* Resultado='+FloatToStr(V1));
Memo1.lines.add(' ');

end;

function TForm1.GetStringValue(svVar:string):Real;
begin
Result:=StrtoFloat(CalcList.Values[svVar]);
end;

procedure TForm1.setStringValue(svVar:string;svValue:Real);
begin
CalcList.Values[svVar]:=FloatToStr(svValue);
end;

procedure TForm1.Criar_variavelClick(Sender: TObject);
begin
CalcList.Values[edit_var1.Text]:=edit_valor1.Text;
box_varlist.Items.Add(edit_var1.Text);
ListBox1.Items.Values[edit_var1.Text]:=edit_valor1.Text;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
CalcList:=TStringlist.Create;
Memo1.lines.Clear;
box_operation.ItemIndex:=-1;
box_varlist.ItemIndex:=-1;
end;

end.


A tela do nosso programinha, deve ficar assim:




Download dos Fontes:

Faça o download dos fontes aqui


Até a próxima.