Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   cambiar foco de un control a otro (https://www.clubdelphi.com/foros/showthread.php?t=75843)

lmpadron 22-09-2011 15:29:06

cambiar foco de un control a otro
 
Hola comunidad

Necesito saber como se puede lograr que cuando un usuario esta escribiendo algo en un Edit por ejemplo y presione ENTER cambie a otro edit para continuar. he tratado llamando la propiedad Edit1->Focused() pero no lo hace y no se si estoy haciendo algo mal o no.

gracias de antemano

aposi 22-09-2011 15:59:23

NOMBRE_DEL_OBJETO.SetFocus;
en el evento onexit del primer objeto

ecfisa 22-09-2011 16:30:37

Hola impadron.

Probá asignando este código a el evento OnKeyPress de los Edits en que desees ese comportamiento:
Código:

void __fastcall TForm1::EditKeyPress(TObject *Sender, char &Key)
{
  if(Key == 13){
    Key = 0;
    keybd_event(VK_TAB,0,0,0);
    keybd_event(VK_TAB,0,2,0);
  }
}

Saludos.

newtron 22-09-2011 17:06:24

Hola.

Yo lo que hago es poner este código en el FormKeyDown del formulario, además de esto tienes que activar el KeyPreview del mismo a true. Con esto te servirá para todos los controles del formulario.

Código Delphi [-]
  case Key of

    VK_UP: begin
      SelectNext(ActiveControl, False, True);
      Key := 0;
    end;

    VK_DOWN: begin
      SelectNext(ActiveControl, True, True);
      Key := 0;
    end;

  end;

Saludos


Edito: Perdón perdón... no había visto que era de C++

ecfisa 22-09-2011 19:40:35

Cita:

Empezado por newtron (Mensaje 413026)
Edito: Perdón perdón... no había visto que era de C++

Pero... es que tu respuesta es totalmente correcta mi estimado newtron! ;)

Así que traduciendo a C++ y tomando en cuenta que quiere verificar la tecla Enter sería:
Código:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  KeyPreview = true;  /* se puede asignar desde el Object Inspector */
}

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
TMsg *Msg;
  if(Key == VK_RETURN){
    PeekMessage(Msg, 0, WM_CHAR, WM_CHAR,PM_REMOVE); /* Quitar Beep */
    SelectNext(ActiveControl, true, true);
  }
}

Un saludo. :)

newtron 22-09-2011 19:41:44

Cita:

Empezado por ecfisa (Mensaje 413091)
Pero... es que tu respuesta es totalmente correcta mi estimado newtron! ;)

Pues fíjate que hasta cuando me equivoco acierto. :D

escafandra 22-09-2011 19:58:31

Quisiera hacer un comentario al último código de ecfisa.

Declaras un puntero a TMsg, ese puntero no apunta a nada válido, no está inicializado. Antes o después dará lugar a un error difícil de depurar. Las prisas...;)

Tu código está mejor así:
Código:

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
  TMsg Msg;
  if(Key == VK_RETURN){
    PeekMessage(&Msg, 0, WM_CHAR, WM_CHAR,PM_REMOVE);
    SelectNext(ActiveControl, true, true);
  }
}

O así:
Código:

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
  if(Key == VK_RETURN){
    PeekMessage(0, 0, WM_CHAR, WM_CHAR,PM_REMOVE);
    SelectNext(ActiveControl, true, true);
  }
}

Aunque lo que apuntó newtron se entiende mejor y tiene una traducción casi literal:
Código:

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
  if(Key == VK_RETURN){
    Key = 0;
    SelectNext(ActiveControl, true, true);
  }
}

Las dos opciones son perfectamente válidas :)

Saludos.

ecfisa 22-09-2011 19:58:39

Lo que me faltó aclarar es que como en ese caso se altera el comportamiento de la tecla Enter para todos los componentes del Form, puede dar resultados no deseados. Como por ejemplo en el caso del StringGrid.

Saludos.

ecfisa 22-09-2011 20:26:23

Cita:

Declaras un puntero a TMsg, ese puntero no apunta a nada válido, no está inicializado.
Hola escafandra.

Tenés toda la razón sobre el puntero (que es innecesario) y sobre el apuro ;), escribí el código directo sobre el mensaje y la traducción no fué la mejor...:o

Pero con referencia a el código:
Código:

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
  if(Key == VK_RETURN){
    Key = 0;  // no quita el Beep
    SelectNext(ActiveControl, true, true);
  }
}

que mencinás arriba, recordaba que en Delphi la asignación Key:= 0; no quita el beep (por eso usaba PeekMessage), por lo que lo probé en Builder y tampoco lo hace.

Un saludo.:)

ecfisa 22-09-2011 20:50:11

Y ya que estamos me acordé de otro modo de hacer lo mismo. :)

Código:

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
  if(Key == VK_RETURN) {
    PeekMessage(0, 0, WM_CHAR, WM_CHAR, PM_REMOVE);
    Perform(WM_NEXTDLGCTL, false, false);
  }
}

Saludos.

escafandra 22-09-2011 21:18:08

Tienes razón en lo del Beep. :)

Siguiendo la estela del bajo nivel, nada nos impide usar solo la API. :D

Código:

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
  if(Key == VK_RETURN){
    PeekMessage(0, 0, WM_CHAR, WM_CHAR,PM_REMOVE);
    SendMessage(Handle, WM_NEXTDLGCTL, 0, 1);
  }
}

Saludos.

roman 22-09-2011 21:23:31

Una variante, usando un componente ApplicationEvents:

Código Delphi [-]
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
begin
  with Msg do
    if (message = WM_KEYDOWN) and (wParam = VK_RETURN) and (ActiveControl is TCustomEdit) then
    begin
      SelectNext(ActiveControl, true, true);
      Handled := true; // con esto quitamos el beep
    end;
end;

// Saludos

escafandra 22-09-2011 23:04:12

Buena variante roman. :)

Saludos.

ecfisa 22-09-2011 23:39:41

Lo que siempre digo: román nunca deja de sorprenderme... ;):)

Saludos.

roman 22-09-2011 23:42:53

Pues es prácticamente lo mismo que lo de ustedes, con el único agregado de comprobar se es un Edit. Lo que es a mi, eso del PeekMessage en delphi como que no se me da :p

// Saludos

lmpadron 26-09-2011 16:10:25

Gracias amigos por su ayuda

como los objetos estan desorganizados utilize lo siguiente

Código:

NOMBRE_DEL_OBJETO->SetFocus;
y funciono perfectamente


La franja horaria es GMT +2. Ahora son las 00:16: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