PDA

Ver la Versión Completa : ¿Cómo simular de "verdad" las teclas SHIFT+TAB?


Casimiro Notevi
20-09-2011, 16:50:52
Hola, me explico:

Tengo un simple TStringGrid, al iniciar está el foco en la primera celda, la fila 1, columna1, ya que la 0,0 es la del título y la de los datos del lado izquierdo.
Si se pulsa la tecla TAB, el foco pasa a la siguiente, fila 1, columna 2. Si se repite la pulsación de TAB pasamos a fila 1, columna 3.
Cuando se pulsa TAB en la última columan de la primera fila entonces el foco pasa a la primera celda de la segunda columna (2,1), y así sucesivamente hasta llegar a la última fila, columna.
Una vez allí, si pulsamos TAB, el foco vuelve al principio, a la celda 1,1. Hasta aquí no he dicho nada que todos sepáis.
Bien, si en lugar de pulsar TAB, decidimos pulsar SHIFT+TAB, el proceso es exactamente el mismo, pero al revés, marcha atrás, del final hacia el principio. Y siempre, en ambos casos, es una "rueda" sin fin.

http://farm7.static.flickr.com/6176/6166396008_826f4c8232.jpg

Bien, lo complicamos un poco, tengo un array bidimensional con las mismas celdas que tiene el Grid, básicamente se ve así:

aCeldas : array of array of boolean;
(false,false,false,false,false,false,false,false,false,false),
(false,false,false,false,false,false,false,false,false,false),
(false,false,false,false,false,false,false,false,false,false),
(false,false,false,false,false,false,false,false,false,false)

Cada posición del array representa una celda del StringGrid anterior.


procedure TFprobando.grTSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
begin
inherited;
if aCeldas[ARow-1,ACol] = false then // si no es editable la celda, entonces pasamos a la siguiente editable
begin
keybd_event(VK_TAB, 0, 0, 0);
keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);
end;
end;


¿Qué hace esto?, fácil, si nos movemos a una celda de StringGrid y en el array aCeldas esa posición está a 'false', simula la tecla TAB y pasa a la siguiente posición.

Todo este "invento" es para que sólo puedan ser editadas unas celdas y otras no, lo mismo existe otra forma mucho más cómoda de hacerlo, pero no se me ha ocurrido o, enfrascado en esto, se me olvidó.

Bien, sigo, cambiamos los valores del array para probarlo:

aCeldas : array of array of boolean;
(false,true,true,false,false,false,true,true,false,false),
(false,false,true,true,true,false,false,false,true,true),
(false,true,true,false,false,false,true,true,false,false),
(false,false,true,true,true,false,false,false,true,true)

Perfecto, si nos movemos con la tecla TAB o con la tecla SHIFT+TAB, funciona perfecto, tanto hacia delante como hacia atrás, se salta las celdas que en el array están a false y sólo se posiciona en las que están a true.
Aunque cuando va hacia atrás no debería de funcionar, viendo el código del evento SelectCell se ve que debería de avanzar, no retroceder, cuando encuentre una posición con valor false :confused:, pero funciona perfecto.
Bien, continuo, lo que quiero es que pulsando las teclas de flechas IZQUIERDA y DERECHA funcione exactamente igual que con las teclas TAB y SHIFT+TAB.
He buscado por los foros y he encontrado diversas formas, pero ninguna de ellas funciona, eso me hace sospechar que no son de "verdad" simuladoras de la pulsación de esas teclas.
Ahora sí, ya termino:
¿Cómo puedo simular de verdad las teclas SHIFT+TAB, para que el resultado sea exactamente igual que pulsando esas teclas?.

¡Ale!, se acabó el rollo :)

roman
20-09-2011, 18:24:24
Perfecto, si nos movemos con la tecla TAB o con la tecla SHIFT+TAB, funciona perfecto, tanto hacia delante como hacia atrás, se salta las celdas que en el array están a false y sólo se posiciona en las que están a true.
Aunque cuando va hacia atrás no debería de funcionar, viendo el código del evento SelectCell se ve que debería de avanzar, no retroceder, cuando encuentre una posición con valor false , pero funciona perfecto.


Supongo que funciona perfecto porque cuando vas hacia atrás y emulas el TAB tienes oprimida la tecla SHIFT.

Ahora bien, no especificas de qué manera estás intentando con las teclas IZQUIERDA y DERECHA. Porque "algo" tienes que hacer, puesto que las teclas de cursor no funcionan en el StringGrid exactamente igual que TAB y SHIFT+TAB (no avanzan ni retroceden de fila cuando se llega a un extremo).

Pero, si usas el evento KeyDown o KeyUp, tendrás que anular (Key := 0) el comportamiento natural o tendrás un doble movimiento. Además, no te funcionaría el retroceso a menos que oprimas SHIFT+LEFT pues aquí lo que se supone que no funciona realmente no funcioona al no tener oprimida la tecla SHIFT.

Yo más o menos lo he podido hacer mandando una doble simulación:


keybd_event(VK_SHIFT, 0, 0, 0);
keybd_event(VK_TAB, 0, 0, 0);
keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);


pero deja algo extraño al teclado pues no recibe el UP del SHIFT. Y si se lo añdo, entonces no funciona.

Por otra parte, lo que quieres lograr, creo que yo no lo haría así. Para empezar, ¿has visto lo que sucede cuando intentas seleccionar una celda con el ratón?

No he probado todavía, pero me parece que sería mejor intentar no simular esas teclas y manipular los valores de Col y Row en el evento KeyDown.

// Saludos

escafandra
20-09-2011, 19:03:23
procedure TForm1.StringGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_LEFT then
begin
keybd_event(VK_SHIFT,0,0,0);
keybd_event(VK_TAB,0,0,0);

keybd_event(VK_SHIFT,0,KEYEVENTF_KEYUP,0);
keybd_event(VK_TAB,0,KEYEVENTF_KEYUP,0);
Key := 0;
end;
if Key = VK_RIGHT then
begin
keybd_event(VK_TAB,0,0,0);
keybd_event(VK_TAB,0,KEYEVENTF_KEYUP,0);
Key := 0;
end;
end;

Saludos.

newtron
20-09-2011, 19:15:49
A ver porque igual suelto una tontería (como casi siempre).

Uno de nuestros componentes (que no he hecho yo) está basado en el StringGrid y nosotros podemos darle propiedades para que se pueda editar o no.

He estado echando un vistazo y veo que el que se pueda editar o no se decide en el evento OnSelectCell. En este evento creo que puedes comprobar si la columna en la que se encuentra se puede editar o no y devolver True o False según te interese.

Igual esto te ayuda en vez de intentar controlar el tema del teclado porque si en vez de desplazarte con el teclado picas con el ratón en una celda que no quieres que se edite ¿qué haces?.

Saludos

Edito: Si que he soltado una tontería, no he leido bien el mensaje y entendía que preguntabas otra cosa, mis disculpas.

roman
20-09-2011, 19:22:41
procedure TForm1.StringGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_LEFT then
begin
keybd_event(VK_SHIFT,0,0,0);
keybd_event(VK_TAB,0,0,0);

keybd_event(VK_SHIFT,0,KEYEVENTF_KEYUP,0);
keybd_event(VK_TAB,0,KEYEVENTF_KEYUP,0);
Key := 0;
end;
if Key = VK_RIGHT then
begin
keybd_event(VK_TAB,0,0,0);
keybd_event(VK_TAB,0,KEYEVENTF_KEYUP,0);
Key := 0;
end;
end;

Saludos.

¡Vaya! Juraría que había hecho eso y no funcionaba, pero sí funciona. Aún así, por lo que dije antes, yo no usaría esto para lograr lo que quiere Casimiro.

// Saludos

escafandra
20-09-2011, 19:24:33
No vi que roman contestó mientras yo tecleaba y que apuntó algunas cosas de lo luego yo plasmé en mi código. Aclarar que las pruebas que he realizado no dejan "atontado al teclado" y funciona bien al seleccionar con el ratón y luego volver a "teclear".

Pruébalo a ver si te sirve.

Saludos.

roman
20-09-2011, 19:24:55
A ver porque igual suelto una tontería (como casi siempre).

Uno de nuestros componentes (que no he hecho yo) está basado en el StringGrid y nosotros podemos darle propiedades para que se pueda editar o no.

He estado echando un vistazo y veo que el que se pueda editar o no se decide en el evento OnSelectCell. En este evento creo que puedes comprobar si la columna en la que se encuentra se puede editar o no y devolver True o False según te interese.

Igual esto te ayuda en vez de intentar controlar el tema del teclado porque si en vez de desplazarte con el teclado picas con el ratón en una celda que no quieres que se edite ¿qué haces?.

Saludos

Ninguna tontería. Con esto se resuelve el problema de inhabilitar la edición. Pero el efecto desplazarse con el cursor saltándose las celdas 0 es bonito :) y sería deseable de lograr.

// Saludos

escafandra
20-09-2011, 19:33:55
Caramba, roman nos vamos pisando los mensajes, tampoco vi que respondias mientras ya estaba realizando otro comentario... :)

Saludos.

roman
20-09-2011, 19:38:26
Je, je. Oye escafandra: algo no me funciona. Creí que sí, pero al poner tu código, el LEFT no me funciona cuando me cruzo con un cero. Por ello había quitado el UP del SHIFT, que es cuando se "atonta" el teclado. ¿Cambiaste algo en el SelectCell?

// Saludos

Casimiro Notevi
20-09-2011, 19:46:58
Para empezar, gracias a todos :)
Veamos, lo que estoy intentando conseguir es que sólamente puedan ser editables las celdas permitidas y además que el cursor ni siquiera pueda detenerse en las celdas no permitidas, de esa manera el usuario no tiene que estar con las teclas (o el ratón) moviéndose por las celdas, ya que él no sabe en cada caso cuales son las editables. Así que si moviéndose con las teclas IZQ y DER se posiciona automáticamente en las celdas válidas el trabajo es más cómodo, más intuitivo, más rápido y no hay equivocaciones.

He probado el código que habéis puesto y el problema es que cuando va hacia atrás y se encuentra una celda no editable... ahí se queda. Sin embargo, pulsando Shift+Tab sí que se la salta y va a la anterior válida/editable. Es por lo que decía que debe de haber otra forma de simular de verdad esa tecla, el comportamiento no es exactamente igual.

Voy a seguir haciendo unas pruebas, a ver...

Casimiro Notevi
20-09-2011, 20:03:14
He estado echando un vistazo y veo que el que se pueda editar o no se decide en el evento OnSelectCell. En este evento creo que puedes comprobar si la columna en la que se encuentra se puede editar o no y devolver True o False según te interese.

Sí, así es, eso es perfecto, así lo hago, sólo que lo que intento hacer es que el cursor se mueva automáticamente a la siguiente celda editable (o a la anterior editable), sin tener que usar tab ni shift+tab, sino con teclas left y right.
Y el problema es que ninguna solución que he encontrado simula de verdad la pulsación de las tecla shift+tab al mismo tiempo.

He hecho otras pruebas y siempre acaban mal. Sin embargo si en ese punto le pulso a shift+tab continua perfectamente, o sea, hay que simular esas teclas de otra forma que las simule de verdad :D

Casimiro Notevi
20-09-2011, 20:08:20
Hola Casimiro.
Probaste algo como lo que sugirió newtron ?
Dado el arreglo de Boolean que ya has declarado, este código:
Código Delphi [-]procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); begin CanSelect:= aCeldas[ACol,ARow]; end;

No permitirá que se seleccione o edite las celdas cuyo valor correspondiente en el arreglo aCeldas sea False.
Saludos.

Sí, es que quiero que se salte esas celdas cuando se mueva con las teclas de flechas, sólamente por eso, a las malas, si no se encuentra solución, tendré que dejarlo así, de todas formas no va a poder modificarlas.

Casimiro Notevi
20-09-2011, 20:09:19
Te he dejado en evidencia, ecfisa, jajaja... te he contestado a algo que has borrado porque ya lo había explicado antes, mientras tú contestabas :D:D:D

roman
20-09-2011, 20:12:24
Bueno pero, ¿has considerado lo que he dicho? Es decir, aún en el supuesto que logres, como dices, emular el TAB y SHIFT+TAB, ¿no notas que al usar el ratón la selección se comporta rara? En el evento SelectCell tú presupones que se genera por una navegación secuencial, siendo que no necesariamente es así.

// Saludos

ecfisa
20-09-2011, 20:13:37
Hola Casimiro.

Para impedir la edición se podría usar:

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
begin
with TStringGrid(Sender) do
if aCeldas[ACol,ARow] then
Options:= Options + [goEditing]
else
Options:= Options - [goEditing];
end;

En cuanto saltar las celdas, sigo en eso... :)

Saludos.

ecfisa
20-09-2011, 20:42:47
Te he dejado en evidencia, ecfisa, jajaja... te he contestado a algo que has borrado porque ya lo había explicado antes, mientras tú contestabas :D:D:D
Si luego noté que ya lo habias explicado, pero no fuí lo suficientemente rápido para darme cuenta (o para borrarlo)... :D

Saludos.

Casimiro Notevi
20-09-2011, 21:01:17
Bueno pero, ¿has considerado lo que he dicho? Es decir, aún en el supuesto que logres, como dices, emular el TAB y SHIFT+TAB, ¿no notas que al usar el ratón la selección se comporta rara? En el evento SelectCell tú presupones que se genera por una navegación secuencial, siendo que no necesariamente es así.
// Saludos
Vaya, no había visto lo del ratón, no es mucho problema porque ahí sólo hay que usar el teclado para rellenar datos, pero si se cambian de celda con el ratón entonces no quedará muy elegante :confused:

Bueno, creo que voy a olvidar lo de las teclas, lo dejaré sólo que pueda ser editada/no editada y para diferenciarlas les cambiaré el color, por ejemplo.
En fin, mi gozo en un pozo :)

roman
20-09-2011, 21:10:13
A ver, prueba con esto:


procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
begin
if GoingForward or GoingBackward then
begin
if StrToIntDef(StringGrid1.Cells[ACol, ARow], 0) = 0 then
begin
if GoingBackward then
keybd_event(VK_SHIFT, 0, 0, 0);

keybd_event(VK_TAB, 0, 0, 0);
keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);

if GoingBackward then
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
end;
end;

GoingForward := false;
GoingBackward := false;
end;

procedure TForm1.StringGrid1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
GoingForward := false;
GoingBackward := false;

if Key = VK_LEFT then
begin
keybd_event(VK_SHIFT, 0, 0, 0);
keybd_event(VK_TAB, 0, 0, 0);
keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);

Key := 0;
end;

if Key = VK_RIGHT then
begin
keybd_event(VK_TAB, 0, 0, 0);
keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP, 0);

Key := 0;
end;

if Key in [VK_PRIOR, VK_UP] then
begin
GoingBackward := true;
end;

if Key in [VK_NEXT, VK_DOWN] then
begin
GoingForward := true;
end;

if Key = VK_TAB then
begin
if ssShift in Shift then
GoingBackward := true
else
GoingForward := true;
end;
end;


GoingBackward y GoingForward son variables boolenas delcaradas en el formulario.

En principio, con esto queda tal como quieres y se impide lo de la selección con el ratón (aunque no he hecho una prueba exhaustiva).

Aún así, el resultado puede ser confuso para el usuario, sobre todo con las teclas de avanzar o retroceder página, pues el "ciclado" puede dejarlos en un lugar para nada esperado.

¡Ah! Me olvidaba: en el ejemplo, para simplificar, la verificación de si la celda es editable se hace contra el contenido en sí de la celda (0 o 1).

// Saludos

Casimiro Notevi
20-09-2011, 21:26:35
Probando...


.

escafandra
20-09-2011, 21:33:53
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:

Por si las moscas he realizado otra función para simular pulsaciones, mas acorde con el S.O. usando la API SendImput (http://msdn.microsoft.com/en-us/library/ms646310(VS.85).aspx) y que ya use en un ejemplo aquí (http://clubdelphi.com/foros/showthread.php?t=65039&highlight=SendInput) para simular clicks de ratón.


procedure SimKey(VK: BYTE; Down: boolean);
var
Input: TInput;
begin
ZeroMemory(@Input, sizeof(Input));
Input.Tipo:= INPUT_KEYBOARD;
Input.ki.wVk:= VK;
Input.ki.wScan:= MapVirtualKey(VK, 0);
Input.ki.dwFlags:= KEYEVENTF_EXTENDEDKEY;
if not Down then
Input.ki.dwFlags:= Input.ki.dwFlags or KEYEVENTF_KEYUP;
windows.SendInput(1, tagINPUT(Input), sizeof(TInput));
end;

procedure TForm1.StringGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_LEFT then
begin
SimKey(VK_SHIFT, true);
SimKey(VK_TAB, true);
SimKey(VK_SHIFT, false);
SimKey(VK_TAB, false);
Key := 0;
end;
if Key = VK_RIGHT then
begin
SimKey(VK_TAB, true);
SimKey(VK_TAB, false);
Key := 0;
end;
end;


Saludos.

roman
20-09-2011, 21:54:35
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 Notevi
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: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...

Escafandra, el código que has puesto creo que necesita algo más que no has puesto, me da error en la línea: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 (http://msdn.microsoft.com/en-us/library/ms646270(v=VS.85).aspx) define así:
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:
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
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 (http://www.clubdelphi.com/foros/showpost.php?p=112824&postcount=6):


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 Notevi
21-09-2011, 13:44:42
De la otra guía de estilo (http://www.clubdelphi.com/foros/showpost.php?p=112824&postcount=6): :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:

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.


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 :).

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
....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 Notevi
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
...me parece que sería mejor intentar no simular esas teclas y manipular los valores de Col y Row en el evento KeyDown.



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 Notevi
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
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 Notevi
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
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
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 Notevi
21-09-2011, 19:50:52
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
...así que no lo he leído entero ..

Me ofendes. :p

Casimiro Notevi
22-09-2011, 17:47:09
Me ofendes. :p

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