Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleEnumerate the records in a Windows metafile (WMF) or enhanced metafile (EMF) in VB .NET
Keywordsmetafile, WMF, EMF, VB.NET, enumerate
CategoriesGraphics, VB.NET
 
When the user clicks the Enumerate button, the program erases its ListBox and PictureBox. It then makes a Metafile object representing a metafile. It creates a Graphics object and calls its EnumerateMetafile method, passing it the Metafile object. The last parameter to this call is the address of an enumeration function that should be called for each metafile record.

The ListRecords function is called for each record. This routine displays the type name of each metafile record in a ListBox.

 
' Enumerate the metafile to list its records.
Private Sub btnEnumerate_Click(ByVal sender As _
    System.Object, ByVal e As System.EventArgs) Handles _
    btnEnumerate.Click
    ' Clear the record list.
    lstRecords.Items.Clear()

    ' Clear the PictureBox.
    Dim bm As New Bitmap(picResults.ClientSize.Width, _
        picResults.ClientSize.Height)
    Dim gr As Graphics = Graphics.FromImage(bm)
    gr.Clear(picResults.BackColor)
    picResults.Image = bm
    gr.Dispose()

    ' Enumerate the metafile records.
    Dim mf As New Metafile(txtFileName.Text)
    Me.CreateGraphics.EnumerateMetafile( _
        mf, New PointF(0, 0), _
        AddressOf ListRecords)

    btnDraw.Enabled = True
End Sub

' Add this record to the list.
Public Function ListRecords( _
    ByVal recordType As EmfPlusRecordType, _
    ByVal flags As Integer, _
    ByVal dataSize As Integer, _
    ByVal data As IntPtr, _
    ByVal callbackData As PlayRecordCallback _
) As Boolean
    lstRecords.Items.Add(recordType.ToString)
    Return True
End Function
 
When the user clicks the Draw button, the program erases its PictureBox. It makes a Bitmap to fit its PictureBox and clears it. The program then creates a Metafile object representing a metafile.

Next the program calls the uses the EnumerateMetafile method of the Graphics object attached to the Bitmap. The final parameter to this routine indicates that the metafile records should be passed to the DrawRecords subroutine.

DrawRecords checks whether the corresponding entry in the ListBox is selected (use Click, Shift-Click, and Ctrl-Click to select records). If the record is selected, the routine returns without executing it. If the record is not selected in the ListBox, the function calls the Metafile's PlayRecord method. That applies the record to the Graphics object whose EnumerateMetafile method we are executing (i.e. the one attached to the Bitmap).

When the EnumerateMetafile method returns, the btnDraw_Click event handler displays the Bitmap's results.

 
' Enumerate the metafile records, drawing those
' that are NOT selected in the list.
Private Sub btnDraw_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles btnDraw.Click
    ' Start with the first record.
    m_NextRecordNumber = 0

    ' Make a Bitmap and Graphics to display
    ' the results.
    Dim bm As New Bitmap(picResults.ClientSize.Width, _
        picResults.ClientSize.Height)
    Dim gr As Graphics = Graphics.FromImage(bm)
    gr.Clear(picResults.BackColor)

    ' Open the metafile.
    m_Metafile = New Metafile(txtFileName.Text)

    ' Enumerate the records.
    gr.EnumerateMetafile( _
        m_Metafile, New PointF(0, 0), _
        AddressOf DrawRecords)

    ' Display the results.
    picResults.Image = bm
    gr.Dispose()
End Sub

' Draw the record if it is not selected in 
' the list.
Public Function DrawRecords( _
    ByVal recordType As EmfPlusRecordType, _
    ByVal flags As Integer, _
    ByVal dataSize As Integer, _
    ByVal data As IntPtr, _
    ByVal callbackData As PlayRecordCallback _
) As Boolean
    ' See if this record is selected.
    With lstRecords.SelectedIndices
        For i As Integer = 0 To .Count - 1
            If .Item(i) = m_NextRecordNumber Then
                Debug.WriteLine("Skipping " & _
                    recordType.ToString)
                m_NextRecordNumber += 1
                Return True
            End If
        Next i
    End With
    m_NextRecordNumber += 1

    Dim data_array() As Byte = Nothing
    If Not (data.Equals(IntPtr.Zero)) Then
        ' Copy the unmanaged record data 
        ' into a managed byte buffer that we
        ' can pass to PlayRecord.
        ReDim data_array(dataSize - 1)
        Marshal.Copy(data, data_array, 0, dataSize)
    End If

    ' Play the record.
    m_Metafile.PlayRecord(recordType, flags, dataSize, _
        data_array)

    ' Continue the enumeration.
    Return True
End Function
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated