Visual Basic - Formulario no redimensionable

Life is soft - evento anual de software empresarial
 
Vista:

Formulario no redimensionable

Publicado por FIHG (1 intervención) el 05/09/2007 08:35:23
Hola a todos:

Estamos tratando de implementar mediante la gestión de notificaciones un evento BeforeFormResize que nos permita cancelar dicha modificación del tamaño del formulario. Son variados los métodos presentados en diversas fuentes, pero ninguno lleva a cumplir completamente las expectativas. Aplicando una combinación de las mismas más la experiencia propia hemos articulado la función que incluimos a continuación y que aún padece de alguna deficiencia que pasamos a indicar a posteriori. Como pueden comprobar trabaja teniendo en cuenta las siguientes notificaciones: WM_NCLBUTTONDOWN (clic botón izquierdo sobre zona no cliente), para controlar el clic sobre los botones maximizar y minimizar, WM_WINDOWPOSCHANGING (modificación de la posición y/o tamaño de la ventana), WM_SIZING (modificación del tamaño de la ventana), y WM_NCLBUTTONDBLCLK (doble clic botón izquierdo sobre zona no cliente), para controlar dicha circunstancia sobre la barra de título, que produce un maximizado o restauración de la ventana.

Private Sub SubClassEvent_WinMsgArrived(ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long, Cancel As Boolean)

Dim OwnerhWnd As Long
Dim MDIhWnd As Long

Dim lCancel As Boolean ' Ivan 15.08.2007 Act. 62005

Select Case Msg

Case WM_NCLBUTTONDOWN ' Clic boton izquierdo ratón
Debug.Print Me.FormObj.Name & ".WM_NCLBUTTONDOWN"
Select Case wParam
Case HTMAXBUTTON, HTMINBUTTON ' Maximizar, Minimizar
RaiseEvent BeforeFormResize(Cancel)
End Select 'wParam
' WM_NCLBUTTONDOWN

Case WM_WINDOWPOSCHANGING
Debug.Print Me.FormObj.Name & ".WM_WINDOWPOSCHANGING"
Dim WP As WINDOWPOS
CopyMemory WP, ByVal lParam, LenB(WP)
Debug.Print "Propiedad", "Form", "WindowPos"
Debug.Print "Top:", Me.FormObj.Top, WP.Y
Debug.Print "Left:", Me.FormObj.Left, WP.X
Debug.Print "Height:", Me.FormObj.Height, WP.cy
Debug.Print "Width:", Me.FormObj.Width, WP.cx
'If WP.cx <> Me.FormObj.Width Or WP.cy <> Me.FormObj.Height Then
If (WP.cx = 0 And WP.cy = 0 And WP.X = 0 And WP.Y = 0) Or (WP.cx <> Me.FormObj.Width Or WP.cy <> Me.FormObj.Height) Then
RaiseEvent BeforeFormResize(Cancel)
If Cancel Then
WP.Flags = SWP_NOSIZE + SWP_NOMOVE
CopyMemory ByVal lParam, WP, LenB(WP)
End If
End If
' WM_WINDOWPOSCHANGING

Case WM_SIZING ' Redimensionando la ventana
Debug.Print Me.FormObj.Name & ".WM_SIZING"
RaiseEvent BeforeFormResize(Cancel)
If Cancel Then
Dim rc As RECT
CopyMemory rc, ByVal lParam, LenB(rc)
Debug.Print "Top:", rc.Top, Me.FormObj.Top, Me.FormObj.Top - rc.Top, Me.FormObj.Top / Screen.TwipsPerPixelY
Debug.Print "Left:", rc.Left, Me.FormObj.Left, Me.FormObj.Left - rc.Left, Me.FormObj.Left / Screen.TwipsPerPixelX
Debug.Print "Height:", rc.Bottom - rc.Top, Me.FormObj.Height, Me.FormObj.Height - (rc.Bottom - rc.Top), Me.FormObj.Height / Screen.TwipsPerPixelY
Debug.Print "Width:", rc.Right - rc.Left, Me.FormObj.Width, Me.FormObj.Width - (rc.Right - rc.Left), Me.FormObj.Width / Screen.TwipsPerPixelX
rc.Bottom = (Me.FormObj.Top + Me.FormObj.Height) / Screen.TwipsPerPixelY + 69 ' ?? Valor en constante
rc.Left = Me.FormObj.Left / Screen.TwipsPerPixelX
rc.Right = (Me.FormObj.Left + Me.FormObj.Width) / Screen.TwipsPerPixelX
rc.Top = Me.FormObj.Top / Screen.TwipsPerPixelY + 69 ' ?? Valor en constante
CopyMemory ByVal lParam, rc, LenB(rc)
End If
' WM_SIZING

Case WM_NCLBUTTONDBLCLK ' Doble clic boton derecho en área no cliente
Debug.Print Me.FormObj.Name & ".WM_NCLBUTTONDBLCLK"
Select Case wParam
Case HTCAPTION ' Barra de título
RaiseEvent BeforeFormResize(Cancel)
' HTCAPTION
End Select
' WM_NCLBUTTONDBLCLK
End Select
End Sub

Sin embargo si el formulario se encuentra maximizado y pulsamos el botón de minización y deseamos cancelar dicha acción, esto no se hace posible y se queda en un bucle infinito. Según las trazas que hemos realizado salta la notificación WM_NCLBUTTONDOWN pero a posteriori del redimensionado real.

Por otro lado alguno puede haber notado que no hemos utilizado la notificación WM_GETMINMAXINFO que en algunas fuentes señala como la adecuada a utilizar. Sin embargo, puesto que esta notificación también es enviada al mover el formulario, no es válida para nuestro propósito, que es generar un evento sólo en el caso de que se redimensione la venta.

Esperando alguna aportación que nos pueda ayudar a completar este proyecto, gracias de antemano.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder