I've attempted to modify API code found on another web page to resize userform in proportion or aspect ratio (Width/Height = constant).
Did a fair amount of testing, it's a bit tricky to figure out sequence of code ... suggest that UserForm_Resize is called up before UserForm_Initialize ... and each may be called up twice???
So far it works when I change form size (in proportion) using the Hor. and 45deg grips, but not the Ver. grip.
Is it possible for one of the following:
- Change form size in proportion using all three grips (Hor., Ver, 45deg).
- Remove the options for the Hor. and Ver. grips entirely, so only change using the 45deg grip.
MODULE CODE
FORM CODE
Did a fair amount of testing, it's a bit tricky to figure out sequence of code ... suggest that UserForm_Resize is called up before UserForm_Initialize ... and each may be called up twice???
So far it works when I change form size (in proportion) using the Hor. and 45deg grips, but not the Ver. grip.
Is it possible for one of the following:
- Change form size in proportion using all three grips (Hor., Ver, 45deg).
- Remove the options for the Hor. and Ver. grips entirely, so only change using the 45deg grip.
MODULE CODE
VBA Code:
Option Explicit
Public Const GWL_STYLE = -16
Public Const WS_CAPTION = &HC00000
Public Const WS_THICKFRAME = &H40000
#If VBA7 Then
Public Declare PtrSafe Function GetWindowLong Lib "User32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare PtrSafe Function SetWindowLong Lib "User32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare PtrSafe Function DrawMenuBar Lib "User32" (ByVal hwnd As Long) As Long
Public Declare PtrSafe Function FindWindowA Lib "User32" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#Else
Public Declare Function GetWindowLong Lib "User32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowLong Lib "User32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function DrawMenuBar Lib "User32" (ByVal hwnd As Long) As Long
Public Declare Function FindWindowA Lib "User32" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#End If
Sub ResizeWindowSettings(frm As Object, show As Boolean)
'Debug.Print "api_mod"
Dim windowStyle As Long
Dim windowHandle As Long
windowHandle = FindWindowA(vbNullString, frm.Caption)
windowStyle = GetWindowLong(windowHandle, GWL_STYLE)
If show = False Then
windowStyle = windowStyle And (Not WS_THICKFRAME)
Else
windowStyle = windowStyle + (WS_THICKFRAME)
End If
SetWindowLong windowHandle, GWL_STYLE, windowStyle
DrawMenuBar windowHandle
End Sub
Sub Open_Form_API_mod()
myUserForm_API.show vbModeless
End Sub
FORM CODE
VBA Code:
Option Explicit
'form proportion
Dim form_proportion As Double
'to maintain proportions
Dim cnt As Long 'counter
Dim arrW() As Variant, arrH() As Variant 'W=Width and H=Height
Dim init_width, init_height As Double
Dim W1 As Double, W2 As Double, H1 As Double, H2 As Double '1=Previous and 2=New
Private Sub UserForm_Initialize()
Dim width_at_Initialize
'proportions ...
form_proportion = 1.41
'size
width_at_Initialize = 120
Me.Width = width_at_Initialize + 1 * (Me.Width - Me.InsideWidth)
Me.Height = form_proportion * width_at_Initialize + 1 * (Me.Height - Me.InsideHeight)
init_width = Me.Width
init_height = Me.Height
'Call the Window API to enable resizing
Call ResizeWindowSettings(Me, True)
'arrays
ReDim arrW(0)
ReDim arrH(0)
End Sub
'this is called up multiple (???) times initialy, and twice (???) when resizing form
'-----------------------------------------------------------------------------------
Private Sub UserForm_Resize()
On Error Resume Next
'arrays
ReDim Preserve arrW(cnt)
ReDim Preserve arrH(cnt)
arrW(cnt) = Me.Width
arrH(cnt) = Me.Height
If cnt = 0 Then
'nothing ... init not called up yet
End If
If cnt = 1 Then
'nothing ... init not called up yet
End If
If cnt = 2 Then 'effectively the process of getting the form up one screen, seems to be 3 iterations
W2 = arrW(cnt): W1 = init_width
H2 = arrH(cnt): H1 = init_height
Debug.Print "(" & cnt & ")" & "W2 =" & arrW(cnt) & ", W1 = " & init_width & " ... " & "H2 =" & arrH(cnt) & ", H1 = " & init_height
End If
If cnt > 2 Then
W2 = arrW(cnt): W1 = arrW(cnt - 1)
H2 = arrH(cnt): H1 = arrH(cnt - 1)
Debug.Print "(" & cnt & ")" & "W2 =" & arrW(cnt) & ", W1 = " & arrW(cnt - 1) & " ... " & "H2 =" & arrH(cnt) & ", H1 = " & arrH(cnt - 1)
End If
'resize in proportion
'--------------------
If cnt >= 2 Then
'important to round Double
If Round(W2, 1) = Round(W1, 1) Then
Me.Height = H2
Me.Width = (1 / form_proportion) * H2
End If
If Round(H2, 1) = Round(H1, 1) Then
Me.Width = W2
Me.Height = form_proportion * W2
End If
If (Round(W2, 1) <> Round(W1, 1)) And (Round(H2, 1) <> Round(H1, 1)) Then
Me.Width = W2
Me.Height = form_proportion * W2
End If
End If
'counter
cnt = cnt + 1
On Error GoTo 0
End Sub