Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   ¿Cómo simular de "verdad" las teclas SHIFT+TAB? (https://www.clubdelphi.com/foros/showthread.php?t=75807)

roman 20-09-2011 21:54:35

Cita:

Empezado por escafandra (Mensaje 412780)
Pues el código que puse, en mi delphi 7 no hace cosas raras, no creo haber añadido nada mas que activar la tecla tab para que funcione como dice Casimiro. :confused:

Tu código funciona bien, pero no al mezclarlo con el código del evento SelectCell de Casimiro. Al menos a mi no me ha funcionado tal cual.

Bueno, este último no lo he probado.

// Saludos

Casimiro Noteví 20-09-2011 23:59:22

Bueno, he hecho unas pruebas y el código de Román funciona bien :). Me he encontrado con un problema añadido, que ya está solucionado, cuando pulsaba enter sobre una celda para editarla, se quedaba el texto seleccionado, así que si intentaba teclear algo... se perdía lo que había. Un mal menor que ya está solucionado.

Escafandra, el código que has puesto creo que necesita algo más que no has puesto, me da error en la línea:
Código Delphi [-]
Input.Tipo:= INPUT_KEYBOARD;

Dice que no sabe qué es 'Tipo'. Hay otra propiedad, IType, o algo así, será esa la que hay que poner, ¿no?

escafandra 21-09-2011 00:17:56

Ciertamente no había probado con el evento OnSelectCell que proponía Casimiro. Claro, el problema está en el evento. Cuando pulsamos Shift está pulsado constantemente, pero cuando lo simulamos lo despulsamos. Así al retroceder a una celda prohibida se simula un TAB sin Shift y se para...

Cita:

Empezado por Casimiro Notevi (Mensaje 412795)
Escafandra, el código que has puesto creo que necesita algo más que no has puesto, me da error en la línea:
Código Delphi [-]
Input.Tipo:= INPUT_KEYBOARD;

Dice que no sabe qué es 'Tipo'. Hay otra propiedad, IType, o algo así, será esa la que hay que poner, ¿no?

Si..., Casimiro. La documentación de MS define así:
Código:

typedef struct tagINPUT {
  DWORD type;
  union {
    MOUSEINPUT    mi;
    KEYBDINPUT    ki;
    HARDWAREINPUT hi;
  };
} INPUT, *PINPUT;

Pero type es una palabra reservada en Delphi así que hice una conversión que olvidé publicar:
Código Delphi [-]
type
  TINPUT = record
  Tipo: DWORD;
  case integer of
    0: (mi: TMOUSEINPUT);
    1: (ki: TKEYBDINPUT);
    2: (hi: THARDWAREINPUT);
  end;  PTINPUT = ^TINPUT;
Ahora me doy cuenta de que en la unidad windows está definida la estructura y le dan el nombre de iType. Ese es el nombre que debes usar.


Saludos.

roman 21-09-2011 04:13:07

Cita:

Empezado por Casimiro Notevi (Mensaje 412795)
Me he encontrado con un problema añadido, que ya está solucionado, cuando pulsaba enter sobre una celda para editarla, se quedaba el texto seleccionado, así que si intentaba teclear algo... se perdía lo que había. Un mal menor que ya está solucionado.

De la otra guía de estilo:

Cita:

Si encuentras la solución tú mismo, no te molestes en explicarla. Bastará con un "Ya lo resolví, gracias". Nos emociona ver gente autosuficiente.
:D

// Saludos

newtron 21-09-2011 08:59:54

A ver..... sigo soltando tonterías. :D

De una forma o de otra creo que mi componente heredado del stringrid funciona como tú quieres, si quieres te lo envío y le echas un vistazo, aunque aviso que tiene un rato de conversación. :)

Saludos

gluglu 21-09-2011 09:45:02

Hola !

Voy a tomar parte de este hilo, aunque yo no use el TStringGrid sino el StringGrid de TMS.

En cualquier caso tampoco se me ha planteado todavía la necesidad de realizar la acción que comenta Casimiro.

Con toda humildad, no entiendo la problemática de este hilo.

He realizado pruebas muy básicas para cerciorarme de que lo que pensaba era más o menos así, y creo que he podido comprobar que si funciona como pienso. No he terminado el código pero expongo la idea.

El StringGrid tiene el evento OnKeyPress en el cual puedes 'interceptar' las teclas del cursor Izquierda y Derecha.

Basta con que muevas la posición Col y Row del StringGrid :

StringGrid1.Col := StringGrid1.Col + 1; (o - según Der o Izq)

Una vez que te posiciones, compruebas si la celda es editable o no, y si no lo es aumentas la posición de la columna. Al comprobar que llegas a la última columna y pulsas derecha, vuelves a la 1a columna pero con 1 fila más, y así sucesivamente.

No veo la necesidad de utilizar la función Keyb_Event.

A lo mejor me equivoco, claro está .....

P.D. Al menos en la prueba con un TStringGrid que acabo de hacer, además me funcionan las teclas del cursor 'en cierta manera' como se indica en este hilo. Hacia la derecha va bien, hasta la última columna, pero hacia la izquierda me edita cada celda antes de pasar a la celda anterior.

Casimiro Noteví 21-09-2011 13:44:42

Cita:

Empezado por roman (Mensaje 412812)
De la otra guía de estilo: :D
// Saludos

perdón, es que soy novato, pero prometo leer esa guía de los estilos :)

Sólo añadí una variable booleana más y añadí lo siguiente al evento KeyDown:

Código Delphi [-]
  if Key = VK_RETURN then
  begin
    if not bEditandoCelda then
    begin
      keybd_event(VK_F2, 0, 0, 0);
      keybd_event(VK_F2, 0, KEYEVENTF_KEYUP, 0);
      //
      Key := 0;
      //
    end;
    bEditandoCelda := not bEditandoCelda;
  end;

De esta manera al pulsar "enter" la primera vez se simula F2 y pasa a editar poniendo el cursor al final del texto que exista en la celda.
La siguiente vez que se pulsa "enter" se ejecuta normalmente y "acepta" el contenido.
La siguiente vez... vuelta a empezar.


Cita:

Empezado por newtron (Mensaje 412820)
A ver..... sigo soltando tonterías. :D
De una forma o de otra creo que mi componente heredado del stringrid funciona como tú quieres, si quieres te lo envío y le echas un vistazo, aunque aviso que tiene un rato de conversación. :)
Saludos

Se agradece, envíamelo, habrá que echarle un vistazo, mientras tenga el código fuente y no me cobres muy caro :).

Cita:

Empezado por gluglu (Mensaje 412822)
Hola !
P.D. Al menos en la prueba con un TStringGrid que acabo de hacer, además me funcionan las teclas del cursor 'en cierta manera' como se indica en este hilo. Hacia la derecha va bien, hasta la última columna, pero hacia la izquierda me edita cada celda antes de pasar a la celda anterior.

Gracias gluglu, esa opción fue la primera que se me ocurrió, pero no terminaba de "estabilizarse", ocurrían cosas como las que cuentas y si lo solucionaba entonces salían otros efectos colaterales :), por lo que decidí dejarlo.

escafandra 21-09-2011 13:53:55

Cita:

Empezado por gluglu (Mensaje 412822)
....No veo la necesidad de utilizar la función Keyb_Event.

A lo mejor me equivoco, claro está .....

No te equivocas, evidentemente se puede realizar de muchas formas. Yo entiendo que Casimiro pretende usar las teclas de cursor y la previamente establecida con VK_TAB combinada con VK_SHIF. Ese es el motivo por el que quiso simular la pulsación de teclas y el título del hilo.

Evidentemente podemos capturar en el evento OnKeyDown todas las teclas en juego (VK_TAB, VK_SHIF, VK_LEFT y VK_RIGHT) y mover el foco como tu comentas ;).

PD: Veo que Casimiro comenta sus motivos.

Saludos.

Casimiro Noteví 21-09-2011 13:59:39

A veces, las cosas más sencillas (aparentemente) son las que más tiempo llevan, se complican de una manera absurda con pequeños detalles que no terminan de quedar bien. Solucionamos un detalle y aparece otro, y así sucesivamente hasta que por fin lo tienes ¿todo? controlado.
Cuando te das cuenta, resulta que has perdido un montón de tiempo, pero es lo que tiene cuando quieres hacer algo decente.

roman 21-09-2011 15:17:21

Cita:

Empezado por roman (Mensaje 412738)
...me parece que sería mejor intentar no simular esas teclas y manipular los valores de Col y Row en el evento KeyDown.

Cita:

Empezado por gluglu (Mensaje 412822)
El StringGrid tiene el evento OnKeyPress en el cual puedes 'interceptar' las teclas del cursor Izquierda y Derecha.

