[Lazarus-es] [Fpc] Refresh no funciona

francisco prieto fajprieto en gmail.com
Jue Ago 6 14:54:06 CEST 2015


Creo que estoy mas cerca, aunque ahora da otro error...

Les cuento los cambios que hice...

1) Agregue la propiedad publica lcLectura a la clase TMiHilo

    TMiHilo = class(TThread)
    private
      fStatusText: string;
      procedure MostrarPeso;
    protected
      procedure Execute; override;
    public
      lcLectura:string;
      constructor Create(CreaSuspendido: boolean);
    end;

2) Modifique el contenido de UpdPeso, ahora solo crea el hilo y le pasa la
lectura recibida de la balanza... esa que como les comente en la otra
pantalla la muestro en una lista.

procedure TfrmPesaje.UpdPeso(cLectura:String);
var
  MiHilo : TMiHilo;
begin
     //creamos el hilo, pero no lo iniciamos
     MiHilo := TMiHilo.Create(True); // Con el parametro true no se inicia
automaticamente
     if Assigned(MiHilo.FatalException) then
        raise MiHilo.FatalException;
     //si no hay ninguna excepción lo iniciamos
     MiHilo.lcLectura:=cLectura;
     MiHilo.Start;
end;

3) Modifique el contenido de MostrarPeso en MiHilo, para que contenga todo
el analisis de la trama y lo muestre por pantalla.

procedure TMiHilo.MostrarPeso;
var
  lcTramas:TStringList;
  lnNeto,lnNegativo,lnFueraRango,lnFueraEqui,lnTeclaAd,lnCantTramas:integer;
  lcEstadoA,lcEstadoB,lcEstadoC,lcPeso,lcTara,lcDecimales:string;
  lnPesoTara,lnPesoTot:real;
  lnPesoComa:integer;
begin
  lcEstadoA:='';
  lcEstadoB:='';
  lcEstadoC:='';
  lcPeso:='';
  lcTara:='';
  lcTramas:= TStringList.Create;
  Split('|', lcLectura, lcTramas);
  lnCantTramas:=lcTramas.count;
  if lnCantTramas=5 then
     begin
       lcEstadoA:=lcTramas.Strings[1];
       lcEstadoB:=lcTramas.Strings[2];
       lcEstadoC:=lcTramas.Strings[3];
       lcPeso:=copy(lcTramas.Strings[4],1,6);
       lcTara:=copy(lcTramas.Strings[4],7,6);
       {Analisis Estado A}
       lcEstadoA:=HextoBin(lcEstadoA);
       lcDecimales:=copy(lcEstadoA,6,3);
       case lcDecimales of
            '010':lnPesoComa:=0;
            '011':lnPesoComa:=1;
            '100':lnPesoComa:=2;
            '101':lnPesoComa:=3;
            '110':lnPesoComa:=4;
       else
            lnPesoComa:=0;
       end;
       {Analisis Estado B}
       lcEstadoB:=HextoBin(lcEstadoB);
       lnNeto:=StrToInt(copy(lcEstadoB,8,1));
       lnNegativo:=StrToInt(copy(lcEstadoB,7,1));
       lnFueraRango:=StrToInt(copy(lcEstadoB,6,1));
       lnFueraEqui:=StrToInt(copy(lcEstadoB,5,1));
       {Analisis Estado C}
       lcEstadoC:=HextoBin(lcEstadoC);
       lnTeclaAd:=StrToInt(copy(lcEstadoB,5,1));
       {Calculos Finales}
       lnPesoTara:=StrToInt(lcTara)/(Exp(LN(10)*lnPesoComa));
       lnPesoTot:=StrToInt(lcPeso)/(Exp(LN(10)*lnPesoComa));
       if lnNegativo=1 then
          lnPesoTot:=lnPesoTot*(-1);
       frmPesaje.txtPesoAct.Text:=FloatToStr(lnPesoTot);
       frmPesaje.txtPesoAct.Refresh;
   end;
end;

Todo eso compila fantastico pero al ejecutar da el siguiente error:

Thread creation error: Espacio de almacenamiento insuficiente para procesar
este comando

constructor TMiHilo.Create(CreaSuspendido: boolean);
begin
  FreeOnTerminate := True;
  inherited Create(CreaSuspendido); <== aca da el error
