Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > FireMonkey
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 22-09-2020
QuiqueSalamanca QuiqueSalamanca is offline
Miembro
 
Registrado: mar 2014
Posts: 35
Poder: 0
QuiqueSalamanca Va por buen camino
Lectura de un código de barras vía TMessage

Buenas a todos!

Espero que la pandemia os esté tratando bien!

Os pongo un poco en antecedentes, para leer un código de barras a través de un lector yo lo hago vía Messages en VCL, el problema es al migrar esta aplicación a FireMonkey (cosas del cliente), soy incapaz de replicar el funcionamiento.

Os pongo un poco de código y os explico, yo en el Main de la aplicación VCL (no dejo abrir la aplicación más de una vez) en el .OnMessage tengo este código, que no hace más que comprobar dos tipos de mensajes, WM_KEYDOWN para apertura de un cajón portamonedas y cambiar el '.' por ',' y comprobar si lo que se pasa es una WM_CHAR entonces ahí procesar el código de barras:


Código:
procedure TfrMain.AppOnMessage( var Msg: TMsg; var Handled: Boolean);
begin  
   if (Msg.message = WM_KEYDOWN) then
   begin
      oMsg.hwnd   := Msg.hwnd;
      oMsg.message:= Msg.message;
      oMsg.wParam := Msg.wParam;
      oMsg.lParam := Msg.lParam;
      oMsg.time   := Msg.time;
      oMsg.pt     := Msg.pt;
      
      if (Msg.wParam = VK_F9) then
      begin
         Handled := True;  // le indicamos a windows que lo procesamos
                           // nosotros y no queremos que llege a la aplicación
         if Assigned(OdaDisplay) then
         begin
            try
               OdaDisplay.ClearDisplay;
               OdaDisplay.OpenBoxNew;
            except
            end;   
         end;   
      end
      else if Msg.wParam = VK_DECIMAL then
      begin
         PostMessage( Msg.Hwnd, wm_Char, Ord(','), 0 );
         Handled := True;
      end
      else
         ProcesarMensajeKeyDown( Msg, Handled ); 
   end   
   else if (Msg.message = WM_CHAR) then
      ProcesarMensajeChar( Msg, 
                           Handled, tTimerCodBar, 
                           ParmPerfil.PrefijoLectorCodBar, 
                           ParmPerfil.SufijoLectorCodBar,
                           ParmPerfil.ForzarUpperCase ); 
end;
El procedimiento ProcesarMensajeChar no hace otra cosa que procesa (valga la redundancia) lo que le llega y hace un PostMessage con un mensaje personalizado que controlo para saber que lo que está llegando es un código de barras:

Código:
procedure ProcesarMensajeChar( var Msg: TMsg; 
                               var Handled: Boolean; 
                               tTimer   : TTimer;
                               iPrefijo : Integer;
                               iSufijo  : Integer;
                               bForzarUC: Boolean );
var
   iBarType   : TBarType;
   sCaracter  : Char;
   hOwner     : Hwnd;
   iCodigo    : Integer;
   sBuffer    : string;
   i          : Integer;
   oEdit      : TEdit;