Basta con que muevas la posición Col y Row del StringGrid :

StringGrid1.Col := StringGrid1.Col + 1; (o - según Der o Izq)

Una vez que te posiciones, compruebas si la celda es editable o no, y si no lo es aumentas la posición de la columna. Al comprobar que llegas a la última columna y pulsas derecha, vuelves a la 1a columna pero con 1 fila más, y así sucesivamente.

No veo la necesidad de utilizar la función Keyb_Event.

Si es lo que yo decía :) Pero como estaba empecinado con el TAB pues también seguí por ese camino.

Toma en cuenta, eso sí, como menciona escafandra, que debes manejar no sólo las teclas LEFT y RIGHT sino también UP, DOWN, PRIOR, NEXT, TAB, o sea, todas las que muevan el cursor del teclado con lo cual prácticamente estás rehaciendo la lógica del movimiento y en ese punto uno se pone a pensar que la idea de Casimiro no es mala pues se termina escribiendo, quizá, menos código.

// Saludos

Casimiro Noteví 21-09-2011 15:34:52

Al principio lo intenté controlando las teclas de flechas, y aunque parece lo más simple, sin embargo no terminaba de funcionar bien, entonces por casualidad vi que las teclas tab y shift+tab funcionaban perfectamente en la misma situación que las teclas normales no terminaban por hacer bien su cometido. Y fue cuando me dije, "pues mejor simulo que he pulsado esas teclas (tab y shift+tab) y se acabó", más fácil, me ahorro de estar controlando las otras teclas.
Ese fue el motivo.
Pero si con las teclas de flechas hubiese ido bien, ese sistema es el que habría usado de primera hora.
Que no digo que vaya mal, sino que no acababa por ir bien del todo, seguramente estaba haciendo algo mal, no lo sé.

newtron 21-09-2011 16:19:52

Cita:

Empezado por Casimiro Notevi (Mensaje 412830)
Se agradece, envíamelo, habrá que echarle un vistazo, mientras tenga el código fuente y no me cobres muy caro :).

Pues vale, ¿cómo te lo mando?.

Casimiro Noteví 21-09-2011 16:27:48

Pincha en mi nombre junto al avatar y te saldrá un menú con la opción de "Enviar correo a casimiro".

newtron 21-09-2011 16:32:17

Cita:

Empezado por Casimiro Notevi (Mensaje 412857)
Pincha en mi nombre junto al avatar y te saldrá un menú con la opción de "Enviar correo a casimiro".

Vale, eso ya lo imaginaba :D, pero no veo opción para adjuntar ficheros.

roman 21-09-2011 16:42:52

También podrías hacerlo "open source" y publicarlo aquí en este hilo o en el FTP :p

// Saludos

newtron 21-09-2011 17:01:43

Cita:

Empezado por roman (Mensaje 412862)
También podrías hacerlo "open source" y publicarlo aquí en este hilo o en el FTP :p

// Saludos

Ningún problema, lo único es que este componente está integrado con otra docena de ellos y todos intimamente ligado a la base de datos que uso así que de poco iba a servir a no ser para consultar el código. :)

Casimiro Noteví 21-09-2011 19:50:52

Cita:

Empezado por newtron (Mensaje 412863)
Ningún problema, lo único es que este componente está integrado con otra docena de ellos y todos intimamente ligado a la base de datos que uso así que de poco iba a servir a no ser para consultar el código. :)

uuufff... lo he estado mirando un poco y eso no es un TStringGrid "normal", es un grid creado a mano que hereda de TComponent e incluye opciones para bases de datos también. Es más bien un TDBGrid. O una mezcla :)
Bastante completo y, como dices tú, muy adaptado para las necesidades de tus programas. Si tiene cerca de 5.000 líneas de código, así que no lo he leído entero :)
Me servirá para consultar algunas cosillas, eso sí. Gracias.

newtron 22-09-2011 16:57:29

Cita:

Empezado por Casimiro Notevi (Mensaje 412887)
...así que no lo he leído entero ..

Me ofendes. :p

Casimiro Noteví 22-09-2011 17:47:09

Cita:

Empezado por newtron (Mensaje 413025)
Me ofendes. :p

Tranquilo, en cuanto acabe el libro que estoy leyendo, empezaré con el tuyo :)


La franja horaria es GMT +2. Ahora son las 18:08:01.

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