http://www.vb-helper.com/HowTo/shapefrm.zip

	Purpose
Make a form shaped around with hollow text and a PictureBox

	Method
This is a fairly complex example. Most of the fun happens in the ShapeForm subroutine.

It uses the CreateFont API function to make a specially sized font. It uses SelectObject to select the font.

Then the program use the GetTextExtentPoint API function to get the size of the text it will display. It uses the result for the text's width.

Because the height returned by GetTextExtentPoint include space above and below the actual text, the program uses GetTextMetrics to see exactly how tall the printed part of the text is (ascent) and how far from the "top" of the text the actual drawing starts (internal leading space).

With these values, the program calculates exactly where it will put its two lines of text and the PictureBox in the middle.

Next ShapeForm makes Windows regions for the two text strings and the PictureBox. This code fragment shows how it makes a region for the first line of text. The BeginPath, EndPath, and PathToRegion API functions do the work here.

        SelectObject hdc, font1
        BeginPath hdc
        CurrentX = (wid - text1_wid) / 2
        CurrentY = -text1_int
        Print TEXT1
        EndPath hdc
        hRgn1 = PathToRegion(hdc)

After creating three regions, one for each line of text and one for the PictureBox, the program combines them using CombineRgn. It then restricts the form so it is clipped at this combined region.

        CombineRgn hRgn1, hRgn1, hRgn2, RGN_OR
        CombineRgn hRgn1, hRgn1, hRgn3, RGN_OR

        ' Constrain the form to the combined region.
        SetWindowRgn hWnd, hRgn1, False

Finally, the program repeats the steps it took to make the text regions except it calls StrokePath to draw the outline text instead of making regions.

    ' Shape the login window.
    Private Sub ShapeForm()
    Const TEXT1 = "RAD"
    Const TEXT2 = "VB"
    Const TEXT_HGT1 = 250
    Const TEXT_WID1 = 100
    Const TEXT_HGT2 = 250
    Const TEXT_WID2 = 100
    Const FONT_NAME1 = "Times New Roman"
    Const FONT_NAME2 = "Times New Roman"
    Const VGAP1 = -20
    Const VGAP2 = -40
    Const DRAW_WIDTH = 5
    
    Dim font1 As Long
    Dim font2 As Long
    Dim origfont As Long
    Dim hRgn1 As Long
    Dim hRgn2 As Long
    Dim hRgn3 As Long
    Dim x1 As Long
    Dim x2 As Long
    Dim y1 As Long
    Dim y2 As Long
    Dim sz As Size
    Dim tm As TEXTMETRIC
    Dim wid As Single
    Dim hgt As Single
    Dim pix_wid As Single
    Dim pix_hgt As Single
    Dim text1_wid As Single
    Dim text1_hgt As Single
    Dim text1_int As Single
    Dim text2_wid As Single
    Dim text2_hgt As Single
    Dim text2_int As Single
    
        ' Prepare the form.
        AutoRedraw = True
        ScaleMode = vbPixels
        BorderStyle = vbBSNone
        BackColor = vbBlue
        ForeColor = vbBlack
        Caption = ""
        DrawWidth = DRAW_WIDTH
        ' ControlBox = False    ' Set at design time.
        ' MinButton = False     ' Set at design time.
        ' MaxButton = False     ' Set at design time.
        ' ShowInTaskbar = False ' Set at design time.
    
        ' Get the size of the text.
        font1 = CustomFont(TEXT_HGT1, TEXT_WID1, 0, 0, _
            FW_BOLD, False, False, False, _
            FONT_NAME1)
        origfont = SelectObject(hdc, font1)
        GetTextExtentPoint hdc, TEXT1, Len(TEXT1), sz
        text1_wid = sz.cx
        GetTextMetrics hdc, tm
        text1_int = tm.tmInternalLeading
        text1_hgt = tm.tmAscent - text1_int
    
        font2 = CustomFont(TEXT_HGT2, TEXT_WID2, 0, 0, _
            FW_BOLD, False, False, False, _
            FONT_NAME2)
        SelectObject hdc, font1
        GetTextExtentPoint hdc, TEXT2, Len(TEXT2), sz
        text2_wid = sz.cx
        GetTextMetrics hdc, tm
        text2_int = tm.tmInternalLeading
        text2_hgt = tm.tmAscent - text2_int
    
        ' Make the form big enough.
        wid = picLogin.Height
        If wid < text1_wid Then wid = text1_wid
        If wid < text2_wid Then wid = text2_wid
        hgt = picLogin.Height + text1_hgt + text2_hgt + VGAP1 + VGAP2
        pix_wid = ScaleX(wid, vbPixels, vbTwips)
        pix_hgt = ScaleY(hgt, vbPixels, vbTwips)
        Move (Screen.Width - pix_wid) / 2, _
             (Screen.Height - pix_hgt) / 2, _
             pix_wid, pix_hgt
    
        ' Make the regions.
        SelectObject hdc, font1
        BeginPath hdc
        CurrentX = (wid - text1_wid) / 2
        CurrentY = -text1_int
        Print TEXT1
        EndPath hdc
        hRgn1 = PathToRegion(hdc)
    
        SelectObject hdc, font2
        BeginPath hdc
        CurrentX = (wid - text2_wid) / 2
        CurrentY = text1_hgt + VGAP1 + VGAP2 + picLogin.Height - text2_int
        Print TEXT2
        EndPath hdc
        hRgn2 = PathToRegion(hdc)
    
        picLogin.Move (wid - picLogin.Width) / 2, text1_hgt + VGAP1
        x1 = picLogin.Left
        x2 = x1 + picLogin.Width
        y1 = picLogin.Top
        y2 = y1 + picLogin.Height
        hRgn3 = CreateRectRgn(x1, y1, x2, y2)
    
        ' Combine the regions.
        CombineRgn hRgn1, hRgn1, hRgn2, RGN_OR
        CombineRgn hRgn1, hRgn1, hRgn3, RGN_OR
    
        ' Constrain the form to the combined region.
        SetWindowRgn hWnd, hRgn1, False
    
        ' Draw with a hollow font.
        SelectObject hdc, font1
        BeginPath hdc
        CurrentX = (wid - text1_wid) / 2
        CurrentY = -text1_int
        Print TEXT1
        EndPath hdc
        StrokePath hdc
    
        SelectObject hdc, font2
        BeginPath hdc
        CurrentX = (wid - text2_wid) / 2
        CurrentY = text1_hgt + VGAP1 + VGAP2 + picLogin.Height - text2_int
        Print TEXT2
        EndPath hdc
        StrokePath hdc
    
        ' Restore the original font.
        SelectObject hdc, origfont
    
        ' Free font resources (important!)
        DeleteObject font1
        DeleteObject font2
    End Sub

The program also shows how to get the program's name, version number, copyright information, etc. from the project properties. Use the Project menu's Properties command to set these values. Look in Form_Load to see how the program loads them.

	Disclaimer
This example program is provided "as is" with no warranty of any kind. It is
intended for demonstration purposes only. In particular, it does no error
handling. You can use the example in any form, but please mention
www.vb-helper.com.
