Step by Step Guide for Drop Down Forms

There is a downloadable demo of a Drop Down Form which will probably be helpfull when using this guide

Step 1: Create the main form shape in VBSFC, and save it as a form. This should not include the dropping part, which is done later. At this point you may also want to draw the background picture for the form in its undropped state, and set this as the background bitmap for the form.

Step 2: Create the dropping part in VBSFC. You may wish to do this by drawing it on top of the non-dropping part, then deleting the non-dropping part in order to get it to line up properly, or you could use the background picture from step 1 in VBSFC as a guide (make it the VBSFC background picture). The dropping part should be in the dropped position. Once you have the dropping shape, save it as a new form. This will be deleted later.

Step 3: Open the dropping shape form, and find the sub called CreateFormRegion. You will need to make the following changes:
Replace the very first line (starting Private Function CreateFormRegion(...) with:

Private Function DropRegion(ByRef CurrentRegion As Long, ScaleX As Single, ScaleY As Single, OffsetX As Integer, OffsetY As Integer) As Long

The following line must be added before the ResultRegion = CreateRectRgn(0, 0, 0, 0) line:

DeleteObject ResultRegion

Replace the first line starting nRet = CombineRgn(... to:

nRet = CombineRgn(ResultRegion, CurrentRegion, ObjectRegion, RGN_OR)

You will also need to change the last line from CreateFormRegion = ResultRegion to DropRegion = ResultRegion. Then copy the entire sub, and paste it into the original main shaped form.

Step 4: You must now create some picture boxes on the main form. Draw a picture box called DropHolder to contain the dropping part of the form. You may wish to draw a background picture for this too, and set the picture boxes picture property to that. Inside the picture box you can put any controls that are on the dropping part. At this point you must decide how far the dropping bit drops so that you can calculate where it should be when undropped. For example, if your shape is at y position 100, and it 30 high, then you will probably want it to be at 70 when undropped.

Step 5: Create a new picture box called DropBitHider which completely covers the area occupied by the dropping part when in the undropped position. This is necessary to produce the effect that the dropping part drops from behind the form, but if you want the dropping part to be visible all the time, and just drop down in front of the form, then don't use it. Make a note of the co-ordinates of this picture box, then open your favourite picture editor, and cut out a bit of you background image at those co-ordinates, and save it as a new image. Use that as the background for DropBitHider. If you got the co-ordinates right, this should look seamless.

Step 6: The final picture box is only necessary if you are using windowless controls (like labels, for example). This picture box should cover the entire non-dropping area, and contain all the controls for that. It is possible to get away without using ths picture box at all, but it is just convenient, as it stops you from having to worry about putting controls over or in the other two picture boxes. Call it ControlHolder

Step 7: Time to start writing some code!

Private WindowRegion As Long
Private Const RGN_OR = 2

Private Sub Form_Load()
Dim nRet As Long, TempRgn As Long
'Position the dropping part
DropHolder.ZOrder 1
DropHolder.Top = UnDroppedPos
'Keep a copy of the window region
WindowRegion = CreateRectRgn(0, 0, 0, 0)
TempRgn = CreateFormRegion(1, 1, 0, 0)
nRet = CombineRgn(WindowRegion, TempRgn, 0, RGN_COPY)
'Set window and hider picture box regions.
'The hider picture box is necessary to stop the dropping
'part being visible when not dropped

nRet = SetWindowRgn(Me.hwnd, TempRgn, True)
nRet = SetWindowRgn(DropBitHider.hwnd, CreateFormRegion(1, 1, -DropBitHider.Left, -DropBitHider.Top), True)
End Sub

UnDroppedPos: Put the undropped position of the dropping section here (70 in our example)

Private Sub Form_Unload(Cancel As Integer)
DeleteObject ResultRegion
DeleteObject WindowRegion
End Sub

Private Sub Animate()
Dim Counter As Integer
For Counter = -DropHeight To 0 Step 4 'If you want larger steps, modify this line (changes drop speed)
'Adjust window shape
SetWindowRgn Me.hWnd, 0, False
SetWindowRgn Me.hWnd, DropRegion(WindowRegion, 1, 1, 0, Counter), True
'Move dropping part controls and picture
DropHolder.Top = DroppedPos + Counter
DoEvents
Next Counter
End Sub

DropHeight: Put the height to drop through here (30 in our example)
DroppedPos: Put the dropped position of the dropping part here (100)

Private Sub AnimateReverse()
Dim Counter As Integer
For Counter = 0 To DropHeight Step -8 'If you want larger steps, modify this line (changes rise speed)
SetWindowRgn Me.hWnd, 0, False
SetWindowRgn Me.hWnd, DropRegion(WindowRegion, 1, 1, 0, Counter), True
DropHolder.Top = DroppedPos + Counter
DoEvents
Next Counter
End Sub

Step 8: All that is needed now is to call Animate when you want the bit to drop, and AnimateReverse when you want it to rise. I put these in buttons in the DropDown demo, but it is up to you where you want to put them.