GFSkinEngine/GFSkinEngine_PropertyEditfrm.frm

VERSION 5.00
Begin VB.Form GFSkinEngine_PropertyEditfrm
   BorderStyle     =   1 'Fest Einfach
   Caption         =   "SE Property Edit"
   ClientHeight    =   5430
   ClientLeft      =   45
   ClientTop       =   330
   ClientWidth     =   8550
   Icon            =   "GFSkinEngine_PropertyEditfrm.frx":0000
   LinkTopic       =   "Form1"
   MaxButton       =   0   'False
   MinButton       =   0   'False
   ScaleHeight     =   5430
   ScaleWidth      =   8550
   StartUpPosition =   3 'Windows‑Standard
   Begin VB.PictureBox GFListHScrollFontSizePicture
      Enabled         =   0   'False
      Height          =   315
      Left            =   60
      ScaleHeight     =   17
      ScaleMode       =   3 'Pixel
      ScaleWidth      =   9
      TabIndex        =   6
      Top             =   0
      Visible         =   0   'False
      Width           =   195
   End
   Begin VB.CommandButton SEPE_CancelCommand
      Caption         =   "Cancel"
      Height          =   375
      Left            =   5760
      TabIndex        =   2
      Top             =   4980
      Width           =   1335
   End
   Begin VB.CommandButton SEPE_OkCommand
      Caption         =   "Ok"
      Height          =   375
      Left            =   7140
      TabIndex        =   3
      Top             =   4980
      Width           =   1335
   End
   Begin VB.TextBox SEPE_ControlPropertyText
      Height          =   4350
      Left            =   3660
      MultiLine       =   ‑1 'True
      ScrollBars      =   3 'Beides
      TabIndex        =   1
      Top             =   300
      Width           =   4815
   End
   Begin VB.ListBox SEPE_ControlNameList
      Height          =   4935
      Left            =   60
      Sorted          =   ‑1 'True
      TabIndex        =   0
      Top             =   315
      Width           =   3375
   End
   Begin VB.Line Line3
      BorderColor     =   &H80000016&
      X1              =   3660
      X2              =   8475
      Y1              =   4800
      Y2              =   4800
   End
   Begin VB.Line Line2
      BorderColor     =   &H80000015&
      X1              =   3660
      X2              =   8460
      Y1              =   4785
      Y2              =   4785
   End
   Begin VB.Line Line1
      BorderColor     =   &H80000016&
      X1              =   3555
      X2              =   3555
      Y1              =   15
      Y2              =   5310
   End
   Begin VB.Label SEPE_Label1
      Caption         =   "control name:"
      Height          =   195
      Left            =   60
      TabIndex        =   4
      Top             =   60
      Width           =   3375
   End
   Begin VB.Label SEPE_Label2
      Caption         =   "control properties:"
      Height          =   195
      Left            =   3660
      TabIndex        =   5
      Top             =   60
      Width           =   4815
   End
   Begin VB.Line SEPE_Line1
      BorderColor     =   &H80000015&
      X1              =   3540
      X2              =   3540
      Y1              =   0
      Y2              =   5280
   End
End
Attribute VB_Name = "GFSkinEngine_PropertyEditfrm"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
'(c)2001 by Louis. Part of the GFSkinEngine project.
'
'NOTE: this form allows the user to edit the properties of all controls in the current SkinDataFile.
'Therefore the current SkinDataFile is copied into a temp file in the current skin's directory.
'Any changes are done to this temp file. When the user presses 'Ok', the temp file is copied into
'the current SkinDataFile. Note that this form should be shown in vbModal state to verify that
'the user cannot change the original SkinDataFile.
'
'SEPE_TempFile_Create
Private Declare Function CopyFile Lib "kernel32" Alias "CopyFileA" (ByVal lpExistingFileName As StringByVal lpNewFileName As StringByVal bFailIfExists As Long) As Long
'GFListHScroll
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As LongByVal wMsg As LongByVal wParam As LongByVal lParam As Long) As Long
'GFListHScroll
Const LB_SETHORIZONTALEXTENT = &H194
'SEPE_TempFileStruct
Private Type SEPE_TempFileStruct
    TempFile As String
End Type
Dim SEPE_TempFileStructVar As SEPE_TempFileStruct
'SEPE_PropertyStringStruct ‑ contains a property string (including Chr$(13) and Chr$(10)) and source information
Private Type SEPE_PropertyStringStruct
    PropertyStringStartPos As Long 'position in SkinDataFile
    PropertyStringEndPos As Long
    PropertyString As String
End Type
Dim SEPE_PropertyStringStructVar As SEPE_PropertyStringStruct
'SEPE_HideControlStruct ‑ used to prevent special controls from being added
Private Type SEPE_HideControlStruct
    ControlName As String
End Type
Dim SEPE_HideControlStructNumber As Integer
Dim SEPE_HideControlStructArray() As SEPE_HideControlStruct
'other
Public DisplayPaletteFlag As Boolean 'if True, the sub that opened this form in vbModal state must call SE_DisplayPalette() and reset the flag
Dim ChangesExistingFlag As Boolean 'True if text box content has been changed at least once

Private Sub Form_Load()
    'on error resume next
    'nothing to do
End Sub

Private Sub SEPE_ControlNameList_Click()
    'on error resume next
    If Not (SEPE_ControlNameList.ListIndex = True) Then
        Call SEPE_ControlPropertyText_LoadProperties(SEPE_ControlNameList.List(SEPE_ControlNameList.ListIndex))
    End If
End Sub

Private Sub SEPE_OkCommand_Click()
    'on error resume next
    Call SEPE_Save
    Call SEPE_TempFile_Delete 'reset
    ChangesExistingFlag = False 'reset
    Unload Me
End Sub

Private Sub SEPE_CancelCommand_Click()
    'on error resume next
    Call SEPE_TempFile_Delete 'reset
    ChangesExistingFlag = False 'reset
    Unload Me
End Sub

'************************************SEPE DISPLAYING************************************
'NOTE: the following code makes SE data visible to the user.

Private Sub SEPE_ControlNameList_Reload(ByVal SEControlStructNumber As IntegerByRef SEControlStructArray() As SEControlStruct)
    'on error resume next
    Dim StructLoop As Integer
    'reset
    SEPE_ControlNameList.Clear 'reset
    'begin
    For StructLoop = 1 To SEControlStructNumber
        If SEPE_HideControl_IsToBeHidden(SEControlStructArray(StructLoop).SEControlName) = False Then
            'NOTE: some controls may not be displayed as the user is not allowed to edit their properties.
            SEPE_ControlNameList.AddItem SEControlStructArray(StructLoop).SEControlName
        End If
    Next StructLoop
    Call GFListHScroll_AddScrollBars(SEPE_ControlNameList)
End Sub

Public Sub SEPE_ControlNameList_LoadProperties(ByVal ControlName As String)
    'on error resume next
    Dim TestLoop As Integer
    'begin
    Call SEPE_ControlNameList_Reload(SEControlStructNumber, SEControlStructArray())
    For TestLoop = 1 To SEPE_ControlNameList.ListCount
        If SEPE_ControlNameList.List(TestLoop ‑ 1) = ControlName Then
            SEPE_ControlNameList.ListIndex = TestLoop ‑ 1
            Call SEPE_ControlPropertyText_LoadProperties(ControlName)
            Exit For
        End If
    Next TestLoop
End Sub

Private Sub SEPE_ControlPropertyText_LoadProperties(ByVal ControlName As String)
    'on error resume next
    Dim SEControlStructIndex As Integer
    Dim SEControlType As Integer
    'preset
    SEControlStructIndex = GetSEControlStructIndex(ControlName)
    If Not (SEControlStructIndex = 0) Then 'verify
        SEControlType = SEControlStructArray(SEControlStructIndex).SEControlType
    Else
        SEControlType = 0 'reset (error)
    End If
    'begin
    Call Skin_DecryptFile(SE_GetSkinDataFile)
    SEPE_PropertyStringStructVar = SEPE_GetPropertyString(ControlName, SEControlType, SEPE_TempFile_Create(SE_GetSkinDataFile))
    Call Skin_EncryptFile(SE_GetSkinDataFile)
    SEPE_ControlPropertyText.TEXT = SEPE_PropertyStringStructVar.PropertyString
End Sub

Private Sub SEPE_ControlPropertyText_LostFocus()
    'on error resume next
    Dim PropertyString As String
    Dim TempFile As String 'temporary temp file, not the copy of the SkinDataFile
    '
    'NOTE: when this text box loses focus the contained property
    'string is written at its original location in the temp file.
    '
    If Not ((Dir$(SEPE_TempFileStructVar.TempFile) = "") Or (Right$(SEPE_TempFileStructVar.TempFile, 1) = "\") Or (SEPE_TempFileStructVar.TempFile = "")) Then 'verify
        If Not (SEPE_ControlPropertyText.TEXT = SEPE_PropertyStringStructVar.PropertyString) Then 'verify changes were made
            TempFile = GenerateTempFileName(GetDirectoryName(SEPE_TempFileStructVar.TempFile)) 'current skin directory
            If Not (TempFile = "") Then 'verify
                ChangesExistingFlag = True 'see Form_Unload()
                PropertyString = SEPE_ControlPropertyText.TEXT
                Call RemoveBorderBelow32(PropertyString)
                If Not (Len(PropertyString) = 0) Then PropertyString = PropertyString + Chr$(13) + Chr$(10) + Chr$(13) + Chr$(10)
                'NOTE: the PropertyString will contain only one empty lines at its end by default.
                'NOTE: if PropertyString is "" then it will be set to Chr$(13) + Chr$(10).
                If Not (Left$(PropertyString, 2) = Chr$(13) + Chr$(10)) Then PropertyString = Chr$(13) + Chr$(10) + PropertyString 'verify (see code that reads property string for annotations)
                If Not (Right$(PropertyString, 2) = Chr$(13) + Chr$(10)) Then PropertyString = PropertyString + Chr$(13) + Chr$(10) 'verify (see code that reads property string for annotations)
                If ReplaceStringInFile(SEPE_TempFileStructVar.TempFile, TempFile, PropertyString, SEPE_PropertyStringStructVar.PropertyStringStartPos, SEPE_PropertyStringStructVar.PropertyStringEndPos) = True Then 'verify
                    If CopyFile(TempFile, SEPE_TempFileStructVar.TempFile, 0) = 0 Then GoTo Error: 'verify
                    If Not ((Dir$(TempFile) = "") Or (Right$(TempFile, 1) = "\") Or (TempFile = "")) Then Kill TempFile
                Else
                    GoTo Error:
                End If
            Else
                GoTo Error:
            End If
        End If
    End If
    Exit Sub
Error:
    MsgBox "internal error in SEPE_ControlPropertyText_LostFocus() !", vbOKOnly + vbExclamation
    If Not ((Dir$(TempFile) = "") Or (Right$(TempFile, 1) = "\") Or (TempFile = "")) Then Kill TempFile 'make sure file is deleted
    Exit Sub
End Sub

Private Function SEPE_GetPropertyString(ByVal ControlName As StringByVal ControlType As IntegerByVal SkinDataFile As String) As SEPE_PropertyStringStruct
    'on error resume next
    Dim SkinDataFileNumber As Integer
    Dim SkinDataFileString As String
    Dim StartPos As Long
    Dim EndPos As Long
    Dim Temp As Long
    '
    'NOTE: no SkinDataFile property line may begin with '[', except a control name line.
    '
    'preset
    SkinDataFileNumber = FreeFile(0)
    'begin
    If Not ((Dir$(SkinDataFile) = "") Or (Right$(SkinDataFile, 1) = "\") Or (SkinDataFile = "")) Then 'verify
        Open SkinDataFile For Binary As #SkinDataFileNumber
            SkinDataFileString = String$(LOF(SkinDataFileNumber), Chr$(0))
            Get #SkinDataFileNumber, 1, SkinDataFileString
        Close #SkinDataFileNumber
        StartPos = InStr(1, SkinDataFileString, "[" + ControlName + "]", vbBinaryCompare)
        If Not (StartPos = 0) Then
            '
            'NOTE: a property string ends at file end, before the next control name
            'or, if the control type is not SECONTROLTYPE_PSEUDOCONTROL,
            'before a 'system_[...]' line.
            'A 'system_[...]' line must not be located right within the properties of a
            'control but only after them.
            '
            EndPos = InStr(StartPos + 1, SkinDataFileString, Chr$(13) + Chr$(10) + "[", vbBinaryCompare) + 1
            If Not (ControlType = SECONTROLTYPE_PSEUDOCONTROL) Then
                Temp = InStr(StartPos + 1, SkinDataFileString, Chr$(13) + Chr$(10) + "system_", vbTextCompare) + 1
                If Not (Temp = 1) Then 'verify (important)
                    If Temp < EndPos Then EndPos = Temp
                End If
            End If
            If EndPos = 1 Then EndPos = FileLen(SkinDataFile) 'verify
            '
            'NOTE: the returned string is at least Chr$(13) + Chr$(10) when
            'there are no properties below the control name.
            'When a property string is written into the SkinDataFile, it must be
            'bordered by Chr$(13) + Chr$(10) at both sides.
            'StartPos points to a Chr$(13) and EndPos to a Chr$(10).
            '
            SEPE_GetPropertyString.PropertyStringStartPos = StartPos + 2 + Len(ControlName)
            SEPE_GetPropertyString.PropertyStringEndPos = EndPos
            If Not ((SEPE_GetPropertyString.PropertyStringEndPos ‑ SEPE_GetPropertyString.PropertyStringStartPos) < 0) Then 'verify
                SEPE_GetPropertyString.PropertyString = FormatLine(Mid$(SkinDataFileString, SEPE_GetPropertyString.PropertyStringStartPos, (SEPE_GetPropertyString.PropertyStringEndPos ‑ SEPE_GetPropertyString.PropertyStringStartPos + 1)))
                Exit Function 'ok
            Else
                GoTo Error:
            End If
        Else
            GoTo Error:
        End If
    Else
        GoTo Error:
    End If
    Exit Function
Error:
    SEPE_GetPropertyString.PropertyStringStartPos = 0 'reset (error)
    SEPE_GetPropertyString.PropertyStringEndPos = 0 'reset (error)
    SEPE_GetPropertyString.PropertyString = "" 'reset (error)
    Exit Function 'error
End Function

'********************************END OF SEPE DISPLAYING*********************************
'**************************************SEPE SAVING**************************************
'NOTE: the following code applies changes to the current SkinDataFile.
'Changes are done to a temp file until SEPE_Save is called, then the temp file
'is copied into the current skin's SkinDataFile.

Private Function SEPE_TempFile_Create(ByVal SkinDataFile As String) As String
    'on error resume next 'returns path to a copy of current SkinDataFile or nothing ("") for error
    '
    'NOTE: the temp file is created once only, if it is already existing
    'this functions returns the path of the existing temp file.
    'Use SEPE_TempFile_Delete before calling this function to create
    'a new temp file.
    '
    If Not ((Dir$(SkinDataFile) = "") Or (Right$(SkinDataFile, 1) = "\") Or (SkinDataFile = "")) Then 'verify
        If SEPE_TempFileStructVar.TempFile = "" Then
            SEPE_TempFileStructVar.TempFile = GenerateTempFileName(GetDirectoryName(SkinDataFile))
            If CopyFile(SkinDataFile, SEPE_TempFileStructVar.TempFile, 0) = 0 Then GoTo Error: 'verify (do not use FileCopy, does not work correctly on network drives)
        End If
        If Not (SEPE_TempFileStructVar.TempFile = "") Then 'verify
            SEPE_TempFile_Create = SEPE_TempFileStructVar.TempFile
        Else
            GoTo Error:
        End If
    Else
        GoTo Error:
    End If
    Exit Function
Error:
    SEPE_TempFile_Create = "" 'reset (error)
    Exit Function
End Function

Private Sub SEPE_TempFile_Delete()
    'on error resume next 'deletes current temp file
    If Not ((Dir$(SEPE_TempFileStructVar.TempFile) = "") Or (Right$(SEPE_TempFileStructVar.TempFile, 1) = "\") Or (SEPE_TempFileStructVar.TempFile = "")) Then 'verify
        Kill SEPE_TempFileStructVar.TempFile
        SEPE_TempFileStructVar.TempFile = "" 'reset
    End If
End Sub

Private Sub SEPE_Save()
    'on error resume next
    If Not ((Dir$(SEPE_TempFileStructVar.TempFile) = "") Or (Right$(SEPE_TempFileStructVar.TempFile, 1) = "\") Or (SEPE_TempFileStructVar.TempFile = "")) Then
        If ChangesExistingFlag = True Then 'check if user made changes
ReDo:
            If Not (CopyFile(SEPE_TempFileStructVar.TempFile, SE_GetSkinDataFile, 0) = 0) Then 'verify
                Call Skin_EncryptFile(SE_GetSkinDataFile)
                DisplayPaletteFlag = True 'global flag, processed by sub that opened this form in vbModal state
            Else
                Select Case MsgBox("internal error in SEPE_Save() (GFSkinEngine): file copy failed: " + Chr$(10) + SEPE_TempFileStructVar.TempFile + " ‑> " + SE_GetSkinDataFile + " !", vbRetryCancel)
                Case vbRetry
                    GoTo ReDo:
                Case vbCancel
                    'continue, send TempFile to hell
                End Select
            End If
        End If
    End If
End Sub

'**********************************END OF SEPE SAVING***********************************
'***********************************SEPE HIDE CONTROL***********************************
'NOTE: the target project can call SEPE_HideControl_AddControl() to prevent any special SE control
'from being shown in SEPE_ControlNameList (so that the user cannot edit the control's properties).
'Controls that should not be edited by the user are those which display logos, copyrights, etc.

Public Sub SEPE_HideControl_Add(ByVal ControlName As String)
    'on error resume next
    Dim StructLoop As Integer
    '
    'NOTE: any control that was passed to this sub cannot be edited
    'by the user as it will not be displayed in SEPE_ControlNameList.
    '
    'verify
    For StructLoop = 1 To SEPE_HideControlStructNumber
        If SEPE_HideControlStructArray(StructLoop).ControlName = ControlName Then  'case sensitive
            Exit Sub 'control was already added
        End If
    Next StructLoop
    'begin
    If Not (SEPE_HideControlStructNumber = 32766) Then 'verify
        SEPE_HideControlStructNumber = SEPE_HideControlStructNumber + 1
    Else
        MsgBox "internal error in SEPE_HideControl_Add() (GFSkinEngine): overflow !", vbOKOnly + vbExclamation
        Exit Sub 'error
    End If
    ReDim Preserve SEPE_HideControlStructArray(1 To SEPE_HideControlStructNumber) As SEPE_HideControlStruct
    SEPE_HideControlStructArray(SEPE_HideControlStructNumber).ControlName = ControlName
    Exit Sub
End Sub

Private Function SEPE_HideControl_IsToBeHidden(ByVal ControlName As String) As Boolean
    'on error resume next 'returns True if passed control should not appear in SEPE_ControlNameList, False if it should appear there
    Dim StructLoop As Integer
    'begin
    For StructLoop = 1 To SEPE_HideControlStructNumber
        If SEPE_HideControlStructArray(StructLoop).ControlName = ControlName Then 'case sensitive
            SEPE_HideControl_IsToBeHidden = True 'do not allow editing control properties
            Exit Function
        End If
    Next StructLoop
    SEPE_HideControl_IsToBeHidden = False 'allow editing control properties
    Exit Function
End Function

'*******************************END OF SEPE HIDE CONTROL********************************
'***********************************GENERAL FUNCTIONS***********************************

Private Sub GFListHScroll_AddScrollBars(ByRef TargetList As ListBox)
    'on error resume next 'this sub requires GFListHScrollFontSizePicture to be located on current form
    Dim TextWidthMax As Long
    Dim Temp As Long
    'preset
    GFListHScrollFontSizePicture.Font.Name = TargetList.Font.Name
    GFListHScrollFontSizePicture.Font.Size = TargetList.Font.Size
    GFListHScrollFontSizePicture.Font.Bold = TargetList.Font.Bold
    GFListHScrollFontSizePicture.Font.Italic = TargetList.Font.Italic
    GFListHScrollFontSizePicture.Font.Weight = TargetList.Font.Weight
    GFListHScrollFontSizePicture.Font.Charset = TargetList.Font.Charset
    'begin
    For Temp = 1 To TargetList.ListCount
        If GFListHScrollFontSizePicture.TextWidth(TargetList.List(Temp ‑ 1)) > TextWidthMax Then
            TextWidthMax = GFListHScrollFontSizePicture.TextWidth(TargetList.List(Temp ‑ 1))
        End If
    Next Temp
    Call SendMessageLong(TargetList.hwnd, LB_SETHORIZONTALEXTENT, TextWidthMax + 15, ByVal 0&) '15 pixels for v scroll bar
End Sub

Private Function GetDirectoryName(ByVal GetDirectoryNameName As String) As String
    'On Error Resume Next 'returns chars from string beginning to (including) last backslash or nothing
    Dim GetDirectoryNameLoop As Integer
    GetDirectoryName = "" 'reset
    For GetDirectoryNameLoop = Len(GetDirectoryNameName) To 1 Step (‑1)
        If Mid$(GetDirectoryNameName, GetDirectoryNameLoop, 1) = "\" Then
            GetDirectoryName = Left$(GetDirectoryNameName, GetDirectoryNameLoop)
            Exit For
        End If
    Next GetDirectoryNameLoop
End Function

Private Sub RemoveBorderBelow32(ByRef InputString As String)
    'on error resume next 'use to cut empty lines at a string's start or end; pass short strings only (slow)
    If Len(InputString) Then 'verify
        Do While Asc(Left$(InputString, 1)) < 32
            InputString = Right$(InputString, Len(InputString) ‑ 1)
            If Len(InputString) = 0 Then Exit Do 'verify
        Loop
    End If
    If Len(InputString) Then 'verify
        Do While Asc(Right$(InputString, 1)) < 32
            InputString = Left$(InputString, Len(InputString) ‑ 1)
            If Len(InputString) = 0 Then Exit Do 'verify
        Loop
    End If
End Sub

Private Function FormatLine(ByVal FormatLineLine As String) As String
    'On Error Resume Next 'removes Asc() < 32 at start and end of passed string
    FormatLine = FormatLineLine
    If Not (FormatLine = "") Then
        Do While (Asc(Left$(FormatLine, 1))) < 32
            FormatLine = Right$(FormatLine, Len(FormatLine) ‑ 1)
            If FormatLine = "" Then Exit Function
        Loop
        Do While (Asc(Right$(FormatLine, 1))) < 32
            FormatLine = Left$(FormatLine, Len(FormatLine) ‑ 1)
            If FormatLine = "" Then Exit Function
        Loop
    End If
End Function

Private Function ReplaceStringInFile(ByVal InputName As StringByVal TempFile As StringByRef Replace_String As StringByVal Replace_StartPos As LongByVal Replace_EndPos As Long) As Boolean 'used by PPCsys
    On Error GoTo Error: 'returns True in case of success, False if an error occurs
    Dim InputNameNumber As Integer
    Dim TempFileNumber As Integer
    '
    'NOTE: use this function to put a string into another at a fixed location.
    'Files are used to allow working with large strings without running out of memory.
    'The string to change must be written into the file InputName manually, and the
    'changed string read out of TempFile. This is not done automatically as sometimes
    'strings are not necessary (replace file parts only).
    '
    'verify files
    If ((Dir$(InputName) = "") Or (Right$(InputName, 1) = "\") Or (InputName = "")) Then
        GoTo Error:
    End If
    If ((Right$(TempFile, 1) = "\") Or (TempFile = "")) Then
        GoTo Error:
    End If
    'end
    InputNameNumber = FreeFile(0)
    Open InputName For Binary As #InputNameNumber
    'verify replace start‑ and end pos
    Select Case Replace_StartPos
    Case Is < 1
        GoTo Error:
    Case Is > LOF(InputNameNumber)
        GoTo Error:
    End Select
    Select Case Replace_EndPos
    Case Is < Replace_StartPos
        GoTo Error:
    Case Is > LOF(InputNameNumber)
        GoTo Error:
    End Select
    'end
    TempFileNumber = FreeFile(0)
    Open TempFile For Output As #TempFileNumber
        Dim BlockString As String
        Dim BlockStartPos As Long
        Dim BlockLength As Long
        For BlockStartPos = 1 To (Replace_StartPos ‑ 1) Step 128000
            BlockLength = 128000
            If (Replace_StartPos ‑ BlockStartPos) < BlockLength Then
                BlockLength = (Replace_StartPos ‑ BlockStartPos)
            End If
            BlockString = String$(BlockLength, Chr$(0))
            Get #InputNameNumber, BlockStartPos, BlockString
            Print #TempFileNumber, BlockString;
        Next BlockStartPos
        Print #TempFileNumber, Replace_String;
        For BlockStartPos = (Replace_EndPos + 1) To LOF(InputNameNumber) Step 128000
            BlockLength = 128000
            If (LOF(InputNameNumber) ‑ BlockStartPos + 1) < BlockLength Then
                BlockLength = (LOF(InputNameNumber) ‑ BlockStartPos + 1)
            End If
            BlockString = String$(BlockLength, Chr$(0))
            Get #InputNameNumber, BlockStartPos, BlockString
            Print #TempFileNumber, BlockString;
        Next BlockStartPos
    Close #TempFileNumber
    Close #InputNameNumber
    ReplaceStringInFile = True 'default (no error)
    Exit Function
Error:
    On Error GoTo 0
    On Error Resume Next 'important
    Close #TempFileNumber
    Close #InputNameNumber
    ReplaceStringInFile = False 'error
    Exit Function
End Function

Private Function GenerateTempFileName(ByVal TempFilePath As String) As String
    'On Error Resume Next 'returns name of a non‑existing file in TempFilePath, file name has following format: ########.tmp
    Dim GenerateTempFileTemp As Integer
    If (Not (Right$(TempFilePath, 1) = "\")) And (Not (TempFilePath = "")) Then
        TempFilePath = TempFilePath + "\"
    End If
    Do
        GenerateTempFileName = TempFilePath + Format$((Rnd(1) * 1E+08!), "00000000") + ".tmp"
        GenerateTempFileTemp = GenerateTempFileTemp + 1 'just to make sure
    Loop Until (Dir$(GenerateTempFileName) = "") Or (GenerateTempFileTemp = 32767)
End Function

Private Sub Form_Unload(Cancel As Integer)
    'on error resume next
    If ChangesExistingFlag = True Then
        ChangesExistingFlag = False 'reset
        If MsgBox("Save changes ?", vbYesNo + vbExclamation) = vbYes Then
            Call SEPE_Save
        End If
    End If
    Call SEPE_TempFile_Delete 'reset
    Me.Visible = False
    Me.Enabled = False
    Me.Refresh
End Sub


[END OF FILE]