For i = 0 To lstAttachments.ListCount - 1
lstAttachments.ListIndex = i
m_strEncodedFiles = m_strEncodedFiles & _
UUEncodeFile(lstAttachments.Text) & vbCrLf
Next i
上面的代码将附件的路径作为参数传递给UUEncodeFile函数。该函数的作用是按照我们前面所讲的算法对字符进行编码。编码后的数据被保存在一个模块级变量m_strEncodedFile中。然后该变量的内容被添加到邮件正文中:
Public Function UUEncodeFile(strFilePath As String) As String
Dim intFile As Integer 'file handler
Dim intTempFile As Integer 'temp file
Dim lFileSize As Long 'size of the file
Dim strFileName As String 'name of the file
Dim strFileData As String 'file data chunk
Dim lEncodedLines As Long 'number of encoded lines
Dim strTempLine As String 'temporary string
Dim i As Long 'loop counter
Dim j As Integer 'loop counter
Dim strResult As String
'
'Get file name
strFileName = Mid$(strFilePath, InStrRev(strFilePath, "\") + 1)
'
'Insert first marker: "begin 664 ..."
strResult = "begin 664 " + strFileName + vbLf
'
'Get file size
lFileSize = FileLen(strFilePath)
lEncodedLines = lFileSize \ 45 + 1
'
'Prepare buffer to retrieve data from
'the file by 45 symbols chunks
strFileData = Space(45)
'
intFile = FreeFile
'
Open strFilePath For Binary As intFile
For i = 1 To lEncodedLines
'Read file data by 45-bytes cnunks
'
If i = lEncodedLines Then
'Last line of encoded data often is not
'equal to 45, therefore we need to change
'size of the buffer
strFileData = Space(lFileSize Mod 45)
End If
'Retrieve data chunk from file to the buffer
Get intFile, , strFileData
'Add first symbol to encoded string that informs
'about quantity of symbols in encoded string.
'More often "M" symbol is used.
strTempLine = Chr(Len(strFileData) + 32)
'
If i = lEncodedLines And (Len(strFileData) Mod 3) Then
'If the last line is processed and length of
'source data is not a number divisible by 3,
'add one or two blankspace symbols
strFileData = strFileData + Space(3 - (Len(strFileData) Mod 3))
End If
For j = 1 To Len(strFileData) Step 3
'Breake each 3 (8-bits) bytes to 4 (6-bits) bytes
'
'1 byte
strTempLine = strTempLine + Chr(Asc(Mid(strFileData, j, 1)) \ 4 + 32)
'2 byte
strTempLine = strTempLine + _
Chr((Asc(Mid(strFileData, j, 1)) Mod 4) * 16 + Asc(Mid(strFileData, j + 1, 1)) \ 16 + 32)
'3 byte
strTempLine = strTempLine + _
Chr((Asc(Mid(strFileData, j + 1, 1)) Mod 16) * 4 + Asc(Mid(strFileData, j + 2, 1)) \ 64 + 32)
'4 byte
strTempLine = strTempLine + _
Chr(Asc(Mid(strFileData, j + 2, 1)) Mod 64 + 32)
Next j
'add encoded line to result buffer
strResult = strResult + strTempLine + vbLf
'reset line buffer
strTempLine = ""
Next i
Close intFile
'add the end marker
strResult = strResult & "'" & vbLf + "end" + vbLf
'asign return value
UUEncodeFile = strResult
Dim strFileName As String
Dim strMessage As String
Dim strAttachment As String
Dim lngPosA As Long
Dim lngPosB As Long
'Extract full text of the message
strMessage = m_colMessages(lvMessages.SelectedItem.Key).MessageText
'Extract name of the file
strFileName = lvAttachments.SelectedItem.Key
'
Do Until lngPosA = 0
'Looking for the file's name in the message's text
lngPosA = InStr(lngPosA + 1, strMessage, " " & strFileName)
If lngPosA > 0 Then
'End of string with the file's name
lngPosB = InStrRev(strMessage, vbCrLf, lngPosA) + 2
If lngPosB > 2 Then
'Check whether the string with the file's name
'is the part of the "begin" marker
If (Mid$(strMessage, lngPosB, lngPosA - lngPosB _
+ Len(strFileName) + 1)) Like _
("begin ### " & strFileName) Then
'Position of the end marker
lngPosA = InStr(lngPosA, strMessage, "'" & _
vbCrLf & "end" & vbCrLf)
If lngPosA > 0 Then
With ComDialog
'Bring up the file selection dialog
.FileName = strFileName
.ShowSave
If Err = 0 Then
'Encoding data save to the strAttachment
'variable
strAttachment = Mid$(strMessage, lngPosB, _
lngPosA + 8 - lngPosB)
'Pass it to the UUDecodeToFile routine
'in order to decode and save as file
UUDecodeToFile strAttachment, .FileName
End If
End With
End If
End If
End If
End If
Loop
End Sub
最后是UUDecodeToFile函数的代码:
Public Function UUDecodeToFile(strUUCodeData As String, strFilePath As String)
Dim vDataLine As Variant
Dim vDataLines As Variant
Dim strDataLine As String
Dim intSymbols As Integer
Dim intFile As Integer
Dim strTemp As String
'
'Remove first marker
If Left$(strUUCodeData, 6) = "begin " Then
strUUCodeData = Mid$(strUUCodeData, InStr(1, strUUCodeData, vbLf) + 1)
End If
'
'Remove marker of the attachment's end
If Right$(strUUCodeData, 5) = "end" + vbCrLf Then
strUUCodeData = Left$(strUUCodeData, Len(strUUCodeData) - 10)
End If
intFile = FreeFile
Open strFilePath For Binary As intFile
'Break decoded data to the strings
'From now each member of the array vDataLines contains
'one line of the encoded data
vDataLines = Split(strUUCodeData, vbCrLf)
For Each vDataLine In vDataLines
'Decode data line by line
'
strDataLine = CStr(vDataLine)
'Extract the number of characters in the string
'We can figure it out by means of the first string character
intSymbols = Asc(Left$(strDataLine, 1))
'which we delete because of its uselessness
strDataLine = Mid$(strDataLine, 2, intSymbols)
'Decode the string by 4 bytes portion.
'From each byte remove two oldest bits.
'From remain 24 bits make 3 bytes
For i = 1 To Len(strDataLine) Step 4
'1 byte
strTemp = strTemp + Chr((Asc(Mid(strDataLine, i, 1)) _
- 32) * 4 + (Asc(Mid(strDataLine, i + 1, 1)) _
- 32) \ 16)
'2 byte
strTemp = strTemp + Chr((Asc(Mid(strDataLine, i + 1, 1))_
Mod 16) * 16 + (Asc(Mid(strDataLine, i + 2, 1))_
- 32) \ 4)
'3 byte
strTemp = strTemp + Chr((Asc(Mid(strDataLine, i + 2, 1)) _
Mod 4) * 64 + Asc(Mid(strDataLine, i + 3, 1)) - 32)
Next i
'Write decoded string to the file
Put intFile, , strTemp
'Clear the buffer in order to receive the next _
'line of the encoded data
strTemp = ""
Next
Close intFile
End Function
看上去似乎就这么多了。其实不然。要想编写出现代电子邮件程序,你必须了解Base 64和MIME用的Quoted-Printalbe算法。不过你放心,本站介绍的算法大多数的邮件程序还是能识别的。只不过它的年纪比较老,现在的电子邮件程序往往是最后才用这种算法。