home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 1_2002.ISO / Data / Zips / TinyServer253258252001.psc / frmServer.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  2001-07-18  |  19.5 KB  |  555 lines

  1. VERSION 5.00
  2. Object = "{248DD890-BB45-11CF-9ABC-0080C7E7B78D}#1.0#0"; "MSWINSCK.OCX"
  3. Begin VB.Form Server 
  4.    BorderStyle     =   1  'Fixed Single
  5.    Caption         =   "Tiny Server"
  6.    ClientHeight    =   4365
  7.    ClientLeft      =   150
  8.    ClientTop       =   435
  9.    ClientWidth     =   7455
  10.    Icon            =   "frmServer.frx":0000
  11.    LinkTopic       =   "Form1"
  12.    MaxButton       =   0   'False
  13.    MouseIcon       =   "frmServer.frx":030A
  14.    ScaleHeight     =   4365
  15.    ScaleWidth      =   7455
  16.    StartUpPosition =   3  'Windows Default
  17.    Begin VB.Timer Timer1 
  18.       Interval        =   1000
  19.       Left            =   4680
  20.       Top             =   360
  21.    End
  22.    Begin VB.CommandButton Configure 
  23.       Caption         =   "Configure Server"
  24.       Height          =   375
  25.       Left            =   5520
  26.       TabIndex        =   3
  27.       Top             =   240
  28.       Width           =   1335
  29.    End
  30.    Begin VB.CommandButton StopButton 
  31.       Caption         =   "Stop Server"
  32.       Height          =   375
  33.       Left            =   3060
  34.       TabIndex        =   2
  35.       Top             =   240
  36.       Width           =   1335
  37.    End
  38.    Begin VB.CommandButton StartButton 
  39.       Caption         =   "Start Server"
  40.       Height          =   375
  41.       Left            =   600
  42.       TabIndex        =   1
  43.       Top             =   240
  44.       Width           =   1335
  45.    End
  46.    Begin VB.TextBox TextBox 
  47.       Height          =   2895
  48.       Left            =   120
  49.       Locked          =   -1  'True
  50.       MultiLine       =   -1  'True
  51.       ScrollBars      =   3  'Both
  52.       TabIndex        =   0
  53.       Top             =   1080
  54.       Width           =   7215
  55.    End
  56.    Begin MSWinsockLib.Winsock tcpServer 
  57.       Index           =   0
  58.       Left            =   6960
  59.       Top             =   240
  60.       _ExtentX        =   741
  61.       _ExtentY        =   741
  62.       _Version        =   393216
  63.       LocalPort       =   80
  64.    End
  65.    Begin VB.Label Label3 
  66.       Caption         =   "Website :"
  67.       Height          =   255
  68.       Left            =   2040
  69.       TabIndex        =   6
  70.       Top             =   4080
  71.       Width           =   735
  72.    End
  73.    Begin VB.Label Label2 
  74.       BackStyle       =   0  'Transparent
  75.       Caption         =   "http://connect.to/tinyserver"
  76.       BeginProperty Font 
  77.          Name            =   "MS Sans Serif"
  78.          Size            =   8.25
  79.          Charset         =   0
  80.          Weight          =   700
  81.          Underline       =   -1  'True
  82.          Italic          =   0   'False
  83.          Strikethrough   =   0   'False
  84.       EndProperty
  85.       ForeColor       =   &H8000000D&
  86.       Height          =   255
  87.       Left            =   2880
  88.       MouseIcon       =   "frmServer.frx":074C
  89.       MousePointer    =   99  'Custom
  90.       TabIndex        =   5
  91.       ToolTipText     =   "Click to visit the TinyServer Website"
  92.       Top             =   4080
  93.       Width           =   2535
  94.    End
  95.    Begin VB.Label Label1 
  96.       Caption         =   "Message Window"
  97.       BeginProperty Font 
  98.          Name            =   "MS Sans Serif"
  99.          Size            =   8.25
  100.          Charset         =   0
  101.          Weight          =   400
  102.          Underline       =   -1  'True
  103.          Italic          =   0   'False
  104.          Strikethrough   =   0   'False
  105.       EndProperty
  106.       Height          =   255
  107.       Left            =   3060
  108.       TabIndex        =   4
  109.       Top             =   840
  110.       Width           =   1335
  111.    End
  112.    Begin VB.Menu mnuPopup 
  113.       Caption         =   "Popup"
  114.       Visible         =   0   'False
  115.       Begin VB.Menu mnuShow 
  116.          Caption         =   "Show TinyServer"
  117.       End
  118.       Begin VB.Menu mnuStartServer 
  119.          Caption         =   "Start Server"
  120.       End
  121.       Begin VB.Menu mnuStopServer 
  122.          Caption         =   "Stop Server"
  123.       End
  124.       Begin VB.Menu mnuConfigure 
  125.          Caption         =   "Configure"
  126.       End
  127.       Begin VB.Menu mnuAbout 
  128.          Caption         =   "About"
  129.       End
  130.       Begin VB.Menu mnuExit 
  131.          Caption         =   "Exit"
  132.       End
  133.    End
  134. Attribute VB_Name = "Server"
  135. Attribute VB_GlobalNameSpace = False
  136. Attribute VB_Creatable = False
  137. Attribute VB_PredeclaredId = True
  138. Attribute VB_Exposed = False
  139. Option Explicit
  140. 'Declare a user-defined variable to pass to the Shell_NotifyIcon
  141. 'function.
  142. Private Type NOTIFYICONDATA
  143.     cbSize As Long
  144.     hwnd As Long
  145.     uId As Long
  146.     uFlags As Long
  147.     uCallBackMessage As Long
  148.     hIcon As Long
  149.     szTip As String * 64
  150. End Type
  151. 'The following constants are the messages sent to the
  152. 'Shell_NotifyIcon function to add, modify, or delete an icon from the
  153. 'taskbar status area.
  154. Private Const NIM_ADD = &H0
  155. Private Const NIM_MODIFY = &H1
  156. Private Const NIM_DELETE = &H2
  157. 'The following constant is the message sent when a mouse event occurs
  158. 'within the rectangular boundaries of the icon in the taskbar status
  159. 'area.
  160. Private Const WM_MOUSEMOVE = &H200
  161. 'The following constants are the flags that indicate the valid
  162. 'members of the NOTIFYICONDATA data type.
  163. Private Const NIF_MESSAGE = &H1
  164. Private Const NIF_ICON = &H2
  165. Private Const NIF_TIP = &H4
  166. 'The following constants are used to determine the mouse input on the
  167. 'the icon in the taskbar status area.
  168. 'Left-click constants.
  169. Private Const WM_LBUTTONDBLCLK = &H203   'Double-click
  170. Private Const WM_LBUTTONDOWN = &H201     'Button down
  171. Private Const WM_LBUTTONUP = &H202       'Button up
  172. 'Right-click constants.
  173. Private Const WM_RBUTTONDBLCLK = &H206   'Double-click
  174. Private Const WM_RBUTTONDOWN = &H204     'Button down
  175. Private Const WM_RBUTTONUP = &H205       'Button up
  176. 'Declare the API function call.
  177. Private Declare Function Shell_NotifyIcon Lib "shell32" _
  178.     Alias "Shell_NotifyIconA" _
  179.     (ByVal dwMessage As Long, pnid As NOTIFYICONDATA) As Boolean
  180. Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
  181. 'Dimension a variable as the user-defined data type.
  182. Dim nid As NOTIFYICONDATA
  183. 'Maximum no of connections
  184. Private Const MAX_CONNECTIONS = 100
  185. 'Time in seconds for connection timeout
  186. Private Const MAX_TIME = 4
  187. Dim timeOut(1 To MAX_CONNECTIONS) As Integer
  188. Private Sub Form_Load()
  189.     'Terminate if already running
  190.     If App.PrevInstance Then
  191.         MsgBox "TinyServer already running...", vbInformation
  192.         End
  193.     End If
  194.     Dim sFile As String
  195.     sFile = Space(256)
  196.     sFile = Left(sFile, GetCurrentDirectory(Len(sFile), sFile))
  197.     sFile = sFile & "\server.ini"
  198.     Dim i As Long
  199.         For i = 1 To MAX_CONNECTIONS
  200.             Load tcpServer(i)
  201.         Next
  202.     wwwRoot = Space(256)
  203.     wwwRoot = Left(wwwRoot, GetPrivateProfileString("config", "wwwroot", "NULL", wwwRoot, Len(wwwRoot), sFile))
  204.     DefaultPage = Space(64)
  205.     DefaultPage = Left(DefaultPage, GetPrivateProfileString("config", "defaultpage", "NULL", DefaultPage, Len(DefaultPage), sFile))
  206.     PortNum = GetPrivateProfileInt("config", "port", 0, sFile)
  207.     If StrComp(wwwRoot, "NULL") = 0 Or StrComp(DefaultPage, "NULL") = 0 Or PortNum = 0 Then
  208.         sFile = Left(sFile, GetCurrentDirectory(Len(sFile), sFile))
  209.         wwwRoot = sFile
  210.         DefaultPage = "index.htm"
  211.         PortNum = 80
  212.         WritePrivateProfileString "config", "wwwroot", sFile, sFile + "\server.ini"
  213.         sFile = sFile + "\server.ini"
  214.         WritePrivateProfileString "config", "defaultpage", "index.htm", sFile
  215.         WritePrivateProfileString "config", "port", Str(80), sFile
  216.         MsgBox "Configuration file not found or corrupted, defaults loaded", vbInformation
  217.     End If
  218.     setSysTrayIcon
  219. End Sub
  220. Private Sub Label2_Click()
  221.     Call ShellExecute(0, "open", _
  222.         "http://connect.to/tinyserver", _
  223.         vbNullString, vbNullString, 1)
  224. End Sub
  225. Private Sub StartButton_Click()
  226.     ' Set the LocalPort property to an integer.
  227.     ' Then invoke the Listen method.
  228.     If tcpServer(0).State <> sckListening Then
  229.         tcpServer(0).LocalPort = PortNum
  230.         tcpServer(0).Listen
  231.         TextBox.Text = "TinyServer started . . ." + vbCrLf + "Listening on port : " + Str(PortNum) + vbCrLf
  232.     Else
  233.         TextBox.Text = TextBox.Text + vbCrLf + "TinyServer already started!!!"
  234.     End If
  235. End Sub
  236. Private Sub StopButton_Click()
  237.     If tcpServer(0).State <> sckListening Then
  238.         TextBox.Text = TextBox.Text + vbCrLf + "TinyServer not running!!!"
  239.         Exit Sub
  240.     End If
  241.     tcpServer(0).Close
  242.     If tcpServer(0).State <> sckListening Then
  243.         TextBox.Text = TextBox.Text + vbCrLf + "TinyServer stopped..." + vbCrLf
  244.     End If
  245. End Sub
  246. Private Sub Configure_Click()
  247.     Dim fOptions As New frmOptions
  248.     If tcpServer(0).State = sckListening Then
  249.         MsgBox "Please stop the server before configuring", vbExclamation
  250.     Else
  251.         fOptions.Show vbModal
  252.     End If
  253. End Sub
  254. Private Sub tcpServer_ConnectionRequest _
  255. (Index As Integer, ByVal requestID As Long)
  256.     Dim i As Integer
  257.     ' Accept the request with the requestID
  258.     ' parameter.
  259.     If Index = 0 Then
  260.         For i = 1 To 100
  261.             If tcpServer(i).State = sckClosed Then
  262.                 tcpServer(i).LocalPort = 0
  263.                 tcpServer(i).Accept requestID
  264.                 TextBox.Text = TextBox.Text + vbCrLf + "Connection from : " + tcpServer(i).RemoteHostIP
  265.                 Exit For
  266.             End If
  267.         Next i
  268.     End If
  269. End Sub
  270. Private Sub tcpServer_DataArrival(Index As Integer, ByVal bytesTotal As Long)
  271.     Dim a As Integer
  272.     Dim inData As String
  273.     tcpServer(Index).GetData inData
  274.     Call serveRequest(Index, inData)
  275.     'tcpServer(Index).Close
  276. End Sub
  277. Private Sub serveRequest(ind As Integer, inData As String)
  278.     Dim rServer As Winsock
  279.     Dim i As Integer
  280.     Dim fileNum As Integer
  281.     Dim Method As String
  282.     Dim Request As String
  283.     Dim lRequest As String
  284.     Dim httpVersion As String
  285.     Dim Accept() As String
  286.     Dim AcceptLanguage As String
  287.     Dim UserAgent As String
  288.     Dim Connection As String
  289.     Dim Referer As String
  290.     Dim Host As String
  291.     Dim AcceptEncoding As String
  292.     Dim Cookie As String
  293.     Dim SplitHeader() As String
  294.     Dim SplitTemp() As String
  295.     Dim sFile As String
  296.     Dim outData As String
  297.     Dim fileDate As Date
  298.     i = 1
  299.     Set rServer = tcpServer(ind)
  300.     SplitHeader = Split(inData, vbCrLf)
  301.     SplitTemp = Split(SplitHeader(0))
  302.     Method = SplitTemp(0)
  303.     Request = SplitTemp(1)
  304.     httpVersion = SplitTemp(2)
  305.     While StrComp(SplitHeader(i), "") <> 0
  306.         SplitTemp = Split(SplitHeader(i), ": ")
  307.         Select Case SplitTemp(0)
  308.         Case "Accept"
  309.         Accept = Split(SplitTemp(1), ", ")
  310.         Case "Accept-Language"
  311.         AcceptLanguage = SplitTemp(1)
  312.         Case "Accept-Encoding"
  313.         AcceptEncoding = SplitTemp(1)
  314.         Case "User-Agent"
  315.         UserAgent = SplitTemp(1)
  316.         Case "Host"
  317.         Host = SplitTemp(1)
  318.         Case "Connection"
  319.         Connection = SplitTemp(1)
  320.         Case "Cookie"
  321.         Cookie = SplitTemp(1)
  322.         End Select
  323.         i = i + 1
  324.     Wend
  325.     If StrComp(Method, "GET") <> 0 Then
  326.         rServer.SendData errorPage(405, "Method not allowed : <b>" + Method + "</b>")
  327.         Exit Sub
  328.     End If
  329.     SplitTemp = Split(Request, "/")
  330.     lRequest = Join(SplitTemp, "\")
  331.     If StrComp(Right(lRequest, 1), "\", vbTextCompare) = 0 Then
  332.         sFile = wwwRoot + lRequest + DefaultPage
  333.         If Len(Dir$(sFile)) = 0 And Len(Dir$(wwwRoot + lRequest + "*.*")) <> 0 Then
  334.             rServer.SendData errorPage(403, "You do not have the permission to access <b>" + Request + "</b> on this server")
  335.             Exit Sub
  336.         End If
  337.     Else
  338.         sFile = wwwRoot + lRequest
  339.     End If
  340.     If Len(Dir$(sFile)) = 0 Then
  341.         rServer.SendData errorPage(404, "The following page was not found on this server : <b>" + Request + "</b>")
  342.         Exit Sub
  343.     End If
  344.     fileDate = FileDateTime(sFile)
  345.     SplitTemp = Split(sFile, ".")
  346.     rServer.SendData makemimeHeader(200, FileLen(sFile), SplitTemp(1), Format(fileDate, "ddd, d mmm yyyy hh:mm:ss ") + "GMT", Connection)
  347.     rServer.SendData readFile(sFile)
  348. End Sub
  349. Function errorPage(errNum As Integer, errMessage As String) As String
  350.     Dim responseHeader As String
  351.     Dim responseData As String
  352.     Dim sDate As Date
  353.     Dim sTime As Date
  354.     sDate = Date
  355.     sTime = Time
  356.     responseData = "<html><head>" + vbCrLf _
  357.         + "<meta http-equiv='Content-Type' content='text/html; charset=windows-1252'>" + vbCrLf _
  358.         + "<title>Error : " + Str(errNum) + "</title></head><body><table border='0' width='100%'>" + vbCrLf _
  359.         + "<tr><td width='100%' bgcolor='#00FFFF'><h2>Error : " + Str(errNum) + " " + getReason(errNum) + "<h2></td></tr>" + vbCrLf _
  360.         + "<tr><td width='100%' height='200'>" + errMessage + "</td></tr>" + vbCrLf _
  361.         + "<tr><td width='100%' bgcolor='#C0C0C0'><center><b>TinyServer v1.0.1</b><br>Copyright © Saurabh 2001-2002</center>" + vbCrLf _
  362.         + "</td></tr></table></body></html>"
  363.     errorPage = makemimeHeader(errNum, Len(responseData), "htm", Format(sDate, "ddd, d mmm yyyy ") + Format(sTime, " hh:mm:ss ") + "GMT", "keep-alive") + responseData
  364. End Function
  365. Function makemimeHeader(httpCode As Integer, dataLength As Long, fileExt As String, lastModified As String, conType As String) As String
  366.     Dim mimeType As String
  367.     Dim sDate As Date
  368.     Dim sTime As Date
  369.     Dim Authenticate As String
  370.     sDate = Date
  371.     sTime = Time
  372.     If httpCode = 401 Then
  373.         Authenticate = "WWW-Authenticate: Basic realm=" + Chr(34) + "TinyServer Admin" + Chr(34) + vbCrLf
  374.     Else
  375.         Authenticate = ""
  376.     End If
  377.     Select Case fileExt
  378.         Case "doc"
  379.         mimeType = "application/msword"
  380.         Case "rtf"
  381.         mimeType = "application/rtf"
  382.         Case "zip"
  383.         mimeType = "application/zip"
  384.         Case "jpg"
  385.         mimeType = "image/jpeg"
  386.         Case "jpeg"
  387.         mimeType = "image/jpeg"
  388.         Case "gif"
  389.         mimeType = "image/gif"
  390.         Case "bmp"
  391.         mimeType = "image/x-xbitmap"
  392.         Case "mail"
  393.         mimeType = "message/RFC822"
  394.         Case "txt"
  395.         mimeType = "text/plain"
  396.         Case "htm"
  397.         mimeType = "text/html"
  398.         Case "html"
  399.         mimeType = "text/html"
  400.         Case "mpg"
  401.         mimeType = "video/mpeg"
  402.         Case "mpeg"
  403.         mimeType = "video/mpeg"
  404.         Case "mov"
  405.         mimeType = "video/quicktime"
  406.         Case "wmv"
  407.         mimeType = "video/x-msvideo"
  408.         Case "avi"
  409.         mimeType = "video/avi"
  410.         Case "mid"
  411.         mimeType = "audio/basic"
  412.         Case "wav"
  413.         mimeType = "audio/wav"
  414.         Case Else
  415.         mimeType = "text/plain"
  416.     End Select
  417.     makemimeHeader = "HTTP/1.0 " + Str(httpCode) + " " + getReason(httpCode) + vbCrLf _
  418.                    + "Date: " + Format(sDate, "ddd, d mmm yyyy ") + Format(sTime, " hh:mm:ss ") + "GMT" + vbCrLf _
  419.                    + "Server: TinyServer v1.0.1" + vbCrLf _
  420.                    + "MIME-version: 1.0" + vbCrLf _
  421.                    + "Content-type: " + mimeType + vbCrLf _
  422.                    + "Last-modified: " + lastModified + vbCrLf _
  423.                    + "Connection: " + conType + vbCrLf _
  424.                    + Authenticate _
  425.                    + "Content-length: " + Str(dataLength) + vbCrLf + vbCrLf
  426.     'MsgBox (makemimeHeader)
  427. End Function
  428. Function getReason(httpCode As Integer) As String
  429.     Select Case httpCode
  430.         Case 200
  431.         getReason = "OK"
  432.         Case 201
  433.         getReason = "Created"
  434.         Case 202
  435.         getReason = "Accepted"
  436.         Case 204
  437.         getReason = "No Content"
  438.         Case 301
  439.         getReason = "Moved Permanently"
  440.         Case 302
  441.         getReason = "Moved Temporarily"
  442.         Case 304
  443.         getReason = "Not Modified"
  444.         Case 400
  445.         getReason = "Bad Request"
  446.         Case 401
  447.         getReason = "Unauthorized"
  448.         Case 403
  449.         getReason = "Forbidden"
  450.         Case 404
  451.         getReason = "Not Found"
  452.         Case 405
  453.         getReason = "Method not allowed"
  454.         Case 500
  455.         getReason = "Internal Server Error"
  456.         Case 501
  457.         getReason = "Not Implemented"
  458.         Case 502
  459.         getReason = "Bad Gateway"
  460.         Case 503
  461.         getReason = "Service Unavailable"
  462.         Case Else
  463.         getReason = "Unknown"
  464.     End Select
  465. End Function
  466. Private Sub tcpServer_Error(Index As Integer, ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
  467.     TextBox.Text = TextBox.Text + vbCrLf + "Message form thread " + Str(Index) + ", Code : " + Str(Number) + " Description : " + Description
  468.     tcpServer(Index).Close
  469.     If tcpServer(Index).State = sckClosed Then
  470.         TextBox.Text = TextBox.Text + vbCrLf + "Connection Closed"
  471.         timeOut(Index) = 0
  472.     End If
  473. End Sub
  474. Private Sub setSysTrayIcon()
  475.     'Click this button to add an icon to the taskbar status area.
  476.     'Set the individual values of the NOTIFYICONDATA data type.
  477.     nid.cbSize = Len(nid)
  478.     nid.hwnd = Server.hwnd
  479.     nid.uId = vbNull
  480.     nid.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
  481.     nid.uCallBackMessage = WM_MOUSEMOVE
  482.     nid.hIcon = Server.Icon
  483.     nid.szTip = "Tiny Server" & vbNullChar
  484.     'Call the Shell_NotifyIcon function to add the icon to the taskbar
  485.     'status area.
  486.     Shell_NotifyIcon NIM_ADD, nid
  487. End Sub
  488. Private Sub Form_Terminate()
  489.     Shell_NotifyIcon NIM_DELETE, nid
  490. End Sub
  491. Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  492.     'Event occurs when the mouse pointer is within the rectangular
  493.     'boundaries of the icon in the taskbar status area.
  494.     Dim msg As Long
  495.     Dim sFilter As String
  496.     msg = X / Screen.TwipsPerPixelX
  497.     Select Case msg
  498.         Case WM_LBUTTONDOWN
  499.         Case WM_LBUTTONUP
  500.         Case WM_LBUTTONDBLCLK
  501.             DisplayForm
  502.         Case WM_RBUTTONDOWN
  503.             PopupMenu mnuPopup
  504.         Case WM_RBUTTONUP
  505.         Case WM_RBUTTONDBLCLK
  506.     End Select
  507. End Sub
  508. Private Sub Form_Resize()
  509.     If WindowState = 1 And Visible = True Then
  510.         Me.Hide
  511.     End If
  512. End Sub
  513. 'System tray menu handling subroutines
  514. Private Sub mnuExit_Click()
  515.     Unload Me
  516. End Sub
  517. Private Sub mnuStart_Click()
  518.     StartButton_Click
  519. End Sub
  520. Private Sub mnuStop_Click()
  521.     StopButton_Click
  522. End Sub
  523. Private Sub mnuConfigure_Click()
  524.     Configure_Click
  525. End Sub
  526. Private Sub mnuShow_Click()
  527.     DisplayForm
  528. End Sub
  529. Private Sub mnuAbout_Click()
  530.     MsgBox "                       TinyServer v1.1" + vbCrLf _
  531.          + "Programmed by Saurabh (saurabh@yep.com)" + vbCrLf _
  532.          + "               http://connect.to/tinyserver", 0, "About TinyServer"
  533. End Sub
  534. Private Sub DisplayForm()
  535.     If Visible = False Then
  536.         'Display form
  537.         WindowState = 0
  538.         Visible = True
  539.     End If
  540.     SetFocus
  541. End Sub
  542. Private Sub Timer1_Timer()
  543.     Dim i As Integer
  544.     For i = 1 To MAX_CONNECTIONS
  545.         If tcpServer(i).State = sckConnected Then
  546.             If timeOut(i) > MAX_TIME Then
  547.                 tcpServer(i).Close
  548.                 timeOut(i) = 0
  549.             Else
  550.                 timeOut(i) = timeOut(i) + 1
  551.             End If
  552.         End If
  553.     Next i
  554. End Sub
  555.