Minimize Maximize buttons

  • Thread starter Thread starter Guest
  • Start date Start date
RBS,

Great! It works perfect. Thanks a lot.

RB Smissaert said:
Figured out now how to let it minimize to the taskbar and this is all the
code in my test Wb:

In the UserForm1 code:

Option Explicit
Private lFormHwnd As Long
Private Declare Function FindWindow _
Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) _
As Long

Public Property Let propFormHwnd(lHwnd As Long)
lFormHwnd = lHwnd
End Property

Public Property Get propFormHwnd() As Long
propFormHwnd = lFormHwnd
End Property

Private Sub UserForm_Initialize()

Dim hwnd As Long

If Val(Application.Version) >= 9 Then
hwnd = FindWindow("ThunderDFrame", Caption)
Else
hwnd = FindWindow("ThunderXFrame", Caption)
End If

Me.propFormHwnd = hwnd

End Sub

Private Sub UserForm_Resize()
SetMinimize 'leave out for floating minimize
End Sub

'=====================================

In the normal module:

Option Explicit
Public Declare Function GetWindowLong _
Lib "user32" Alias _
"GetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong _
Lib "user32" Alias _
"SetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private Declare Function DrawMenuBar Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function ShowWindow _
Lib "user32" (ByVal hwnd As Long, _
ByVal nCmdShow As Long) _
As Long
Private Declare Function IsIconic Lib "user32" (ByVal hwnd As Long) _
As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Const WS_MAXIMIZEBOX As Long = &H10000
Private Const WS_MINIMIZEBOX As Long = &H20000
Private Const GWL_STYLE As Long = -16

Sub LoadForm()

Load UserForm1
UserForm1.Show 0
AddMinMax
SetMinimize True 'leave out for floating minimize

End Sub

Sub AddMinMax()

Dim hwnd As Long
Dim lngStyle As Long

hwnd = UserForm1.propFormHwnd

lngStyle = GetWindowLong(hwnd, GWL_STYLE)
lngStyle = lngStyle Or WS_MAXIMIZEBOX
lngStyle = lngStyle Or WS_MINIMIZEBOX

SetWindowLong hwnd, GWL_STYLE, lngStyle
DrawMenuBar hwnd

End Sub

Sub SetMinimize(Optional bNormal As Boolean)

Dim hwnd As Long

hwnd = UserForm1.propFormHwnd

If IsIconic(hwnd) Then
ShowWindow hwnd, 0
SetWindowLong hwnd, -20, &H40101
ShowWindow hwnd, 6
Else
If bNormal Then
ShowWindow hwnd, 0
SetWindowLong hwnd, -20, &H40101
ShowWindow hwnd, 1
End If
End If

End Sub


So, you now have the options to minimize to a small floating window or to
the taskbar and this
depends on running SetMinimize in the 2 places as mentioned.
I think it now all should work.


RBS
 
It looks it can actually work with a normal modal form as well, but as you
can
see it needs some adjustments as it doesn't work first time.

RBS
 
Would be interested if anybody could tell me how to make this work properly
with a normal modal userform.

RBS
 
Had a look at the file FormFun.xls, but even that doesn't handle this
(maximize and minimize with a modal form) properly, as you can see
when you tick modal and minimize the form.

RBS
 
I suppose there is little point in minimizing a modal userform as you
can't do anything outside the form.

RBS
 
Bingo!

--
Regards,
Tom Ogilvy

RB Smissaert said:
I suppose there is little point in minimizing a modal userform as you
can't do anything outside the form.

RBS
 
Well, you could have a peek in the sheet without moving or closing the form,
but that really is all.

RBS
 
Actually it can be done a bit simpler still as it looks we don't need any
code
in the UserForm Resize event.

In UserForm:

Option Explicit
Private lFormHwnd As Long
Private Declare Function FindWindow _
Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) _
As Long

Public Property Let propFormHwnd(lHwnd As Long)
lFormHwnd = lHwnd
End Property

Public Property Get propFormHwnd() As Long
propFormHwnd = lFormHwnd
End Property

Private Sub UserForm_Initialize()

Dim hwnd As Long

If Val(Application.Version) >= 9 Then
hwnd = FindWindow("ThunderDFrame", Caption)
Else
hwnd = FindWindow("ThunderXFrame", Caption)
End If

Me.propFormHwnd = hwnd

End Sub

=========================================

In normal Module:

Option Explicit
Private Declare Function GetWindowLong _
Lib "user32" Alias _
"GetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong _
Lib "user32" Alias _
"SetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private Declare Function DrawMenuBar Lib "user32" _
(ByVal hwnd As Long) As Long
Private Declare Function ShowWindow _
Lib "user32" (ByVal hwnd As Long, _
ByVal nCmdShow As Long) _
As Long
Private Declare Function IsIconic Lib "user32" (ByVal hwnd As Long) _
As Long
Private Const WS_MAXIMIZEBOX As Long = &H10000
Private Const WS_MINIMIZEBOX As Long = &H20000
Private Const GWL_STYLE As Long = -16

Sub LoadForm()

Dim hwnd As Long
Dim bTaskBarMinimize As Boolean

Load UserForm1
UserForm1.Show 0

AddMinMax

hwnd = UserForm1.propFormHwnd

'set to False for floating minimize
'----------------------------------
bTaskBarMinimize = True

If bTaskBarMinimize Then
ShowWindow hwnd, 0
SetWindowLong hwnd, -20, &H40101
ShowWindow hwnd, 1
End If

End Sub

Sub AddMinMax()

Dim hwnd As Long
Dim lngStyle As Long

hwnd = UserForm1.propFormHwnd

lngStyle = GetWindowLong(hwnd, GWL_STYLE)
lngStyle = lngStyle Or WS_MAXIMIZEBOX
lngStyle = lngStyle Or WS_MINIMIZEBOX

SetWindowLong hwnd, GWL_STYLE, lngStyle
DrawMenuBar hwnd

End Sub


RBS
 
Hi Bart,
Would be interested if anybody could tell me how to make this work properly
with a normal modal userform.

Lightly tested, to allow modeless use while the modal form is minimized

Replace all code in your normal module with following (userform code as-was)

Option Explicit
Public Declare Function GetWindowLong _
Lib "user32" Alias _
"GetWindowLongA" _
(ByVal hWnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong _
Lib "user32" Alias _
"SetWindowLongA" _
(ByVal hWnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private Declare Function DrawMenuBar Lib "user32" _
(ByVal hWnd As Long) As Long
Private Declare Function ShowWindow _
Lib "user32" (ByVal hWnd As Long, _
ByVal nCmdShow As Long) _
As Long
Private Declare Function IsIconic Lib "user32" (ByVal hWnd As Long) _
As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Declare Function FindWindowA Lib "user32" (ByVal _
lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function EnableWindow Lib "user32" (ByVal _
hWnd As Long, ByVal bEnable As Long) As Long
Public Declare Function SetForegroundWindow Lib "user32" (ByVal _
hWnd As Long) As Long


Private Const WS_MAXIMIZEBOX As Long = &H10000
Private Const WS_MINIMIZEBOX As Long = &H20000
Private Const GWL_STYLE As Long = -16

Sub LoadFormModal()

Load UserForm1
AddMinMax
UserForm1.Show vbModal

End Sub

Sub AddMinMax()

Dim hWnd As Long
Dim lngStyle As Long

hWnd = UserForm1.propFormHwnd

lngStyle = GetWindowLong(hWnd, GWL_STYLE)
lngStyle = lngStyle Or WS_MAXIMIZEBOX
lngStyle = lngStyle Or WS_MINIMIZEBOX

SetWindowLong hWnd, GWL_STYLE, lngStyle
DrawMenuBar hWnd

End Sub

Sub SetMinimize(Optional bNormal As Boolean)

Dim hWnd As Long

hWnd = UserForm1.propFormHwnd

If IsIconic(hWnd) Then
ShowWindow hWnd, 0
SetWindowLong hWnd, -20, &H40101
ShowWindow hWnd, 6
ChangeMode 1&

Else
ChangeMode 0
If bNormal Then
ShowWindow hWnd, 0
SetWindowLong hWnd, -20, &H40101
ShowWindow hWnd, 1
End If
End If

End Sub

Sub ChangeMode(mode As Long)
Dim appWin As Long

appWin = FindWindowA("XLMAIN", Application.Caption)
EnableWindow appWin, mode
If mode = 1 Then
SetForegroundWindow appWin
End If

End Sub

Seems to work but not sure why the slight difference between first &
subsequent minimize actions.

Regards,
Peter T
 
When I click the close button, the program is gone. Is there a way to give a
warning, like "Do you want to save before exit? Yes/No"
 
Yes, put this code in your UserForm module:

Private Sub UserForm_QueryClose(Cancel As Integer, _
CloseMode As Integer)
If CloseMode = vbFormControlMenu Or _
CloseMode = vbAppTaskManager Then
If MsgBox("Are you sure you want to close this window?", _
vbQuestion + vbYesNo + vbDefaultButton1, _
"") = vbNo Then
Cancel = 1
End If
End If
End Sub

RBS
 
Hi Peter,

Like Tom O, I think minimizing a modal userform doesn't really serve much
purpose.
I am sure though with some tinkering it can work, but don't think it is
worth the trouble.

Bart
 
Cool!

Thanks a lot.

RB Smissaert said:
Yes, put this code in your UserForm module:

Private Sub UserForm_QueryClose(Cancel As Integer, _
CloseMode As Integer)
If CloseMode = vbFormControlMenu Or _
CloseMode = vbAppTaskManager Then
If MsgBox("Are you sure you want to close this window?", _
vbQuestion + vbYesNo + vbDefaultButton1, _
"") = vbNo Then
Cancel = 1
End If
End If
End Sub

RBS
 
Back
Top