Attribute VB_Name = "modICTester"
Option Explicit

Private Const Module_Name                       As String = "modICTester"

Public Const SWP_NOSIZE = &H1
Public Const SWP_NOMOVE = &H2
Public Const HWND_TOPMOST = -1
Public Const HWND_NOTOPMOST = -2
Public Const MAX_PINS                           As Integer = 24
Public Const DEFAULT_COLOURS                    As String = "8454016,16744448,16776960,32768,255,6250335,65280,255,65535,8404992,4227327,3092271,65535,8388863,65280"
    
Public Enum geValidationTypes
    VALIDATE_ALPHA
    VALIDATE_FILENAME
    VALIDATE_NUMERIC
    VALIDATE_HEX
End Enum


Public gbOptions(8)                             As Boolean  ' 0 - Warn IC power requirements
                                                            ' 1 - Show Tool bar
                                                            ' 2 - Show status bar
                                                            ' 3 - Allow Flashing Text
                                                            ' 4 - Dip Type 1
                                                            ' 5 - Dip Type 2
                                                            ' 6 - 4 Way
                                                            ' 7 - 8 Way
                                                            ' 8 - Debugging Mode
Public gbAbortTest                              As Boolean
Public gbBeep                                   As Boolean  ' Beep enabled
Public gbFormLoaded(2)                          As Boolean  ' Is the specified form loaded and initialised
                                                            ' 0 - Logic Trace
                                                            ' 1 - Test Results
                                                            ' 2 - IC View
Public gbModelLoaded                            As Boolean  ' Indicates if an IC model file has been loaded
Public gbMultipleTests                          As Boolean  ' Indicates if single or multiple test passes are to be performed
Public gnPort                                   As Integer  ' COM port to use
Public gnDIPS(7, 2)                             As Integer
Public gnPowerPins(1)                           As Integer
Public glColors(14)                             As Long     ' Holds display colours - linked to txtColor on the config form
Public glPortSpeed                              As Long     ' COM speed
Public gsRXBuffer                               As String
Public gsPaths(0)                               As String   ' Data models path
Public gsSettings(2)                            As String   ' Holds additional configuration settings
Public gsModelFileName                          As String   ' Holds path and file name of the current model def. file
                                                    
Public Type gtypeModel_Pins
    Tag                                         As String
    Usage                                       As Integer
End Type

Public Type gtypeModel_TestScript
    Ins                                         As Integer
    Operand                                     As String
End Type

Public Type gtypeModel
    Model                                       As String
    Description                                 As String
    NumPins                                     As Integer
    Pin(MAX_PINS)                               As gtypeModel_Pins
    TestScript                                  As New Collection ' gtypeModel_TestScript
    UsageCount(5)                               As Integer
    PinVSS                                      As Integer
    PinVDD                                      As Integer
End Type

Public gtypModel                                As gtypeModel
Public gtypNewModel                             As gtypeModel

Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Declare Function SetWindowPos Lib "USER32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Public Sub ErrorRoutine(ByRef Module_Name As String, ByRef PROC_NAME As String, ByRef ErrorObj As ErrObject, Optional Additional As String)
' This is the global error handler

    Dim sDetails                        As String
    
    sDetails = "A critical error has been detected." & vbCrLf
    sDetails = sDetails & "Location: " & Module_Name & "/" & PROC_NAME & vbCrLf
    sDetails = sDetails & "Error:" & ErrorObj.Number & ", " & ErrorObj.Description & vbCrLf
    sDetails = sDetails & "Additional:" & Additional & vbCrLf
    sDetails = sDetails & "Please make a note of the these details of this error" & vbCrLf
    sDetails = sDetails & "and send an Email to ICTester@kcsl.uk.com." & vbCrLf
    sDetails = sDetails & "Please also state exactly what you were doing at the time the error occured !"
    
    MsgBox sDetails, vbOKOnly + vbCritical, "Digital IC Tester Critical Error"
    
    End
    
End Sub

Public Sub LogEvent(sDescription As String, nIcon As Integer, nSeq As Integer)

    Const PROC_NAME                             As String = "LogEvent"
    
    On Error GoTo ErrorHandler
    
    
    frmTestResults.ResultLogEvent sDescription, nIcon, nSeq
    
    If gbBeep = True Then
        Select Case nIcon
        Case 2, 3, 4
            Beep
        End Select
    End If
    
    Exit Sub
    
ErrorHandler:
    ErrorRoutine Module_Name, PROC_NAME, Err
End Sub


Public Function CompareResults(sExpected As String, sResult As String, nPins As Integer, sBuffer As String) As Boolean
' Compares what we get back from the Tester with what were expecting
' Returns True if match is ok
' Also, returns a copy of the converted ASCII buffer contents back as Binary
    
    Dim F                       As Integer
    Dim nOffset                 As Integer
    Dim sTemp                   As String
    
    Const PROC_NAME                     As String = "CompareResults"
    
    On Error GoTo ErrorHandler
    
    nOffset = 12 - (gtypModel.NumPins / 2)
    
    sBuffer = ConvertToBinary(Asc(Mid$(sResult, 1, 1))) ' .....................PORT B
    sBuffer = sBuffer & ConvertToBinary(Asc(Mid$(sResult, 2, 1))) '........... PORT D
    
    sTemp = Right$(ConvertToBinary(Asc(Mid$(sResult, 3, 1))), 6) ' ............PORT A
    sBuffer = sBuffer & Left$(sTemp, 1) ' Recover A5
    sBuffer = sBuffer & Mid$(sTemp, 3) ' Recover A3 to A0
    
    sBuffer = sBuffer & Right$(ConvertToBinary(Asc(Mid$(sResult, 4, 1))), 3) ' PORT E
    '
    ' Now we trim down the buffer to include ONLY the used pins
    
    sBuffer = Mid$(sBuffer, nOffset + 1, gtypModel.NumPins)
        
    CompareResults = True ' Assume OK until proved wrong
    ' Perform bit compare
    For F = 1 To nPins
        If gtypModel.Pin(F).Usage <> 5 Then '
            ' This is not a N/C pin
            If Mid$(UCase$(sExpected), F, 1) <> "X" Then
                If Mid$(sExpected, F, 1) <> Mid$(sBuffer, F, 1) Then
                    ' Match failed
                    CompareResults = False
                    Exit For ' No point carrying on
                End If
            End If
        End If
    Next F
    
    Exit Function
    
ErrorHandler:
    ErrorRoutine Module_Name, PROC_NAME, Err
End Function

Public Function Device_ReadBuffer(ByRef ComPort As MSComm) As String
' This routine looks for data in the RX buffer
' and returns it.

    Dim nSkip                           As Integer
    Dim sBuffer                         As String
    Dim sngTimeout                      As Single
    
    
    
    On Error GoTo ErrorHandler
    
    DoEvents ' Give the system time to get on with it
    
    sngTimeout = Timer
    sBuffer = ""
    DoEvents
    
    nSkip = 0
    Do
        With ComPort
            If sngTimeout + 2 < Timer Then
                nSkip = nSkip + 1
            End If
            
            If .InBufferCount > 0 Then
                ' There is somthing in the buffer
                nSkip = 0
                sBuffer = sBuffer & .Input
                Sleep CLng(gsSettings(2)) * 2
                sngTimeout = Timer ' Reset the time-out
            End If
            
            ' Check to see if we have received everything
            If Right$(sBuffer, 3) = "." & vbCrLf Then
                ' Buffer contains a valid packet
                nSkip = nSkip + 1
            End If
            
        End With
        DoEvents
        'Sleep 10
        
    Loop Until nSkip > CLng(gsSettings(2))
    Device_ReadBuffer = sBuffer
            
    Exit Function
    
    
ErrorHandler:
    Device_ReadBuffer = ""
End Function

Public Function ConvertToBinary(nValue As Integer) As String
' Converts a decimal to value (0 to 255) to a string, MSB (Bit 7) first

    Dim F                           As Integer
    Dim nMul                        As Integer
    Dim sReturn                     As String
    
    
    nMul = 128
    
    For F = 0 To 7
        If nMul And nValue Then
            sReturn = sReturn & "1"
        Else
            sReturn = sReturn & "0"
        End If
        nMul = nMul / 2
    Next F
    
    ConvertToBinary = sReturn
End Function

Public Function GetFileDescription(sFileName As String) As String

    Dim nFileNumber                     As Integer
    Dim sHeading                        As String
    
    
    On Error GoTo ErrorHandler
    
    nFileNumber = FreeFile
    
    Open sFileName For Input As nFileNumber
    
    Line Input #nFileNumber, sHeading ' We ignore this first line which contains the model number
    Line Input #nFileNumber, sHeading ' This line contains the description text
    
    GetFileDescription = sHeading
    
    Close #nFileNumber
    
    Exit Function

ErrorHandler:
    Close 0
    GetFileDescription = "*** INVALID FILE TYPE ***"
End Function

Public Function Device_ClosePort(ByRef ComPort As MSComm) As Long
' This routine closes the comms port

    On Error GoTo ErrorHandler
    
    With ComPort
        .PortOpen = False
    End With
    Device_ClosePort = 0 ' No Error
    
    Exit Function
        
        
ErrorHandler:
    Device_ClosePort = Err
End Function


Public Function Device_FlushBuffer(ByRef ComPort As MSComm) As Long
' Flushes the Input and Output buffers

    On Error GoTo ErrorHandler
    
    gsRXBuffer = ""
    With ComPort
        .InBufferCount = 0
        .OutBufferCount = 0
    End With
    Device_FlushBuffer = 0
    
    Exit Function
    
    
ErrorHandler:
    Device_FlushBuffer = Err
End Function




Public Function Device_OpenPort(ByRef ComPort As MSComm) As Long
' This routine opens the comms port
' after first settings its parameters

    On Error GoTo ErrorHandler
    
    With ComPort
        If .PortOpen = True Then
            .PortOpen = False ' Make sure that the port is closed
        End If
        DoEvents
        
        .CommPort = gnPort
        .Settings = Format$(glPortSpeed) & ",N,8,1"
        .Handshaking = comNone
        .OutBufferSize = 1
        .SThreshold = 0
        .RThreshold = 1
        .InputLen = 0
        .PortOpen = True
    End With
    Device_OpenPort = 0 ' No Error
    Exit Function
    
    
ErrorHandler:
    Device_OpenPort = Err
    ' Try and tidy up
    On Error Resume Next
    If ComPort.PortOpen = True Then
        ComPort.PortOpen = False
    End If
    
End Function


Public Function Device_TX(ByRef ComPort As MSComm, sData As String) As Long
' Sends a packet to the device

    Dim F                           As Integer
    
    
    On Error GoTo ErrorHandler
    
    'Device_EnableRX
    
    With ComPort
        For F = 1 To Len(sData)
            .Output = Mid$(sData, F, 1)
            '
            ' Give the PIC time to get the character
            ' since it dosn't have a buffer
            Do While .OutBufferCount
                DoEvents
            Loop
        Next F
        Sleep 1
    End With
    
    Exit Function
    
    
ErrorHandler:
    Device_TX = Err
End Function


Public Function Device_Reset(ByRef ComPort As MSComm) As Long
' Sends a device reset command to the device

    Dim F                       As Integer
    
    
    On Error GoTo ErrorHandler
    
    ' Send multiple resets to give all the hardware
    ' a chance to train to the communications speed
    '
    For F = 1 To 3
        If F >= 3 Then
            ' We want to see what comes back from now on
            'Device_FlushBuffer ComPort
            'Device_EnableRX
        End If
        ComPort.InBufferCount = 0
        Device_TX ComPort, "0"
    Next F
    
    Device_Reset = 0
    
    Exit Function
    
    
ErrorHandler:
    Device_Reset = Err
End Function


Public Function Device_SendDataBits(ByRef ComPort As MSComm, sBitPattern As String) As Long
' Sends the data bit pattern to the device.
' Pattern can be a maximum of 24 bits long


    Dim nTotals(3)                      As Integer ' For Ports B,D,A,E in that order
    Dim nMul                            As Integer
    Dim F                               As Integer
    Dim sBuffer                         As String
    
    Const PROC_NAME                     As String = "Device_SendDataBits"
    
    On Error GoTo ErrorHandler


    Device_TX ComPort, "3"
        
        
    '
    ' Make sure all totals = 0
    For F = 0 To 3
        nTotals(F) = 0
    Next F
    
    sBitPattern = String$(12 - (gtypModel.NumPins / 2), "1") & sBitPattern  ' All unused pins on the PIC are inputs
    sBitPattern = Left$(sBitPattern & String$(24, "1"), 24) ' Pad to 24 Bits - All unused pins on the PIC are inputs
        
        
    nMul = 128
    For F = 1 To 8
        ' Process bits for 'PORTB'
        If Mid$(sBitPattern, F, 1) = "1" Then
            nTotals(0) = nTotals(0) + nMul
        End If
        ' Process bits for 'PORTD'
        If Mid$(sBitPattern, F + 8, 1) = "1" Then
            nTotals(1) = nTotals(1) + nMul
        End If
                
        nMul = nMul / 2
    Next F
    
    '
    ' Next process PORTA
    ' This one's a bit odd in that we don't use A4 since it's an open drain pin
    ' on the PIC. So we have to fiddle about a bit here
    nMul = 32
    For F = 1 To 5
        If Mid$(sBitPattern, F + 16, 1) = "1" Then
            nTotals(2) = nTotals(2) + nMul
        End If
        If F = 1 Then
            ' Shift on one to skip A4 (decimal 16)
            nMul = nMul / 2
        End If
        nMul = nMul / 2
    Next F
        
    '
    ' Last, PORT E (only 3 bits used here)
    nMul = 4
    For F = 1 To 3
        If Mid$(sBitPattern, F + 21, 1) = "1" Then
            nTotals(3) = nTotals(3) + nMul
        End If
        nMul = nMul / 2
    Next F
    
    '
    ' Send the 4 ASCII characters to the PIC
    For F = 0 To 3
        Device_TX ComPort, Chr$(nTotals(F))
        DoEvents
    Next F
    
    Exit Function

ErrorHandler:
    ErrorRoutine Module_Name, PROC_NAME, Err, sBitPattern
End Function


