La Web del Programador: Comunidad de Programadores
 
    Pregunta:  24262 - SCROLLBARS EN MDI
Autor:  picarog .
Tengo un formulario mdi en el que dentro de él se cargan otros formularios que necesitan barra de desplazamiento vertical. Cuando el formulario es demasiado largo aparece la barra y sin problemas. Bien, el problema lo tengo cuando necesito tener el enfoque en un campo que está al fondo del formulario, el foco lo coje, pero la barra de desplazamiento no se mueve.

¿Como puedo solucionar esto?

Es un poco urgente....

Gracias de antemano

  Respuesta:  coatl_zrm ccp
Saludos picarog.
Hace unas semanas yo tenia la misma duda, pero yo queria mover los scroll bars de la ventana hija y no del mdiForm.
Después de buscar mucho y no encontrar nada me dicidí a hacerlo yo mismo y me he sorprendido, pues despues de tantos dolores de cabeza la respuesta resulto ser no muy complicada.

Bien, logre solucionar mi problema y de paso pude hacer lo que tu quierias: mover las scroll bars del mdiForm.

'----------------------------
'-En un módulo
'---------------------------
Option Explicit

Private Type SCROLLINFO
cbSize As Long
fMask As Long
nMin As Long
nMax As Long
nPage As Long
nPos As Long
nTrackPos As Long
End Type

Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Private Declare Function SetScrollPos Lib "user32" (ByVal hwnd As Long, ByVal nBar As Long, ByVal nPos As Long, ByVal bRedraw As Long) As Long
Private Declare Function SetScrollInfo Lib "user32" (ByVal hwnd As Long, ByVal n As Long, lpcScrollInfo As SCROLLINFO, ByVal bool As Boolean) As Long
Private Declare Function GetScrollInfo Lib "user32" (ByVal hwnd As Long, ByVal n As Long, lpScrollInfo As SCROLLINFO) As Long
Private Declare Function ScrollWindowByNum& Lib "user32" Alias "ScrollWindow" (ByVal hwnd As Long, ByVal XAmount As Long, ByVal YAmount As Long, ByVal lpRect As Long, ByVal lpClipRect As Long)
Private Declare Function GetWindowRect& Lib "user32" (ByVal hwnd As Long, lpRect As RECT)
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetFocus Lib "user32" () As Long

Private Const SB_VERT = 1

Public Const GW_CHILD = 5

Function Focus(howner As Long)
Dim s As SCROLLINFO
Dim H As Long, nOldPos As Long
Dim RecWin As RECT, RecControl As RECT
Dim DimWin As Integer, DimControl As Integer
howner = GetWindow(howner, GW_CHILD)
H = GetFocus()
GetWindowRect H, RecControl
GetWindowRect howner, RecWin
GetScrollInfo howner, SB_VERT, s
nOldPos = s.nPos
'Determina las dimensiones de los controles (en este caso solo 'Alto')
DimWin = (RecWin.Bottom - RecWin.Top) - 50
DimControl = RecControl.Bottom - RecControl.Top
If (RecControl.Top < (RecWin.Top + 25)) Or (DimControl > DimWin) Then
'si el control esta por arriba del área de trabajo
s.nPos = s.nPos - ((RecWin.Top + 25) - RecControl.Top)
ElseIf RecControl.Bottom > RecWin.Bottom Then
'si el control esta por debajo del área de trabajo
s.nPos = ((RecControl.Bottom + 25) - RecWin.Bottom) + s.nPos
End If
SetScrollInfo howner, SB_VERT, s, True
'Activa las coordenadas del Scroll
ScrollWindowByNum howner, 0, nOldPos - s.nPos, 0, 0
SetScrollPos howner, SB_VERT, s.nPos, True
End Function
'-------------------------------------------------------------------------
'- Dentro de cada uno de los controles del MdiChild debes colocar lo siguiente
'-En este caso yo coloque una matriz de textbox
'--------------------------------------------------------------------------
Private Sub Text1_GotFocus(Index As Integer)
Focus MDIForm1.hwnd
End Sub

Private Sub Text1_KeyDown(Index As Integer, KeyCode As Integer, Shift As Integer)
Focus MDIForm1.hwnd
End Sub

Si te interesa un pequeño ejemplo mandame tu email, dado que no lo haz puesto en tu pregunta.

Ah, si hay un usuario que sepa como mejorar este codigo favoir de escribirme, me interesa mucho saber que esto se pueda reducir.

Gracias.