Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Coloboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 20-09-2011
Avatar de Casimiro Noteví
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.671
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
¿Cómo simular de "verdad" las teclas SHIFT+TAB?

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.



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

Código Delphi [-]
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.


Código Delphi [-]
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:

Código Delphi [-]
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 , 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
Responder Con Cita
  #2  
Antiguo 20-09-2011
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Casimiro Notevi
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:

Código Delphi [-]
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
Responder Con Cita
  #3  
Antiguo 20-09-2011
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.210
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Código Delphi [-]
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.
Responder Con Cita
  #4  
Antiguo 20-09-2011
Avatar de newtron
[newtron] newtron is offline
Membrillo Premium
 
Registrado: abr 2007
Ubicación: Motril, Granada
Posts: 4.214
Poder: 24
newtron Va camino a la fama
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.
__________________
Be water my friend.

Última edición por newtron fecha: 20-09-2011 a las 19:24:20.
Responder Con Cita
  #5  
Antiguo 20-09-2011
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.210
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
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.
Responder Con Cita
  #6  
Antiguo 20-09-2011
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por newtron Ver Mensaje
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
Responder Con Cita
  #7  
Antiguo 20-09-2011
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.210
Poder: 22
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Caramba, roman nos vamos pisando los mensajes, tampoco vi que respondias mientras ya estaba realizando otro comentario...

Saludos.
Responder Con Cita
  #8  
Antiguo 20-09-2011
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por escafandra Ver Mensaje
Código Delphi [-]
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
Responder Con Cita
  #9  
Antiguo 20-09-2011
Avatar de Casimiro Noteví
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.671
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
Cita:
Empezado por ecfisa Ver Mensaje
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.
Responder Con Cita
  #10  
Antiguo 20-09-2011
Avatar de Casimiro Noteví
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.671
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
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
Responder Con Cita
  #11  
Antiguo 20-09-2011
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
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
Responder Con Cita
  #12  
Antiguo 20-09-2011
Avatar de Casimiro Noteví
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.671
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
Cita:
Empezado por roman Ver Mensaje
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

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
Responder Con Cita
  #13  
Antiguo 20-09-2011
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
A ver, prueba con esto:

Código Delphi [-]
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
Responder Con Cita
  #14  
Antiguo 20-09-2011
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 38
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Cita:
Empezado por Casimiro Notevi Ver Mensaje
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
Si luego noté que ya lo habias explicado, pero no fuí lo suficientemente rápido para darme cuenta (o para borrarlo)...

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
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
Detectar pulsación de teclas Ctrl, Alt y Shift y teclas virtuales (de función,...) rrf Varios 11 09-08-2017 13:24:21
El programa se queda "colgado" mientras copia y luego "despierta" NeWsP OOP 5 10-03-2010 22:05:40
Como hacer que se vea "Si" en vez de "TRUE" en un DBGrid lu9eui C++ Builder 2 07-08-2007 04:03:13
Necesito llamar a métodos de clases "hija" desde su clase "padre" Flecha OOP 17 20-04-2007 00:03:53


La franja horaria es GMT +2. Ahora son las 09:05:24.


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
Copyright 1996-2007 Club Delphi