Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 27-05-2010
Avatar de Chris
[Chris] Chris is offline
Miembro Premium
 
Registrado: abr 2007
Ubicación: Jinotepe, Nicaragua
Posts: 1.678
Poder: 18
Chris Va por buen camino
problemas con las comparaciones "num1 in [num2 .. num3]" en Delphi 2009

Hola compañeros, recurro a ustedes para que me ayuden a aclarar una duda que tengo. Es con respecto a las evaluaciones del tipo "if num1 in [num2 .. num3]" específicamente evaluaciones de rangos. Resulta que ayer estaba escribiendo este algoritmo:

Código Delphi [-]
/ Calcula si el punto donde será dibujado TextToDraw será bajo el puntero del Ratón.
// PARÁMETROS:
//  CanvasHandle:       Handle del canvas donde se está haciendo el dibujo.
//  TextToDraw:         Texto que se va dibujar.
//  ConstrolOrigin:     Punto relativo a la pantalla en donde se inicia el 
//                      control sobre el que se está haciendo el dibujado. 
//                      (Propiedad "ClientOrigin" de TControl).
//  MainRectTopLeft:    Rect principal del canvas
//  ExtraDrawingRect:   Rect del buffered bitmap que se está utilizando para
//                      hacer el dibujado. Rect compuesto de 0's si no se está
//                      usando un buffered bitmap.  
function MouseOverTextCanvas(const CanvasHandle: HDC;
                             const TextToDraw: String;
                             const ControlOrigin: TPoint;
                             const MainRectTopLeft: TRect;
                             const ExtraDrawingRect: TRect): boolean;
var
    CalcRect: TRect;
    TextRect: TRect;
begin

    // calcular el la posición y dimensión del texto a dibujar
    TextRect := Rect((ControlOrigin.X + MainRectTopLeft.Left + ExtraDrawingRect.Left),
                     (ControlOrigin.Y + MainRectTopLeft.Top + ExtraDrawingRect.Top),
                     0, 0);
    CalcRect := Rect(0, 0, 0, 0);
    DrawText(CanvasHandle,
             PChar(TextToDraw),
             Length(TextToDraw),
             CalcRect, DT_CALCRECT);
    TextRect.Right := TextRect.Left + CalcRect.Right;
    TextRect.Bottom := TextRect.Top + CalcRect.Bottom;

    // el problema es con la evaluación en la línea siguiente. Hasta donde llegan
    // mis conocimientos esta evaluación debería funcionar, pero no lo hace
    // en Delphi 2009 sin Updates
    Result := ((Mouse.CursorPos.X in [TextRect.Left .. TextRect.Right]) and
               (Mouse.CursorPos.Y in [TextRect.Top .. TextRect.Bottom]));

end;

El anterior algoritmo es para probar si un texto dibujado está sobre cierta región del Canvas, para dibujar el texto con estilo "Underline" por ejemplo, al estilo Web.

El problema no es con el algoritmo en si, sino es con la evaluación. Ya que luego de quebrarme la cabeza por gran rato modifiqué la anterior evaluación y me quedé con el mismo algoritmo, pero con una evaluación más de principiante :

Código Delphi [-]
function MouseOverTextCanvas(const CanvasHandle: HDC;
                             const TextToDraw: String;
                             const ControlOrigin: TPoint;
                             const MainRectTopLeft: TRect;
                             const ExtraDrawingRect: TRect): boolean;
var
    CalcRect: TRect;
    TextRect: TRect;
    X, L, R, Y, T, B: Integer;
begin

    // calcular el la posición y dimensión del texto a dibujar
    TextRect := Rect((ControlOrigin.X + MainRectTopLeft.Left + ExtraDrawingRect.Left),
                     (ControlOrigin.Y + MainRectTopLeft.Top + ExtraDrawingRect.Top),
                     0, 0);
    CalcRect := Rect(0, 0, 0, 0);
    DrawText(CanvasHandle,
             PChar(TextToDraw),
             Length(TextToDraw),
             CalcRect, DT_CALCRECT);
    TextRect.Right := TextRect.Left + CalcRect.Right;
    TextRect.Bottom := TextRect.Top + CalcRect.Bottom;

    X := Mouse.CursorPos.X;
    Y := Mouse.CursorPos.Y;
    L := TextRect.Left;
    R := TextRect.Right;
    T := TextRect.Top;
    B := TextRect.Bottom;

    Result := (((x >= l) and (x <= r)) and ((Y >= T) and (Y <= B)));

end;

Un dato curioso también, la existencia de las variables X, Y, L, R, T y B se debe a que la anterior evaluación hecha directamente con las variables Mouse.CursorPos y TextRect no funcionaba tampoco.

No sé si es que estoy equivocado sobre la función de in o es que realmente mi suposición de que es un problema de Delphi 2009 es correcta.

Quisiera saber sus opiniones al respecto.

Saludos,
Chris
__________________
Perfil Github - @chrramirez - Delphi Blog - Blog Web
Responder Con Cita
  #2  
Antiguo 27-05-2010
Avatar de Lord Delfos
Lord Delfos Lord Delfos is offline
Miembro
 
Registrado: ene 2008
Ubicación: Tandil, Argentina
Posts: 558
Poder: 17
Lord Delfos Va por buen camino
Me jugaría la cabeza a que es un problema de rango de los conjuntos.

Verás, un conjunto en Delphi tiene un máximo de 255 elementos, porque la estructura interna del conjunto usa 8 bits.

Cuando uno crea un conjunto "al vuelo" (con "[" y "]") si los valores sobrepasan el máximo de 8 bits ocurreo overflow y por eso si uno intenta evaluar valores mayores a 255, pues... no funciona porque los valores fueron truncados.

Por ejemplo:

Código Delphi [-]
var a, b, c: Integer;
begin
  a:= 270;
  b:= 345;
  c:= 30;
  if c in [a..b] then ShowMessage('sí');
end;

Da que 30 está entre 270 y 345 . Eso es porque en realidad el conjunto [a..b] quedó formado por los valores 14 y 89.

Así, si uno hace:

Código Delphi [-]
var a, b, c: Integer;
begin
  a:= 270;
  b:= 345;
  c:= 300;
  if c in [a..b] then ShowMessage('sí');
end;

Va a decir que 300 no está entre 14 y 89, aunque uno pensó que era entre 270 y 345...

EDITO: Esto es en Delphi 7, no sé si los conjuntos de D2009 serán igual.

Última edición por Lord Delfos fecha: 27-05-2010 a las 23:03:55.
Responder Con Cita
  #3  
Antiguo 28-05-2010
Avatar de Chris
[Chris] Chris is offline
Miembro Premium
 
Registrado: abr 2007
Ubicación: Jinotepe, Nicaragua
Posts: 1.678
Poder: 18
Chris Va por buen camino
Gracias Delfos por la explicación. No sabía ese datos de los conjuntos. Seguramente la limitación sigue existiendo en D2009. Aunque no quedé claro porque A queda en 14 y B en 89??????

Saludos,
Chris
__________________
Perfil Github - @chrramirez - Delphi Blog - Blog Web
Responder Con Cita
  #4  
Antiguo 28-05-2010
Avatar de defcon1_es
defcon1_es defcon1_es is offline
Miembro
 
Registrado: mar 2004
Ubicación: Cuenca - España
Posts: 533
Poder: 21
defcon1_es Va por buen camino
Cita:
Empezado por Chris Ver Mensaje
Gracias Delfos por la explicación. No sabía ese datos de los conjuntos. Seguramente la limitación sigue existiendo en D2009. Aunque no quedé claro porque A queda en 14 y B en 89??????

Saludos,
Chris
1) En delphi 2010 persiste esa limitación en los conjuntos. Extraido de la ayuda de Delphi 2010:

Sets
A set is a collection of values of the same ordinal type.
The values have no inherent order, nor is it meaningful for a value to be included twice in a set.

The range of a set type is the power set of a specific ordinal type, called the base type;
that is, the possible values of the set type are all the subsets of the base type, including the empty set.
The base type can have no more than 256 possible values, and their ordinalities must fall between 0 and 255.



2) Se queda entre 14 y 89 porque se trunca el valor (270 - 256 = 14).
Si representas 270 en binario = 100001100, al guardarlo en 8 bits, el digito más significativo se pierde,
y se guarda solo el valor 00001100, que es el 14 en decimal.
__________________
Progress Openedge
https://abevoelker.com/progress_open...dered_harmful/


Delphi forever...

Última edición por defcon1_es fecha: 28-05-2010 a las 18:51:37.
Responder Con Cita
  #5  
Antiguo 28-05-2010
Avatar de Lord Delfos
Lord Delfos Lord Delfos is offline
Miembro
 
Registrado: ene 2008
Ubicación: Tandil, Argentina
Posts: 558
Poder: 17
Lord Delfos Va por buen camino
Satamente, no lo podría haber explicado mejor.
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
El programa se queda "colgado" mientras copia y luego "despierta" NeWsP OOP 5 10-03-2010 23:05:40
Problemas con fechas, cambiar de formato "mm/dd/aaaa" a "dd/mm/aaaa" nurilla Firebird e Interbase 6 18-02-2010 14:40:53
"OBJECT OR CLASS TYPE REQUIRED" en "APPLICATION EXENAME" Xavierator Varios 3 27-10-2008 10:09:50
Necesito llamar a métodos de clases "hija" desde su clase "padre" Flecha OOP 17 20-04-2007 01:03:53
Tiene delphi Problemas con "Pentum M"? akela Varios 4 05-10-2005 01:24:40


La franja horaria es GMT +2. Ahora son las 11:23:18.


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