In this post we continue the USA flag series by giving VBA GDI code that creates a Windows MetaFile. So GDI works with device contexts, a device context could be a form, a printer or a file. This version of the code writes to a file.
modUSAFlagGDI Standard Module
In the code below a new procedure has been added, DrawUSAFlagToFile(). On line 65, you'll need to change the output path from "N:\metafiles\flag2.wmf".
New API functions have been declared CreateEnhMetaFileA(), DeleteEnhMetaFile() and CloseEnhMetaFile() to manage the meta file. CreateEnhMetaFileA() returns a device context that can be supplied to the drawing logic thus drawing to file.
You'll need the modUSAFlagSpecification module from a previous post.
modUSAFlagGDI Standard Module
- Option Explicit
- '*
- '* Brought to you by the Excel Development Platform Blog
- '* http://exceldevelopmentplatform.blogspot.com/2018/11/
- '*
- Private Declare Function CreatePen Lib "gdi32" _
- (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
- Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hDC As Long, ByVal hObject As Long) As Long
- Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Long) As Long
- Private Declare Function Polygon Lib "gdi32" (ByVal hDC As Long, lpPoint As POINTAPI, ByVal nCount As Long) As Long
- Private Declare Function Rectangle Lib "gdi32" (ByVal hDC As Long, ByVal X1 As Long, _
- ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
- Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hWnd As Long, ByVal hDC As Long) As Long
- Private Declare Function RestoreDC Lib "gdi32" (ByVal hDC As Long, ByVal nSavedDC 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 GetDC Lib "user32.dll" (ByVal hWnd As Long) As Long
- Private Declare Function SaveDC Lib "gdi32" (ByVal hDC As Long) As Long
- Private Const PS_SOLID As Long = 0
- Private Declare Function CreateEnhMetaFileA Lib "gdi32.dll" ( _
- ByVal hdcRef As Long, _
- ByVal lpFileName As String, _
- lpRect As RECT, _
- ByVal lpDescription As String) As Long
- Private Declare Function DeleteEnhMetaFile Lib "gdi32" (ByVal hemf As Long) As Long
- Private Declare Function CloseEnhMetaFile Lib "gdi32" (ByVal hDC As Long) As Long
- Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
- Public Sub FindFormsDeviceContext(ByVal sFormCaption As String, ByRef hForm As Long, ByRef dcForm As Long, ByRef dcOldDeviceContext As Long)
- hForm = FindWindow("ThunderDFrame", sFormCaption)
- dcForm = GetDC(hForm)
- dcOldDeviceContext = SaveDC(dcForm)
- End Sub
- Public Sub ReleaseDeviceContexts(ByVal dcDeviceContext As Long, ByVal dcOldDeviceContext As Long, ByVal hForm As Long)
- ReleaseDC hForm, dcDeviceContext
- RestoreDC hForm, dcOldDeviceContext
- End Sub
- Public Sub DrawUSAFlagToFile()
- Dim uRect As RECT
- uRect.Top = 0
- uRect.Left = 0
- uRect.Bottom = 10000
- uRect.Right = 19000
- Dim sMetaFilePath As String
- sMetaFilePath = "N:\metafiles\flag1.wmf"
- If Len(Dir(sMetaFilePath)) > 0 Then
- Kill sMetaFilePath
- End If
- Dim dcDeviceContext As Long
- dcDeviceContext = CreateEnhMetaFileA(0, sMetaFilePath, uRect, vbNullString)
- Debug.Assert dcDeviceContext <> 0
- DrawUSAFlagByGDI dcDeviceContext, 0.378
- Dim lFileHandle As Long
- lFileHandle = CloseEnhMetaFile(dcDeviceContext)
- Call DeleteEnhMetaFile(lFileHandle)
- End Sub
- Public Sub DrawUSAFlagByGDI(ByVal dcDeviceContext As Long, ByVal dScalar As Double)
- Dim auRects() As RECT
- Dim uBlue As RGB
- Call modUSAFlagSpecification.GetOldGloryBlue(uBlue)
- Dim uRed As RGB
- Call modUSAFlagSpecification.GetOldGloryRed(uRed)
- Dim uWhite As RGB
- Call modUSAFlagSpecification.GetWhite(uWhite)
- Call modUSAFlagSpecification.BlueCanton(dScalar, auRects)
- DrawRects dcDeviceContext, uBlue, auRects
- Call modUSAFlagSpecification.RedStripes(dScalar, auRects)
- DrawRects dcDeviceContext, uRed, auRects
- Call modUSAFlagSpecification.WhiteStripes(dScalar, auRects)
- DrawRects dcDeviceContext, uWhite, auRects
- DrawStars dcDeviceContext, dScalar
- End Sub
- Private Sub DrawStars(ByVal dcDeviceContext As Long, ByVal dScalar As Double)
- Dim Pen As Long, OldPen As Long, Brush As Long, OldBrush As Long
- Dim auRects() As RECT
- Call modUSAFlagSpecification.WhiteStars(dScalar, auRects)
- Dim uWhite As RGB
- Call modUSAFlagSpecification.GetWhite(uWhite)
- Pen = CreatePen(PS_SOLID, 1, uWhite.R + (uWhite.G * 256) + (uWhite.B * 65536))
- OldPen = SelectObject(dcDeviceContext, Pen)
- Brush = CreateSolidBrush(uWhite.R + (uWhite.G * 256) + (uWhite.B * 65536))
- OldBrush = SelectObject(dcDeviceContext, Brush)
- Dim lStarLoop As Long
- For lStarLoop = 0 To 49
- Dim uRect As RECT
- uRect = auRects(lStarLoop)
- Dim auPoints() As POINTAPI, lPointCount As Long
- Call modUSAFlagSpecification.FivePointedStar(dScalar, 30, uRect.Left, uRect.Top, auPoints, lPointCount)
- Call Polygon(dcDeviceContext, auPoints(0), 10)
- Next
- Call SelectObject(dcDeviceContext, OldPen)
- Call SelectObject(dcDeviceContext, OldBrush)
- End Sub
- Private Sub DrawRects(ByVal dcDeviceContext As Long, ByRef uRGB As RGB, ByRef auRects() As RECT)
- Dim Pen As Long, OldPen As Long, Brush As Long, OldBrush As Long
- Pen = CreatePen(PS_SOLID, 1, uRGB.R + (uRGB.G * 256) + (uRGB.B * 65536))
- OldPen = SelectObject(dcDeviceContext, Pen)
- Brush = CreateSolidBrush(uRGB.R + (uRGB.G * 256) + (uRGB.B * 65536))
- OldBrush = SelectObject(dcDeviceContext, Brush)
- Dim lLoop As Long
- For lLoop = LBound(auRects) To UBound(auRects)
- Call Rectangle(dcDeviceContext, auRects(lLoop).Left, auRects(lLoop).Top, auRects(lLoop).Right, auRects(lLoop).Bottom)
- Next lLoop
- Call SelectObject(dcDeviceContext, OldPen)
- Call SelectObject(dcDeviceContext, OldBrush)
- End Sub
No comments:
Post a Comment