end;

Espero sus comentario, y de paso invenstigo.

Saludos,

Pancho
Córdoba
Argentina

El 6 de agosto de 2015, 8:02, francisco prieto <fajprieto en gmail.com>
escribió:

> Maxi, eso seguramente funciona, pero eso no me sirve porque la cadena que
> envía la balanza hay que analizarla, pues no solo trae el peso, trae otros
> estados que me son de utilidad.
>
> Ademas subi el procedimiento que funciona
> TfrmCheck.olePuertoRxData(Sender: TObject); y el que no....
>
> y la diferencia entre ambos es justamente esa..., es decir en el caso que
> funciona, lectura a lectura lo voy tirando en una lista en pantalla y al
> refresco le da el cuero y eso que mi maquina es un avión con acoplado...
>
> en cambio, si analizo la cadena, son tantas las lecturas que entran por
> olePuertoRxData que no logra refrescar.
>
> En VFP existe algo denominado AutoYield para estos casos que va procesando
> en la medida que puede cada una de las peticiones y también existe el
> DoEvents, aquí veo que existe algo parecido denominado
> application.ProcessMessages pero tampoco funciona...
>
> Lo que creo que solucionaría el problema es...
>
> recibir la data de olePuertoRxData en un hilo por separado cada vez...
> procesar el hilo
> y cada proceso que actualice la pantalla...
>
> Eso es lo que voy a intentar el dia de hoy...
>
> Los mantengo al tanto, pues esto se esta transformando en un error muy
> interesante de estudiar.
>
> Saludos,
>
> Pancho
> Córdoba
> Argentina
>
>
>
> El 5 de agosto de 2015, 20:54, Martin Gomez <mmgomez en gmail.com> escribió:
>
>> Con el Sincronize(UpdPeso) tampoco? Eso debería aislarte del
>> multithreading interno de LazSerial (si es que tiene)
>>
>> 2015-08-05 13:54 GMT-03:00 francisco prieto <fajprieto en gmail.com>:
>>
>>> En primer lugar gracias a todos por responder...
>>>
>>> En segundo lugar el proceso monitorea con LazSerial el peso en una
>>> balanza que escupe muy rapido cada lectura.
>>>
>>> En tercer lugar como dije hice el proceso de comunicacion utilizando el
>>> evento OnRxData y si envio la data que recibo a un ListBox funciona sin
>>> inconvenientes...
>>>
>>> El siguiente es el codigo que funciona contra el ListBox.
>>>
>>> procedure TfrmCheck.olePuertoRxData(Sender: TObject);
>>> var
>>>   lcLecturaReal,lcLetra:string;
>>>   i:integer;
>>> begin
>>>      lcLecturaReal:=  olePuerto.ReadData;
>>>        for i := 1 to Length(lcLecturaReal) do
>>>           begin
>>>              lcLetra:=InttoHex(Ord(lcLecturaReal[i]),2);
>>>              lcLecturaHex := lcLecturaHex + lcLetra+ ' ';
>>>              case lcLetra of
>>>                   '30'..'39':
>>>                   begin
>>>                        lcLetra:=RightStr(lcLetra,1);
>>>                        lcLecturaTotal := lcLecturaTotal + lcLetra;
>>>                   end;
>>>                   '0D':
>>>                   begin
>>>                      lcLecturaTotal := lcLecturaTotal + 'CR';
>>>                      if (cboBalanza.KeyValue=1) then
>>>                         begin
>>>                           lcLecturaTotal := lcLecturaTotal +'LF';
>>>                           if chkAuditaCom.Checked=True then
>>>                             UpdLog(lcLecturaTotal);
>>>                           lstTrama.Items.Add(lcLecturaTotal);
>>>                           lcLecturaTotal:='';
>>>                         end;
>>>                   end;
>>>                   '0A':
>>>                   begin
>>>                        lcLecturaTotal := lcLecturaTotal +'LF';
>>>                        if chkAuditaCom.Checked=True then
>>>                          UpdLog(lcLecturaTotal);
>>>                        lstTrama.Items.Add(lcLecturaTotal);
>>>                        lcLecturaTotal:='';
>>>                   end;
>>>              else
>>>                 begin
>>>                      if (lcLetra='02') and (Length(lcLecturaTotal)>0)
>>> then
>>>                        begin
>>>                          if chkAuditaCom.Checked=True then
>>>                            UpdLog(lcLecturaTotal);
>>>                          lstTrama.Items.Add(lcLecturaTotal);
>>>                          lcLecturaTotal:='';
>>>                        end;
>>>                      if (lcLetra='02') then
>>>                         lcLetra:='STX'
>>>                      else
>>>                         lcLetra:='|'+lcLetra+'|';
>>>                      lcLecturaTotal := lcLecturaTotal + lcLetra;
>>>                 end;
>>>              end;
>>>           end;
>>>          if chkAuditaCom.Checked=True then
>>>             UpdLog(lcLecturaHex);
>>>          edtRecepcion.Lines.Add(lcLecturaHex);
>>> end;
>>>
>>> Es mas si revisan hay un listbox y un memo recibiendo la info al mismo
>>> tiempo... pero claro la info en esta instancia no se analiza porque es un
>>> simple programa de comunicacion para comprobar que la comunicacion
>>> funciona...
>>>
>>> Ahora bien ese mismo metodo lo repeti en la pantalla que debe analizar
>>> la trama y cambia a esto otro
>>>
>>> procedure TfrmPesaje.olePuertoRxData(Sender: TObject);
>>> var
>>>   lcLecturaReal,lcLecturaHex,lcLecturaTotal,lcLetra:string;
>>>   i:integer;
>>> begin
>>>   lcLecturaHex:='';
>>>   lcLecturaTotal:='';
>>>   lcLecturaReal:=  olePuerto.ReadData;
>>>     for i := 1 to Length(lcLecturaReal) do
>>>        begin
>>>           lcLetra:=InttoHex(Ord(lcLecturaReal[i]),2);
>>>           lcLecturaHex := lcLecturaHex + lcLetra+ ' ';
>>>           case lcLetra of
>>>                '30'..'39':
>>>                begin
>>>                     lcLetra:=RightStr(lcLetra,1);
>>>                     lcLecturaTotal := lcLecturaTotal + lcLetra;
>>>                end;
>>>                '0D':
>>>                begin
>>>                   lcLecturaTotal := lcLecturaTotal + 'CR';
>>>                   if (cboBalanza.KeyValue=1) then
>>>                      begin
>>>                        lcLecturaTotal := lcLecturaTotal +'LF';
>>>                        if llAuditaCom=True then
>>>                          UpdLog(lcLecturaTotal);
>>>                        UpdPeso(lcLecturaTotal);
>>>                        lcLecturaTotal:='';
>>>                      end;
>>>                end;
>>>                '0A':
>>>                begin
>>>                     lcLecturaTotal := lcLecturaTotal +'LF';
>>>                     if llAuditaCom=True then
>>>                       UpdLog(lcLecturaTotal);
>>>                     UpdPeso(lcLecturaTotal);
>>>                     lcLecturaTotal:='';
>>>                end;
>>>           else
>>>              begin
>>>                   if (lcLetra='02') and (Length(lcLecturaTotal)>0) then
>>>                     begin
>>>                       if llAuditaCom=True then
>>>                         UpdLog(lcLecturaTotal);
>>>                       UpdPeso(lcLecturaTotal);
>>>                       lcLecturaTotal:='';
>>>                     end;
>>>                   if (lcLetra='02') then
>>>                      lcLetra:='STX'
>>>                   else
>>>                      lcLetra:='|'+lcLetra+'|';
>>>                   lcLecturaTotal := lcLecturaTotal + lcLetra;
>>>              end;
>>>           end;
>>>        end;
>>>       if llAuditaCom=True then
>>>          UpdLog(lcLecturaHex);
>>> end;
>>>
>>> Si revisan el cambio es minimo ya que en vez de agregar la lectura al
>>> ListBox o al Memo, envio la lectura como argumento al UpdPeso
>>>
>>> Y UpdPeso funciona sin inconveniente, cuyo codigo es el siguiente:
>>>
>>>
>>> procedure TfrmPesaje.UpdPeso(cLectura:String);
>>> var
>>>   lcTramas:TStringList;
>>>
>>> lnIndice,lnNeto,lnNegativo,lnFueraRango,lnFueraEqui,lnTeclaAd,lnCantTramas:integer;
>>>
>>> lcEstadoA,lcEstadoB,lcEstadoC,lcPeso,lcTara,lcDecimales,lcLectura:string;
>>> begin
>>>   lcEstadoA:='';
>>>   lcEstadoB:='';
>>>   lcEstadoC:='';
>>>   lcPeso:='';
>>>   lcTara:='';
>>>   lcTramas:= TStringList.Create;
>>>   Split('|', cLectura, lcTramas);
>>>   lnCantTramas:=lcTramas.count;
>>>   if lnCantTramas=5 then
>>>      begin
>>>        lcEstadoA:=lcTramas.Strings[1];
>>>        lcEstadoB:=lcTramas.Strings[2];
>>>        lcEstadoC:=lcTramas.Strings[3];
>>>        lcPeso:=copy(lcTramas.Strings[4],1,6);
>>>        lcTara:=copy(lcTramas.Strings[4],7,6);
>>>        {Analisis Estado A}
>>>        lcEstadoA:=HextoBin(lcEstadoA);
>>>        lcDecimales:=copy(lcEstadoA,6,3);
>>>        case lcDecimales of
>>>             '010':lnPesoComa:=0;
>>>             '011':lnPesoComa:=1;
>>>             '100':lnPesoComa:=2;
>>>             '101':lnPesoComa:=3;
>>>             '110':lnPesoComa:=4;
>>>        else
>>>             lnPesoComa:=0;
>>>        end;
>>>        {Analisis Estado B}
>>>        lcEstadoB:=HextoBin(lcEstadoB);
>>>        lnNeto:=StrToInt(copy(lcEstadoB,8,1));
>>>        lnNegativo:=StrToInt(copy(lcEstadoB,7,1));
>>>        lnFueraRango:=StrToInt(copy(lcEstadoB,6,1));
>>>        lnFueraEqui:=StrToInt(copy(lcEstadoB,5,1));
>>>        {Analisis Estado C}
>>>        lcEstadoC:=HextoBin(lcEstadoC);
>>>        lnTeclaAd:=StrToInt(copy(lcEstadoB,5,1));
>>>        {Calculos Finales}
>>>        lnPesoTara:=StrToInt(lcTara)/(Exp(LN(10)*lnPesoComa));
>>>        lnPesoTot:=StrToInt(lcPeso)/(Exp(LN(10)*lnPesoComa));
>>>        if lnNegativo=1 then
>>>           lnPesoTot:=lnPesoTot*(-1);
>>>       end;
>>> end;
>>>
>>> El valor que quiero mostrar se almacena en la propiedad del formulario
>>> lnPesoTot,
>>>
>>> Entiendo que con este link
>>> http://wiki.freepascal.org/Multithreaded_Application_Tutorial/es
>>> debería  implementar un hilo con el procedimiento UpdPeso, o quizas un
>>> hilo que sea llamado desde el procedimiento UpdPeso.
>>>
>>> Hasta ahora por mas que lo estudio no logro entender como se hace eso,
>>> porque entiendo que mi caso es este...
>>>
>>> Type
>>>     TForm1 = class(TForm)
>>>       Button1: TButton;
>>>       Label1: TLabel;
>>>       procedure FormCreate(Sender: TObject);
>>>       procedure FormDestroy(Sender: TObject);
>>>     private
>>>       { private declarations }
>>>       MyThread: TMyThread;
>>>       procedure ShowStatus(Status: string);
>>>     public
>>>       { public declarations }
>>>     end;
>>>
>>>   procedure TForm1.FormCreate(Sender: TObject);
>>>   begin
>>>     inherited;
>>>     MyThread := TMyThread.Create(true);
>>>     MyThread.OnShowStatus := @ShowStatus;
>>>   end;
>>>
>>>   procedure TForm1.FormDestroy(Sender: TObject);
>>>   begin
>>>     MyThread.Terminate;
>>>     MyThread.Free;
>>>     inherited;
>>>   end;
>>>
>>>   procedure TForm1.Button1Click(Sender: TObject);
>>>   begin
>>>    MyThread.Resume;
>>>   end;
>>>
>>>   procedure TForm1.ShowStatus(Status: string);
>>>   begin
>>>     Label1.Caption := Status;
>>>   end;
>>>
>>> Pero no se si Deberia reemplazar ShowStatus por UpdPeso y MyThread.Resume colocarlo en el lugar en que coloco UpdPeso...
>>>
>>> Voy a probar asi, ya que ningun otro consejo me dio resultado.
>>>
>>> Saludos y los mantengo al tanto.
>>>
>>> Pancho
>>>
>>> Córdoba
>>>
>>> Argentina
>>>
>>>
>>>
>>> El 5 de agosto de 2015, 13:04, Daniel Sánchez <resetsoftware en gmail.com>
>>> escribió:
>>>
>>>> Lo que comentas es al parecer que cuando pierde el foco el formulario
>>>> en tu caso llamando a showmessage y vuelve es cuando se muestra el dato, en
>>>> todo caso haz un deactivate/activate en tu formulario para que dispare el
>>>> evento refresh del mismo o en todo caso invoca el refresh del formulario.
>>>> Otra cosa después de actualizar tu text y te posicionas en el con el mouse
>>>> o el teclado sigue sin mostrar tus datos nuevos o sigue mostrando los datos
>>>> anteriores.
>>>>
>>>> Saludos
>>>>
>>>> El 4 de agosto de 2015, 11:30, francisco prieto <fajprieto en gmail.com>
>>>> escribió:
>>>>
>>>>> Tengo el siguiente código
>>>>>
>>>>> procedure TfrmPesaje.UpdPeso(cLectura:String);
>>>>> var
>>>>>   lcTramas:TStringList;
>>>>>
>>>>> lnIndice,lnNeto,lnNegativo,lnFueraRango,lnFueraEqui,lnTeclaAd,lnCantTramas:integer;
>>>>>
>>>>> lcEstadoA,lcEstadoB,lcEstadoC,lcPeso,lcTara,lcDecimales,lcLectura:string;
>>>>> begin
>>>>>   lcEstadoA:='';
>>>>>   lcEstadoB:='';
>>>>>   lcEstadoC:='';
>>>>>   lcPeso:='';
>>>>>   lcTara:='';
>>>>>   lcTramas:= TStringList.Create;
>>>>>   Split('|', cLectura, lcTramas);
>>>>>   lnCantTramas:=lcTramas.count;
>>>>>   if lnCantTramas=5 then
>>>>>      begin
>>>>>        lcEstadoA:=lcTramas.Strings[1];
>>>>>        lcEstadoB:=lcTramas.Strings[2];
>>>>>        lcEstadoC:=lcTramas.Strings[3];
>>>>>        lcPeso:=copy(lcTramas.Strings[4],1,6);
>>>>>        lcTara:=copy(lcTramas.Strings[4],7,6);
>>>>>        {Analisis Estado A}
>>>>>        lcEstadoA:=HextoBin(lcEstadoA);
>>>>>        lcDecimales:=copy(lcEstadoA,6,3);
>>>>>        case lcDecimales of
>>>>>             '010':lnPesoComa:=0;
>>>>>             '011':lnPesoComa:=1;
>>>>>             '100':lnPesoComa:=2;
>>>>>             '101':lnPesoComa:=3;
>>>>>             '110':lnPesoComa:=4;
>>>>>        else
>>>>>             lnPesoComa:=0;
>>>>>        end;
>>>>>        {Analisis Estado B}
>>>>>        lcEstadoB:=HextoBin(lcEstadoB);
>>>>>        lnNeto:=StrToInt(copy(lcEstadoB,8,1));
>>>>>        lnNegativo:=StrToInt(copy(lcEstadoB,7,1));
>>>>>        lnFueraRango:=StrToInt(copy(lcEstadoB,6,1));
>>>>>        lnFueraEqui:=StrToInt(copy(lcEstadoB,5,1));
>>>>>        {Analisis Estado C}
>>>>>        lcEstadoC:=HextoBin(lcEstadoC);
>>>>>        lnTeclaAd:=StrToInt(copy(lcEstadoB,5,1));
>>>>>        {Calculos Finales}
>>>>>        lnPesoTara:=StrToInt(lcTara)/(Exp(LN(10)*lnPesoComa));
>>>>>        lnPesoTot:=StrToInt(lcPeso)/(Exp(LN(10)*lnPesoComa));
>>>>>        if lnNegativo=1 then
>>>>>           lnPesoTot:=lnPesoTot*(-1);
>>>>>        {Actualizo campo de Peso Actual}
>>>>>        txtPesoAct.Text:=FloatToStr(lnPesoTot);
>>>>>        txtPesoAct.Refresh;
>>>>>        application.ProcessMessages;
>>>>>      end;
>>>>>
>>>>> Que se ejecuta por cada lectura del puerto serie.
>>>>>
>>>>> txtPesoAct es una caja de texto en la cual pongo el peso de la balanza.
>>>>>
>>>>> Si solo hago el Refresh no se refresca el control...
>>>>> Si le agrego application.ProcessMessages tampoco se refresca el
>>>>> control.
>>>>>
>>>>> El control solo se refresca cuando hago un showmessage desde otro
>>>>> control.
>>>>>
>>>>> Tengo otra pantalla que tiene un codigo similar pero el que recibe la
>>>>> info es una lista, en ese caso funciona sin inconvenientes...
>>>>>
>>>>> Espero sus comentarios.
>>>>>
>>>>> Pancho
>>>>> Córdoba
>>>>> Argentina
>>>>>
>>>>> --
>>>>> Has recibido este mensaje porque estás suscrito al grupo
>>>>> "comunidad-hispana-freepascal" de Grupos de Google.
>>>>> Para anular la suscripción a este grupo y dejar de recibir sus
>>>>> mensajes, envía un correo electrónico a
>>>>> freepascalhispano+unsubscribe en googlegroups.com.
>>>>> Para ver esta conversación en el sitio web, visita
>>>>> https://groups.google.com/d/msgid/freepascalhispano/CAB6XyW1o82vA9sBAtO0LW48Q6qk84jBD9PJFrWXyNJk_datp1w%40mail.gmail.com
>>>>> <https://groups.google.com/d/msgid/freepascalhispano/CAB6XyW1o82vA9sBAtO0LW48Q6qk84jBD9PJFrWXyNJk_datp1w%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>> Para acceder a más opciones, visita https://groups.google.com/d/optout
>>>>> .
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Daniel Sánchez Escobar
>>>> Investigación y Desarrollo
>>>> Reset Software & Sistemas
>>>> Móvil +051-949398047 RPM #948615385
>>>> Trujillo - Perú
>>>>
>>>> P  Sugerimos no imprimir este e-mail a menos que sea absolutamente
>>>> necesario. Protejamos el medio ambiente.
>>>>
>>>> --
>>>> Has recibido este mensaje porque estás suscrito al grupo
>>>> "comunidad-hispana-freepascal" de Grupos de Google.
>>>> Para anular la suscripción a este grupo y dejar de recibir sus
>>>> mensajes, envía un correo electrónico a
>>>> freepascalhispano+unsubscribe en googlegroups.com.
>>>> Para ver esta conversación en el sitio web, visita
>>>> https://groups.google.com/d/msgid/freepascalhispano/CA%2BEDH_V%3DY2gOs66FZKPtHzCW6rhuyW-29z2rkosiMR5eB0r3-Q%40mail.gmail.com
>>>> <https://groups.google.com/d/msgid/freepascalhispano/CA%2BEDH_V%3DY2gOs66FZKPtHzCW6rhuyW-29z2rkosiMR5eB0r3-Q%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>>> Para acceder a más opciones, visita https://groups.google.com/d/optout.
>>>>
>>>
>>>
>>> _______________________________________________
>>> Lazarus-es mailing list
>>> Lazarus-es en lists.lazarus.freepascal.org
>>> http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es
>>>
>>>
>>
>>
>> --
>>>> Most good programmers do programming not because they expect to get paid
>> or get adulation by the public, but because it is fun to program.
>> ​ ​
>> *Linus Torvalds*
>>
>> _______________________________________________
>> Lazarus-es mailing list
>> Lazarus-es en lists.lazarus.freepascal.org
>> http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es
>>
>>
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus-es/attachments/20150806/2f5af107/attachment-0002.html>


More information about the Lazarus-es mailing list