begin
   if (Msg.message = WM_CHAR) then
   begin
      Handled := False;
      
      sCaracter := Chr(Msg.wParam);

      if (iSufijo > 0) or (iPrefijo > 0) then
      begin
         if DebugCodBarKeyChar and not DebugCodBarKeyDown then
         begin
            if sCaracter <> #0 then
               BufferCodBar := sCaracter+Format( '%d', [Msg.wParam] )+' ';
               
            if Assigned(Screen.ActiveForm) then
               PostMessage( Screen.ActiveForm.Handle, um_CodBar, 0, Longint( BufferCodBar ) );

            Handled := True;
         end;   
         if not Handled and LeyendoCodBar then
         begin
            if sCaracter = Chr(iSufijo) then
            begin
               sBuffer := '';
               for i := 1 to Length(BufferCodBar) do
               begin
                  if BufferCodBar[i] = #13 then
                     Continue;
                  sBuffer := sBuffer + BufferCodBar[i];
               end;
               LeyendoCodBar  := False;
               tTimer.Enabled := False;
               
                  // a veces es nil
               if Assigned(Screen.ActiveForm) then
               begin
                  BufferCodBar := TrimRight(sBuffer);
                  PostMessage( Screen.ActiveForm.Handle, um_CodBar, 0, Longint( BufferCodBar ) );
               end;   
            end   
            else
            begin
               BufferCodBar := BufferCodBar + sCaracter;
               if Length(BufferCodBar) = 50 then
               begin
                  LeyendoCodBar  := False;
                  tTimer.Enabled := False;
               
                  if Assigned(Screen.ActiveForm) then
                     SendKeys( PChar(BufferCodBar), True ); // bWait
                     
                  BufferCodBar := '';
              end;    
            end; 
            Handled := True;   
         end   
         else if (sCaracter = Chr(iPrefijo)) then
         begin
            if LeyendoCodBar then
            begin
               if (BufferCodBar > '') and
                  Assigned(Screen.ActiveForm) then
                  SendKeys(PChar(BufferCodBar), True ); // bWait
            end;
            BufferCodBar   := '';
            LeyendoCodBar  := True;
            Handled        := True;
            tTimer.Enabled := True;  // no en desarrollo
            
               // el sufijo es capturado por el control si esta seleccionado
            if (Screen.ActiveControl is TCustomEdit) then
               TCustomEdit(Screen.ActiveControl).SelLength := 0
               
            else if Screen.ActiveControl is TCustomGrid then
               SetSelectNullGrid( TCustomGrid(Screen.ActiveControl) );
         end
         else if bForzarUC then
         begin
            if Assigned(Screen.ActiveControl) then
            begin
               if (Screen.ActiveControl is TEdit) then
               begin
                  oEdit := TEdit(Screen.ActiveControl);
                  if oEdit.CharCase = ecNormal then
                  begin
                     sBuffer    := AnsiUpperCase(sCaracter);
                     Msg.wParam := Ord(sBuffer[1]);
                  end;
               end
               else if not (Screen.ActiveControl is TCustomMemo) and
                       not (Screen.ActiveControl is TCustomDCMemo) and
                       not (Screen.ActiveControl is TCustomEasyEdit) then
               begin
                  sBuffer    := AnsiUpperCase(sCaracter);
                  Msg.wParam := Ord(sBuffer[1]);
               end
            end;            
         end;     
       end;     
    end;  
end;
Con esto consigo que en mis formularios solo tenga que añadir un procedimiento que esté a la espera de un mensaje tipo um_CodBar y ahí proceso la información específica para él.

Ahora ya en FireMonkey me resulta imposible controlar ni siquiera los mensajes que devuelve Windows...

He rebuscado y lo que he encontrado es el TMessageManager, con esto puedo hacer SendMessages y leerlo pero no controlo el dónde lo tengo que hacer cuando leo un código de barras.

La otra posibilidad es ir controlando objeto por objeto en el KeyDown por si lo introducido es un código de barras, porque solo nos interesan que en dos o tres objetos se pueda hacer una lectura.

Con lo fácil que era lo otro :'(

Gracias de antemano!

Saludos,
Quique.
Responder Con Cita
  #2  
Antiguo 22-09-2020
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Deberías leer estos 2 hilos.
Explican el porqué estás teniendo problemas con los mensajes de Windows en tu aplicación.

https://stackoverflow.com/questions/...iremonkey-form
https://stackoverflow.com/questions/...ssage-handling

Recordemos que la Base de FMX es que es una librería para multiplataforma (Windows, iOS, android, Linux,...), por lo tanto no se si tendría mucho sentido implementar el tratamiento de mensajería de Windows.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 23-09-2020
QuiqueSalamanca QuiqueSalamanca is offline
Miembro
 
Registrado: mar 2014
Posts: 35
Poder: 0
QuiqueSalamanca Va por buen camino
Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
Deberías leer estos 2 hilos.
Explican el porqué estás teniendo problemas con los mensajes de Windows en tu aplicación.

https://stackoverflow.com/questions/...iremonkey-form
https://stackoverflow.com/questions/...ssage-handling

Recordemos que la Base de FMX es que es una librería para multiplataforma (Windows, iOS, android, Linux,...), por lo tanto no se si tendría mucho sentido implementar el tratamiento de mensajería de Windows.
Buenos días Neftali.

Toda esa documentación ya me la he mirado (no sé cuantos días llevo con esto), sí, sé que FMX es una librería que no está basada en Windows y por tanto no se parece en nada a VCL, y por eso os pedía ayuda porque ya me estoy quedando bloqueado , para ver cómo podría implementar algo parecido con FMX y así no tener que estar posicionado en un componente de escritura cuando se haga la lectura, sino que se pueda capturar siempre dicha lectura y poder enviarla al formulario activo.
Gracias de nuevo!

Saludos,
Quique.
Responder Con Cita
  #4  
Antiguo 23-09-2020
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
La primera respuesta del segundo link que te he puesto es lo que yo intentaría.
Haz una pequeña prueba a ver si consigues recibir mensajes.
¿Lo has probado? ¿Has conseguido algo?
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #5  
Antiguo 23-09-2020
QuiqueSalamanca QuiqueSalamanca is offline
Miembro
 
Registrado: mar 2014
Posts: 35
Poder: 0
QuiqueSalamanca Va por buen camino
Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
La primera respuesta del segundo link que te he puesto es lo que yo intentaría.
Haz una pequeña prueba a ver si consigues recibir mensajes.
¿Lo has probado? ¿Has conseguido algo?
Hola Neftali, sí, fue lo primero que probé. EDITO: no, no me funcionó muy bien, me capturaba ciertos mensajes (sobre todo de pantalla, 28...) pero no el que necesitaba.

Estoy probando esto: https://francois-piette.blogspot.com...ndows-and.html

A ver sin el hilo, si es capaz de capturarme un mensaje WM_CHAR...

Te voy contando...

Gracias!
Responder Con Cita
  #6  
Antiguo 24-09-2020
QuiqueSalamanca QuiqueSalamanca is offline
Miembro
 
Registrado: mar 2014
Posts: 35
Poder: 0
QuiqueSalamanca Va por buen camino
Buenas a todos,

Con esto de Overbyte, pues he conseguido registrar casi todos los eventos de Windows, menos el que necesito

Me coge bien el WM_KEYDOWN y el WM_KEYUP justo cuando leo un código de barras, obtengo uno de cada uno por cada cifra devuelve el lector, en vez de mandarme un WM_CHAR que no lo consigo manejar, no sé por qué será.

Estoy desistiendo de la idea de manejar mensajes (que al final sería lo más lógico usando FMX) y empezar a controlarlo mirando el prefijo en el KeyDown (ya que los tenemos configurados con un CTRL+B de prefijo) y mirando si lo que se recibe es la tecla CTRL y ésta no está pulsada, sé que es un código de barras.

No sé cómo lo habéis controlado en otras aplicaciones vosotros, si es mejor hacerlo por otro lado o qué.

Saludos,
Quique.
Responder Con Cita
  #7  
Antiguo 25-09-2020
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por QuiqueSalamanca Ver Mensaje
Con esto de Overbyte, pues he conseguido registrar casi todos los eventos de Windows, menos el que necesito

Me coge bien el WM_KEYDOWN y el WM_KEYUP justo cuando leo un código de barras, obtengo uno de cada uno por cada cifra devuelve el lector, en vez de mandarme un WM_CHAR que no lo consigo manejar, no sé por qué será.

¿Has revisado la VCL?
Es posible que no todos los mensajes que le llegan a una aplicación de Windows los esté generando necesariamente el sistema.
En concreto WM_CHA, ¿Puedes comprobar con alguna utilidad que se esté generando realmente?

Estoy pensando que se sea un mensaje que genera alguna unit de la propia VCL.
¿No se si me explico?
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #8  
Antiguo 25-09-2020
QuiqueSalamanca QuiqueSalamanca is offline
Miembro
 
Registrado: mar 2014
Posts: 35
Poder: 0
QuiqueSalamanca Va por buen camino
Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
¿Has revisado la VCL?
Es posible que no todos los mensajes que le llegan a una aplicación de Windows los esté generando necesariamente el sistema.
En concreto WM_CHA, ¿Puedes comprobar con alguna utilidad que se esté generando realmente?

Estoy pensando que se sea un mensaje que genera alguna unit de la propia VCL.
¿No se si me explico?
Sí, lo he revisado y viene declarada la constante en la unit Messages, lo genera Windows con un valor 0x0102, es gracioso la verdad.

He tirado por la calle del medio y buscando he encontrado un par de cosillas que creo que me van a funcionar.

Cuando compruebe que va bien os pongo el código por si a alguien le interesa.

Gracias!
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Restringir lectura código de barras a un Tedit hogol Varios 8 17-10-2012 11:33:36
lectura de codigo de barras edmundo1481 Varios 1 27-01-2008 01:03:59
Codigo de Barras CoCaInE Varios 2 25-11-2006 11:14:45
Tmessage Hotkey hacia aplicacion externa vtdeleon OOP 4 24-09-2005 17:23:25
Codigo Barras novatix Impresión 1 17-02-2004 12:43:25


La franja horaria es GMT +2. Ahora son las 23:20:52.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi