• Domingo 28 de Abril de 2024, 19:57

Autor Tema:  Problema con el foco de un formulario  (Leído 2492 veces)

alejos

  • Nuevo Miembro
  • *
  • Mensajes: 7
    • Ver Perfil
Problema con el foco de un formulario
« en: Sábado 22 de Agosto de 2009, 11:32 »
0
Hola a todos,

tengo un problema con un programa que estoy desarrollando en Visual Basic 6.0. Consiste en que quiero dibujar un cubo en 3D sobre un formulario. Además incluyo otros objetos en pantalla para hacer otras cosas. El programa debe recibir por el puerto serie una serie de valores que indican cómo se tiene que mover el cubo que he dibujado. Por ahora sólo estoy haciendo pruebas con el cubo y aún no he añadido la parte de la conexión por el puerto serie pero ya tengo mi primer problema.

Parece ser que cuando dibujo sólo el cubo sobre el formulario, el programa funciona perfectamente. Si se pulsan las teclas de dirección del teclado el cubo se mueve en la dirección pulsada. El problema aparece cuando incluyo cualquier otro objeto como un botón o un frame, etc. Si están activos (propiedad enable=true) no consigo que vuelva a funcionar el movimiento del cubo. El foco se mantiene siempre en alguno de los componentes y nunca sobre el formulario por mucho que yo fuerce a que permanezca ahí cuando se carga el form (Form1.SetFocus en la función form_activate()). Si los desactivo (enable= false) todo funciona otra vez perfectamente.

Yo creo que el problema está relacionado con el foco del formulario, pero no sé si realmente puede ser otra cosa. Alguien puede decirme dónde tengo el error o cómo hacer que el foco se mantenga en el form? Os adjutno el programa de prueba que he hecho. En realidad es un código adaptado del original que encontré para dibujar figuras 3D en otra gran web de Visual Basic (recursosvisualbasic.com.ar).

Espero vuestra ayuda. Muchas gracias por adelantado.

Saludos
Alejos
El mensaje contiene 1 archivo adjunto. Debes ingresar o registrarte para poder verlo y descargarlo.

Nebire

  • Miembro HIPER activo
  • ****
  • Mensajes: 670
    • Ver Perfil
Re: Problema con el foco de un formulario
« Respuesta #1 en: Sábado 22 de Agosto de 2009, 18:06 »
0
Hay 4 formas de solucionarlo, pero mejor te lo explico...

El formulario, es un contenedor y como casi todos los contenedores implementa una funcionalidad para recibir el foco (la propiedad causesvalidation y por tanto el evento validate, pertenecen también a esta interfaz).

Ahora bien cuando un contenedor no implementa dicha funcionalidad, no puede retener el foco pero si uno de sus controles contenidos si se 'gana' el foco.

Éste es precisamente el caso del frame, el frame es un contenedor que no implementa la funcionalidad de foco  (en realidad no es exactamente así, si implementa funcionalidad de foco, pero la enmascara, lo que para el caso es casi lo mismo que si no la tuviera) , porque está concebido como un contenedor ligero con la única finalidad de agrupar y mantener ordenados los controles, por eso tampoco incluye otras propiedades como picture ni eventos de teclado (aunque si los de ratón).... el frame lo que hace es repartir el foco entre los controles, sin salirse del contenedor si usamos las teclas... No es todo, luego vamos más a ello.

Te ha dado la curiosa e infrecuente coincidencia de que sólo tienes un control más que precisamente tiene la propiedad tabindex a 0. cuando se carga un   formulario el control que tiene el foco es aquel que tiene la propiedad tabindex más baja, además mediante la propiedad tabindex podemos pasar el foco de un control a otro, usando precisamente la tecla 'Tab' (tabulador) que va pasando de índice a indice. Dentro de cada contenedor, siempre hay un control que es el que recibe el foco por defecto, esto complica un poco la forma en que el tabulador se mueve... el caso es, que si el contenedor puede recibir el foco (el frame ya hemos dicho que no, pero un picture, si) y éste tiene controles, el tabulador irá primero al control que tiene seleccionado por defecto si tiene el tabindex menor que el contenedor y luego al contenedor y luego se irá a otro contenedor, es decir el contenedor actúa como 1 sólo control si no puede recibir el foco o como 2 si puede recibir el foco... como tu pregunta no va por aquí, no me extiendo más sobre el tema salvo que alguien quiera saber más sobre ello...

Dadas esas coincidencias paso a explicarte las 4 soluciones: antes que nada si el formulario tiene controles, y queremos usar teclas sobre el propio contenedor (el formulario) debemos establecer la propiedad KeyPreview a true, esto le dice al formulari oque los eventos de teclado primero los envíe al formulario para procesarlos y luego a los controles, si no se hace esto se manda la pulsación de tecla como un evento de teclado del control que tiene el foco... digamos que esta es la manera que tiene el formulario de ganar el foco a través del teclado...

Bien habiendo activado esa propiedad...
Solución 1: mantén pulsada la tecla CTRL y/o ALT y/o Mayúsculas (1 de las 3 o cualquier combinación de ellas a la vez) y sin soltar mientras pulsas las teclas de dirección que has fijado para el cubo. Si sólo pulsas las teclas no hace caso...

Solución 2: añade un picture al formulario, mándale el foco al picture ... ahora ya te 'obedece', sin tener que pulsar combinaciones de teclas.(si no le mandas el foco directamente por código, al pulsar una vez tecla de dirección le estás enviando el foco desde el botón (Cerrar) al picture, por tanto la próxima pulsación es ya efectiva para 'mover el cubo'.

Solución 3: Esta es la más acertada... en vez de 'dibujar' el cubo sobre el formulario dibújalo dentro de un picture, dedícalo exclusivamente para dibujar, no le metas controles... así el foco no se 'pierde' entre los controles

Solución 4: funciona incluso sin tener activada la propiedad keypreview del formulario... el dibujo sigue sobre el formulario pero quien atiende al evento no es el formulario sino un picture... por tanto añade un picture al formulario, pincha sobre él (mándale el foco de la forma que prefieras, utiliza las teclas... todo el código que tienes dentro del evento:
Código: Visual Basic
  1.  
  2. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  3.   .... 'el código que tienes aquí...
  4. End Sub
  5.  
  6.  
lo cortas y lo pegas al evento del picture
Código: Visual Basic
  1.  
  2. Private Sub Picture1_KeyDown(KeyCode As Integer, Shift As Integer)
  3.   .... 'páslo aquí...
  4. End Sub
  5.  
  6.  
Convendría que no metieras entonces nada en ese picture y éste podría tener un tamaño muy pequeño, de tal modo que pareciera más un botón y haciéndose a la idea tal que para poder dibujar hubiera que activar el dibujado, para fomentar esta sensación podrías ayudarlo con algo como el siguiente código...
Código: Visual Basic
  1.  
  2. Private Sub Picture1_GotFocus()
  3.     Picture1.BorderStyle = 0
  4.     Picture1.BackColor = vbGreen
  5. End Sub
  6.  
  7. Private Sub Picture1_LostFocus()
  8.     Picture1.BorderStyle = 1
  9.     Picture1.BackColor = vbRed
  10.     Timer1.Enabled = False
  11. End Sub
  12.  
  13.  



Si algo te ha resultado confuso, das un aviso, aunque como estoy de vacaciones, posiblemente pasen varios días hasta que vuelva a ojear el foro... y en todo caso será un vistazo rápido...
« última modificación: Sábado 22 de Agosto de 2009, 18:19 por Nebire »
«Ma non troppo»
----> ModoVacaciones = False<----

Nebire

  • Miembro HIPER activo
  • ****
  • Mensajes: 670
    • Ver Perfil
Re: Problema con el foco de un formulario
« Respuesta #2 en: Sábado 22 de Agosto de 2009, 18:09 »
0
... se me olvidaba ... si ves que parpadea mucho la imagen activa la propiedad autoredraw del formulario, irá más un pelín más lento, pero también más suave....
«Ma non troppo»
----> ModoVacaciones = False<----

alejos

  • Nuevo Miembro
  • *
  • Mensajes: 7
    • Ver Perfil
Re: Problema con el foco de un formulario
« Respuesta #3 en: Martes 15 de Septiembre de 2009, 17:15 »
0
Hola Nebire,

muchas gracias por tu ayuda. Aunque haya pasado mucho tiempo sin contestarte quiero decirte que seguí tus instrucciones y me ayudaron mucho. Muchas gracias por todo.


Saludos
Alejos