Minimize Maximize buttons

G

Guest

Tom,

Thanks very much. The FormFun is very interesting. But the codes are too
complicated for me to adopt. I just want to have the bottons on the form once
the form is initialized.

Anyway, I apprecite your help.

Scott
 
R

RB Smissaert

This is simplest code to add those buttons:

Option Explicit
Public Declare Function GetWindowLong _
Lib "user32" Alias _
"GetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function FindWindow _
Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) 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)
Private strFormType As String

Sub AddMinMax(strFormCaption As String)

Dim hwnd As Long
Dim lngStyle As Long

'this is not really necessary, vbNullString will do
If Val(Application.Version) >= 9 Then
strFormType = "ThunderDFrame"
Else
strFormType = "ThunderXFrame"
End If

hwnd = FindWindow(strFormType, strFormCaption)
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 LoadForm()

Load UserForm1
UserForm1.Show 0

AddMinMax "Userform1"

End Sub


RBS
 
G

Guest

Thanks for the help.

I copied your codes to my file, but I still did not get the buttons on my
UserForm1.
 
R

RB Smissaert

If you can show the relevant code I might be able to tell you where you went
wrong.

RBS
 
R

RB Smissaert

Did you do:
UserForm1.Show 0

So did you load the form as a modeless form?
A modeless form means you can do things outside the form (like doing things
in the sheet) while the form is loaded.
It doesn't work with a normal modal form, not sure now if it can.

RBS
 
J

Jim May

RB;
I'd love to incorporate your code into a app I've got going.
I see 3 code sections:
1) The Public Declare - Constants
2) The AddMinMax
3) The Load Form

In My Open Workbook Code I have:
frmMainUser.show ' where frmMainUser - Show Modal prop is set to False

There is no other Userform code attached to frmMainUser

How would I proceed to incorporate the above.
I am fairly VB understanding, so keep it simple, PLEASE..
Thanks for your assistance.
 
R

RB Smissaert

Simple, in your WorkBook_Open code do instead:

Load frmMainUser
frmMainUser.Show 0

AddMinMax frmMainUser.Caption

The declarations and the Sub AddMinMax will have to go to a normal Module.
Keep all the declarations just as they are, no need to make the declarations
Public.

RBS
 
J

Jim May

I think I got it, but When I open my Workbook, I get
Compile error - Only Comments may apprear after End Sub,
End Funtion or End Property The Declaration- Code seems
To be the culprit - am I missing the End Function line
After each Public Declare Function (Lines)?
 
R

RB Smissaert

Maybe the linebreaks messed it up.
Does it compile OK? This goes with:
Debug, Compile VBAProject.
am I missing the End Function line after each Public Declare Function
(Lines)?

No, there is no such thing as End Function for declarations.

This the same declaration section, but made a bit narrower:

Option Explicit
Public Declare Function GetWindowLong _
Lib "user32" Alias _
"GetWindowLongA" _
(ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function FindWindow _
Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) _
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)
Private strFormType As String


RBS
 
J

Jim May

RB,
Got it!!
One last Q;
My Userform on Load (Wb Open) comes up partial screen (3 X 5)
When I minimize it, then Restore it comes up Full screen (7 X 10, say)
Can this aspect be controlled to where the Restore could re-produce
The 3 X 5 Size?
Really do appreciate your help on this.
Jim
 
J

Jim May

RB,
Never mind...
I do now see that I have the ability to choose
My UF size with the icons;
Thanks for all your help.
Jim
 
R

RB Smissaert

Yes, you can do that with:

ShowWindow hwnd, 3

This will have to go in the UserForm_Resize event code of the form and
should
run when you want the form maximized.

If you run it in the UserForm then the declaration in the module should be
made public.

It all will take a bit of experimentation, but it should all work in the
end.

RBS
 
R

RB Smissaert

You also might be interested to minimize to the taskbar rather than having a
floating form.
That can be done with code like this:

Sub SetMinimize(strFormCaption As String)

Dim hwnd As Long

hwnd = FindWindow(strFormType, strFormCaption)

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

End Sub

All this works nicely in large app I have, but when I test in a simple test
setup
the first time this runs it still minimizes to the floating window. After
that it
will miminize to the taskbar. Not sure why this is.


RBS
 
R

RB Smissaert

One last tip:
What you may want to do is to avoid getting every time again that hwnd of
your
form is make this a property of the form like this:

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

Then in your module or where ever you can always do something like this:

hwnd = UserForm1.propFormHwnd

Saving you all the extra code with FindWindow. You could achieve the same
with a public variable, but this is neater.


RBS
 
G

Guest

RBS,

I have a form called "UserForm1" under folder "Forms". I copied your codes
to "Module2" in folder Modules. And I tried to run your codes, which brought
up UserForm1, but there were no Min/Max buttons. Here are the codes:

Option Explicit
Public Declare Function GetWindowLong _
Lib "user32" Alias _
"GetWindowLongA" (ByVal hwnd As Long, _
ByVal nIndex As Long) As Long
Private Declare Function FindWindow _
Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, _
ByVal lpWindowName As String) 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)
Private strFormType As String

Sub AddMinMax(strFormCaption As String)

Dim hwnd As Long
Dim lngStyle As Long

'this is not really necessary, vbNullString will do
If Val(Application.Version) >= 9 Then
strFormType = "ThunderDFrame"
Else
strFormType = "ThunderXFrame"
End If

hwnd = FindWindow(strFormType, strFormCaption)
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 LoadForm()

Load UserForm1
UserForm1.Show 0

AddMinMax "UserForm1"

End Sub
 
J

Jim May

RB,
Thanks for such a full explanation of things;
I've printed out for this and other Source (future) documentation/
Needs.
 
R

RB Smissaert

What is your Excel version?

Try changing this:
hwnd = FindWindow(strFormType, strFormCaption)
to this:
hwnd = FindWindow(vbNullString, strFormCaption)

RBS
 
R

RB Smissaert

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top