Public Function Device_SendConfigBits(ByRef ComPort As MSComm, sBits As String) As Long
' Sends the device configuration info
' Pattern can be a maximum of 24 bits long
' Uses the data in the gTypModel structure


    Dim nTotals(3)                      As Integer ' For Ports B,D,A,E in that order
    Dim nMul                            As Integer
    Dim F                               As Integer
    Dim nBit                            As Integer
    Dim sBuffer                         As String
    Dim sBitPattern                     As String
    
    Const PROC_NAME                     As String = "Device_SendConfigBits"
    
    On Error GoTo ErrorHandler
    
    Device_TX ComPort, "2"
    
    '
    ' Make sure all totals = 0
    For F = 0 To 3
        nTotals(F) = 0
    Next F
            
    sBitPattern = String$(12 - (gtypModel.NumPins / 2), "1")  ' All unused pins on the PIC are inputs
    
    For F = 1 To gtypModel.NumPins
        If sBits = "" Then
            ' Use the base Configuration
            nBit = gtypModel.Pin(F).Usage
        Else
            ' Use the supplied Bit Pattern
            nBit = Val(Mid$(sBits, F, 1))
        End If
                    
        Select Case nBit
        Case 0 ' Input
            sBitPattern = sBitPattern & "0" ' PIC Pin is output to test IC
            
        Case 1, 2, 3, 4, 5 ' Output, I/O, GND, +V, N/C
            sBitPattern = sBitPattern & "1" ' PIC Pin is Input from test IC
            
        End Select
    Next F
    sBitPattern = Left$(sBitPattern & String$(24, "1"), 24) ' Pad to 24 Bits - All unused pins on the PIC are inputs
    
        
    nMul = 128
    For F = 1 To 8
        ' Process bits for 'PORTB'
        If Mid$(sBitPattern, F, 1) = "1" Then
            nTotals(0) = nTotals(0) + nMul
        End If
        ' Process bits for 'PORTD'
        If Mid$(sBitPattern, F + 8, 1) = "1" Then
            nTotals(1) = nTotals(1) + nMul
        End If
                
        nMul = nMul / 2
    Next F
    
    '
    ' Next process PORTA
    ' This one's a bit odd in that we don't use A4 since it's an open drain pin
    ' on the PIC. So we have to fiddle about a bit here
    nMul = 32
    For F = 1 To 5
        If Mid$(sBitPattern, F + 16, 1) = "1" Then
            nTotals(2) = nTotals(2) + nMul
        End If
        If F = 1 Then
            ' Shift on one to skip A4 (decimal 16)
            nMul = nMul / 2
        End If
        nMul = nMul / 2
    Next F
        
    '
    ' Last, PORT E (only 3 bits used here)
    nMul = 4
    For F = 1 To 3
        If Mid$(sBitPattern, F + 21, 1) = "1" Then
            nTotals(3) = nTotals(3) + nMul
        End If
        nMul = nMul / 2
    Next F
    
    '
    ' Send the 4 ASCII characters to the PIC
    For F = 0 To 3
        Device_TX ComPort, Chr$(nTotals(F))
        DoEvents
    Next F
    
    Exit Function
    
ErrorHandler:
    ErrorRoutine Module_Name, PROC_NAME, Err, sBits
End Function



Public Function Device_TestPowerOn(ByRef ComPort As MSComm) As Long
' Switch on the IC Test power

    
    On Error GoTo ErrorHandler
    
    Device_TX ComPort, "1"
    
    Exit Function
    
    
ErrorHandler:
    Device_TestPowerOn = Err
End Function


Public Function Device_ReadStatus(ByRef ComPort As MSComm) As Long
' Reads device status

    
    On Error GoTo ErrorHandler
    
    Device_TX ComPort, "4"
    
    Device_ReadStatus = 0
    
    Exit Function
    
    
ErrorHandler:
    Device_ReadStatus = Err
End Function

Public Function Device_SetContinMode(ByRef ComPort As MSComm) As Long
' Reads device status

    
    On Error GoTo ErrorHandler
    
    Device_TX ComPort, "5"
    
    Device_SetContinMode = 0
    
    Exit Function
    
    
ErrorHandler:
    Device_SetContinMode = Err
End Function


Public Function Device_GetVersion(ByRef ComPort As MSComm) As Long
' Reads device status

    
    On Error GoTo ErrorHandler
    
    Device_TX ComPort, "6"
    
    Device_GetVersion = 0
    
    Exit Function
    
    
ErrorHandler:
    Device_GetVersion = Err
End Function


Public Function LoadModel(sFileName As String) As Boolean
' Loads the specified model file into memory

    Dim nFileNumber                     As Integer
    Dim nLine                           As Integer
    Dim X                               As Integer
    Dim nOffset                         As Integer
    Dim sHeading                        As String
    Dim sLine                           As String
    Dim vParts                          As Variant
    
    On Error GoTo ErrorHandler
    
    Screen.MousePointer = 11
    DoEvents
    
    nFileNumber = FreeFile
    
    Set gtypModel.TestScript = Nothing
    
    Open sFileName For Input As nFileNumber
    
    nLine = 0
    Do While Not EOF(nFileNumber)
        Line Input #nFileNumber, sLine
        sLine = Trim$(sLine)
        '
        ' Remove any comment parts
        X = InStr(1, sLine, "#")
        If X > 0 Then
            sLine = Left$(sLine, X - 1) ' Remove any line comments
        End If
            
        If Len(Trim$(sLine)) > 0 Then ' There is somthing valid on this line
    
            Select Case nLine
            Case 0 ' IC Model
                gtypModel.Model = sLine
                nLine = nLine + 1
                
            Case 1 ' Description
                gtypModel.Description = sLine
                nLine = nLine + 1
                
            Case 2 ' Package Pins
                gtypModel.NumPins = Val(sLine)
                nLine = nLine + 1
                
            Case 3 ' +V Pin
                gtypModel.PinVDD = Val(sLine)
                nLine = nLine + 1
            
            Case 4 ' GND Pin
                gtypModel.PinVSS = Val(sLine)
                nLine = nLine + 1
                                
            Case 5 ' Pin detail and description lines
                vParts = Split(sLine, ",")
                gtypModel.Pin(vParts(0)).Tag = vParts(1)
                gtypModel.Pin(vParts(0)).Usage = vParts(2)

                If vParts(0) = gtypModel.NumPins Then
                    ' Last line processed
                    nLine = nLine + 10
                End If
                            
            ' case 6 to 9 not used yet
            Case Is >= 10 ' Testing script line
                vParts = Split(sLine, ",")
                gtypModel.TestScript.Add vParts(1), "L" & vParts(0)
                
            End Select
            
        End If
    Loop
    
    Close #nFileNumber
    
    LoadModel = True
    Screen.MousePointer = 0
    
    Exit Function


ErrorHandler:
    Close #nFileNumber
    LoadModel = False
    Screen.MousePointer = 0
End Function

  Public Sub ReadDefaultSettings()

    Dim F                               As Integer
    Dim X                               As Integer
    Dim vSplit                          As Variant
    
    
    Const PROC_NAME                     As String = "ReadDefaultSettings"
    
    On Error GoTo ErrorHandler
    
    gnPort = Val(GetSetting(App.Title, "Defaults", "ComPort", "1"))
    glPortSpeed = Val(GetSetting(App.Title, "Defaults", "ComSpeed", "19200"))
    
    vSplit = Split(DEFAULT_COLOURS, ",")
    ' Load in the default system colours
    For F = 0 To UBound(glColors)
        glColors(F) = GetSetting(App.Title, "Defaults", "Colours" & Format$(F), 0)
        
        If glColors(F) = 0 Then
            glColors(F) = Val(vSplit(F))
            ' Save default colours
            SaveSetting App.Title, "Defaults", "Colours" & Format$(F), glColors(F)
        End If
    Next F
    
    For F = 0 To UBound(gsPaths)
        gsPaths(F) = GetSetting(App.Title, "Defaults", "Paths" & Format$(F), "c:\")
    Next F
    
    If Trim$(UCase$(GetSetting(App.Title, "Defaults", "Beep", "YES"))) = "YES" Then
        gbBeep = True
    Else
        gbBeep = False
    End If
        
    gsSettings(0) = GetSetting(App.Title, "Defaults", "Settings" & Format$(0), "99")
    gsSettings(1) = GetSetting(App.Title, "Defaults", "Settings" & Format$(1), "4096")
    gsSettings(2) = GetSetting(App.Title, "Defaults", "Settings" & Format$(2), "1")
    
    '
    ' These are the previous power pin settings
    'gnPowerPins(0) = GetSetting(App.Title, "PowerPins", "VSS", "-1")
    'gnPowerPins(1) = GetSetting(App.Title, "PowerPins", "VDD", "-1")
    
    For F = 0 To UBound(gbOptions)
        X = Val(GetSetting(App.Title, "Defaults", "Options" & Format$(F), "-1"))
        If X = -1 Then
            ' Using default
            Select Case F
            Case 8, 7 ' Debug Mode, 8 Way Dip (OFF)
                X = 0
                
            Case Else
                X = 1
            End Select
            SaveSetting App.Title, "Defaults", "Options" & Format$(F), Format$(X)
        End If
        gbOptions(F) = X
    Next F
    
    For F = 0 To 7
        
        Select Case F
        Case 0
            gnDIPS(F, 0) = 22
            gnDIPS(F, 1) = 1
            
        Case 1
            gnDIPS(F, 0) = 20
            gnDIPS(F, 1) = 1
            
        Case 2
            gnDIPS(F, 0) = 19
            gnDIPS(F, 1) = 1
            
        Case 3
            gnDIPS(F, 0) = 12
            gnDIPS(F, 2) = 1
            
        Case Else
            gnDIPS(F, 0) = Val(GetSetting(App.Title, "PowerDIPS", "Pin" & Format$(F), "0"))
            gnDIPS(F, 1) = Val(GetSetting(App.Title, "PowerDIPS", "Pos" & Format$(F), "0"))
            gnDIPS(F, 2) = Val(GetSetting(App.Title, "PowerDIPS", "Neg" & Format$(F), "0"))
        End Select
    
    Next F
    Exit Sub
    
ErrorHandler:
    ErrorRoutine Module_Name, PROC_NAME, Err
End Sub

Public Sub RecoverFormLoadPosition(ByRef frm As Form, bPositionOnly As Boolean)

    Dim vSplit                          As Variant
        
    Const PROC_NAME                     As String = "RecoverFormLoadPosition"
    
    On Error GoTo ErrorHandler
        
    
    vSplit = Split(GetSetting(App.Title, "FormPositions", frm.Name, ""), ",")

    If UBound(vSplit) = 3 Then
        ' Registry contains valid form position settings
        With frm
            ' Can't change the width and height for this form
            If bPositionOnly = False Then
                .Width = vSplit(0)
                .Height = vSplit(1)
            End If
            .Top = vSplit(2)
            .Left = vSplit(3)
        End With
    End If
    
    Exit Sub
    
ErrorHandler:
    ErrorRoutine Module_Name, PROC_NAME, Err
End Sub


Public Function ValidateKeyPress(nKeyAscii As Integer, nValidateMode As geValidationTypes) As Integer

    If nKeyAscii = 8 Then
        ValidateKeyPress = nKeyAscii
        
    Else
        Select Case nValidateMode
        Case VALIDATE_FILENAME
            Select Case nKeyAscii
            Case 65 To 90, 97 To 122, 48 To 57 ' A to Z, a to z, 0 to 9
                ValidateKeyPress = nKeyAscii
                
            Case Else
                ValidateKeyPress = 0
                
            End Select
            
        Case VALIDATE_ALPHA
            ValidateKeyPress = nKeyAscii
            
        Case VALIDATE_NUMERIC
            Select Case nKeyAscii
            Case 48 To 57 ' 0 to 9
                ValidateKeyPress = nKeyAscii
                
            Case Else
                ValidateKeyPress = 0
                
            End Select
            
        Case VALIDATE_HEX
            Select Case nKeyAscii
            Case 48 To 57, 65 To 70 ' 0 to 9, A to F
                ValidateKeyPress = nKeyAscii
                
            Case Else
                ValidateKeyPress = 0
                
            End Select
    
        Case Else
            ' Unknown type
            nKeyAscii = 0
            
        End Select
        
    End If
    
End Function


