Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > FireMonkey
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 23-02-2017
juniorSoft juniorSoft is offline
Miembro
 
Registrado: abr 2005
Posts: 178
Poder: 19
juniorSoft Va por buen camino
Validar Contenido Portapapeles

Hola de nuevo Amigos,

he creado las siguientes acciones en Firemonkey para copiar y pegar texto pero que su contenido sean números

Código Delphi [-]
procedure TFrmCalculadora.AcCopiarExecute(Sender: TObject);
var
  Clipboard: IFMXClipboardService;
  Value: TValue;
begin
     if TPlatformServices.Current.SupportsPlatformService(IFMXClipboardService,
     IInterface(Clipboard)) then
     begin
       Value := TValue.From<string>(label1.Text);
       Clipboard.SetClipboard(Value);
     end;
end;

procedure TFrmCalculadora.AcPegarExecute(Sender: TObject);
var
  Clipboard: IFMXClipboardService;
  Value: TValue;
begin
  if TPlatformServices.Current.SupportsPlatformService(IFMXClipboardService,
  IInterface(Clipboard)) then
  begin
     Value := Clipboard.GetClipboard;
     label1.Text:=Value.AsString;
   end;
end;

Mi pregunta es como puedo validar la información que tiene el Portapapeles para saber si este contenido es un número de punto flotante y no otro tipo de información.
Responder Con Cita
  #2  
Antiguo 23-02-2017
juniorSoft juniorSoft is offline
Miembro
 
Registrado: abr 2005
Posts: 178
Poder: 19
juniorSoft Va por buen camino
Ya, me respondo y a cualquiera que le pueda ser util

Código Delphi [-]
procedure TFrmCalculadora.AcPegarExecute(Sender: TObject);
var
  Clipboard: IFMXClipboardService;
  Value: TValue;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXClipboardService,
  IInterface(Clipboard)) then
  begin
     Value := Clipboard.GetClipboard;
     if StrToFloatDef(Value.AsString, -0) <> -0 then
         Display.Text:=Value.AsString
     else
        Display.Text:='0';
   end;
   end;
end;

Última edición por juniorSoft fecha: 23-02-2017 a las 20:02:22.
Responder Con Cita
  #3  
Antiguo 23-02-2017
juniorSoft juniorSoft is offline
Miembro
 
Registrado: abr 2005
Posts: 178
Poder: 19
juniorSoft Va por buen camino
Trate de Utilizar

Código Delphi [-]
if value.IsType<.Double> then

pero no funciono
Responder Con Cita
  #4  
Antiguo 24-02-2017
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Mas alla de que lo hayas solucionado, como consejo para el futuro, debes aprender a identificar y aislar los problemas. Osea en este caso, mas que un problema del portapapeles, lo que tenes delante es un problema de validacion de strings. Simplemente debes validar que un string (no importa de donde venga, ingresado por el usuario, una respuesta de un webservice, un campo de una base de datos, el contenido de portapapeles) contenga solo numeros

Y otra cosa es que debes tener cuidado con el tratamiento de numeros de punto flotante, sobre todo para las comparaciones. Esta es la explicacion universal, mientras que este link es mas "Delphi especifico", y esta es la documentacion oficial

En pocas palabras, los numeros de punto flotante no se pueden representar con exactitud. Pueden ocurrir absurdos matematicos como 2.0 = 2.0 --> Evaluando a False

Obviamente hay soluciones al problema, para comparar numeros de coma flotante podes usar las funciones definidas en la unidad System.Math. En particular para saber si un flotante es cero deberias utilizar la funcion System.Math.IsZero. Otros metodos para comparar incluyen System.Math.SameValue y System.Math.CompareValue

Y por ultimo, la solucion mas adecuada a tu problema (es este string un numero de punto flotante?) sea utilizar la funcion System.SysUtils.TryStrToFloat

Esta funcion devuelve un Boolean indicando si el string es un numero de punto flotante, y tambien tiene un parametro de salida con la conversion ya realizada:

Código Delphi [-]
var
  s: string;
  Value: Double;
begin
  s := // obtienes el contenido como string del clipboard
  if TryStrToFloat(s, Value) then
  begin
    // "s" es un string que representa un valor de tipo Double, y la variable Value contiene ese valor
  end
  else
    // "s" no representa un valor de tipo Double; el valor de la variable Value es indefinido
end;
Responder Con Cita
  #5  
Antiguo 24-02-2017
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Cita:
Empezado por juniorSoft Ver Mensaje
Trate de Utilizar

Código Delphi [-]
if value.IsType<.Double> then

pero no funciono

El registro System.Rtti.TValue es un tanto especial, ya que es un "contenedor" de cualquier tipo de datos. Desde objetos, a interfaces, metaclases, punteros, primitivos, otros registros, metodos anonimos..

Ahora bien, dicho "valor" se escribe con un dato de entrada de "cierto tipo", y el metodo IsType<T> lo que hace es comparar el TypeInfo entre lo que le envias como generico y el del valor almacenado.

Un ejemplo practico:

Código PHP:
var
  
vTValue;
begin
  
// inicializamos un TValue con un string
  
:= TValue.From<string>('1234');

  
// la sobrecarga del operador implicito hace posible esta sintaxis tambien
  
:= '1234';

  
Writeln(v.IsType<string>); // --> True
  
Writeln(v.IsType<Integer>); // -- False
end
Lo que te quiero decir es que IsType<T> va a comparar por el valor "raw" internamente almacenado. No realiza ninguna conversion ni ninguna validacion, estas comparando el tipo de datos; y tiene logica puesto que un string no es un Integer, por mucho mas que la conversion en este caso fuera posible
Responder Con Cita
  #6  
Antiguo 24-02-2017
juniorSoft juniorSoft is offline
Miembro
 
Registrado: abr 2005
Posts: 178
Poder: 19
juniorSoft Va por buen camino
Como ultima Interrogante de este caso, sería muy costoso en términos de recursos utilizar el evento onUpdate de la acción para verificar si hay datos en el Portapapeles; en VCL esa acción para el TActionList viene Stadard. Como lo hice funciona bien pero uno siempre trata de hacer las cosas lo mejor que se puede.

Siempre que puedo evito tener que usar este evento para mantener activo/inactivos controles pero en casos como este la opción pegar solo estaría activa si hay algo en el portapapeles y en este caso un número

Definí el OnUpdate de la Acción de la siguiente manera

Cita:
procedure TFrmCalculadora.AcPegarUpdate(Sender: TObject);
var
Clipboard: IFMXClipboardService;
Valueouble;
begin
if TPlatformServices.Current.SupportsPlatformService(IFMXClipboardService,
IInterface(Clipboard)) then
TAction(Sender).Enabled:= TryStrToFloat(Clipboard.GetClipboard.ToString, Value);
end;
Gracias nuevamente AgustinOrtu
Responder Con Cita
  #7  
Antiguo 24-02-2017
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
En realidad el evento TAction.OnUpdate es invocado cuando la aplicación está ociosa. Siempre y cuando no hagas cosas que demoren tiempo dentro de estos eventos no habrá problema. Una posible mejora que no tendrá gran impacto en el código es guardar la referencia al servicio del portapapeles e invocar sobre esa referencia el método GetClipboard

No programes tan defensivamente. Si realmente este evento te genera un problema de performance, recién ahí es el momento de optimizar.
Responder Con Cita
  #8  
Antiguo 24-02-2017
juniorSoft juniorSoft is offline
Miembro
 
Registrado: abr 2005
Posts: 178
Poder: 19
juniorSoft Va por buen camino
Gracias Nuevamente
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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
Validar contenido campo para que no se repita fwhite Conexión con bases de datos 5 07-02-2012 18:14:51
Copiar el contenido de un DBGrid en el Portapapeles GerTorresM Varios 6 28-12-2010 19:35:16
Copiar contenido de Edit->Text al portapapeles de windows JuanErasmo API de Windows 4 22-01-2008 05:44:34
De cómo pueden robarte el contenido del portapapeles en una página Web dec Seguridad 9 02-10-2005 17:05:55
Portapapeles... Perio Varios 3 29-07-2005 17:27:41


La franja horaria es GMT +2. Ahora son las 16:55:19.


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