Listing Messages  
 

If your application needs to list the available messages in a user's mailbox, either the Post Office Protocol v3 (POP3) or Internet Message Access Protocol v4 (IMAP4) controls can be used. Which protocol is selected largely depends on the mail server. Most service providers offer POP3 access to their mail servers, and it is the more commonly used protocol.

Post Office Protocol

The Post Office Protocol is a simple message retrieval protocol designed to access the messages that have arrived in the user's inbox. It is designed for mail clients which will store the messages on the local system and then delete them from the server. POP3 provides only limited support for managing messages on the server. Here is an example of how you could list messages using the POP3 and Mail Message controls:

Dim nMessageId As Long
Dim strHeaders As String
Dim nError As Long

' Establish a connection to the mail server using the default port
' and the specified username and password
nError = PopClient1.Connect(strHostName, , strUserName, strPassword)
If nError Then
    MsgBox PopClient1.LastErrorString, vbExclamation
    Exit Sub
End If

' If the MessageCount property returns 0, then there are no
' messages in the mailbox
If PopClient1.MessageCount = 0 Then
    MsgBox "There are no messages in this mailbox", vbInformation
    PopClient1.Disconnect
    Exit Sub
End If
    
' Initialize the ListBox and ProgressBar controls
List1.Clear
ProgressBar1.Max = PopClient1.MessageCount - 1
ProgressBar1.Value = 0

For nMessageId = 1 To PopClient1.MessageCount
    ' Retrieve the headers for the message, storing them in the
    ' string variable
    nError = PopClient1.GetHeaders(nMessageId, strHeaders)
    If nError Then Exit For

    ' Parse the header block returned by the server
    MailMessage1.ClearMessage
    MailMessage1.ParseMessage strHeaders
   
    ' Update the ListBox and ProgressBar controls
    List1.AddItem nMessageId & " " & MailMessage1.Subject
    ProgressBar1.Value = nMessageId - 1
    DoEvents
Next
    
If nError Then MsgBox PopClient1.LastErrorString, vbExclamation
PopClient1.Disconnect

There's a few important points about this example. The use of the GetHeaders method here to retrieve the message header block is the most compatible means of retrieving header values from a POP3 server. If you review the Technical Reference, you'll notice that there is also a GetHeader method which will return the value of a single header field. While it may seem more efficient to use this approach, rather than download the complete header block, the GetHeader method depends on an extended command called XTND XLST which many POP3 servers do not support. While it is convenient if the server does support that command, an application should never depend on it being available. In addition, although this example only lists the subject of the message, if you wanted to list more information such as the sender, recipient and date of the message then you'd need to call GetHeader multiple times. It is usually more efficient to simply request the entire header block and let the client parse it.

The header block is returned in a string with each header terminated by a carriage return and linefeed sequence. While you could write your own code to parse the headers, it's recommended that you use the Mail Message control to do this. Message headers can be complex when they span multiple lines or contain encoded sequences.

One other thing that is worth pointing out is the use of DoEvents in the For..Next loop. This is done to allow the UI controls to redraw themselves and also permit the application to remain responsive to the user. However, when you do this you need to be aware that your application can be re-entered by the user clicking on buttons, selecting menu items and so on. If you use DoEvents, make sure that you design your application so that the user can not interact with your program in a way that will allow them to perform some other action using the POP3 control while the contents are being listed.

Internet Message Access Protocol

The Internet Message Access Protocol is a more complex, general purpose protocol used for accessing and managing a user's mailbox on a server. The design of the IMAP4 control is intentionally very similar to the POP3 control, with a number of additional properties and methods to take advantage of the protocol's features. Here is how the code would be written to list the available messages in a user's Inbox:

Dim nMessageId As Long
Dim strSubject As String
Dim nError As Long

' Establish a connection to the mail server using the default port
' and the specified username and password
nError = ImapClient1.Connect(strHostName, , strUserName, strPassword)
If nError Then
    MsgBox ImapClient1.LastErrorString, vbExclamation
    Exit Sub
End If

' Select the user's Inbox where new messages arrive
nError = ImapClient1.SelectMailbox("Inbox")
If nError Then
    MsgBox ImapClient1.LastErrorString, vbExclamation
    Exit Sub
End If

' If the MessageCount property returns 0, then there are no
' messages in the mailbox
If ImapClient1.MessageCount = 0 Then
    MsgBox "There are no messages in this mailbox"
    ImapClient1.Disconnect
    Exit Sub
End If
    
' Initialize the ListBox and ProgressBar controls
List1.Clear
ProgressBar1.Max = ImapClient1.MessageCount - 1
ProgressBar1.Value = 0
    
For nMessageId = 1 To ImapClient1.MessageCount
    ' Retrieve the Subject header field from the message
    strSubject = ""
    ImapClient1.GetHeader nMessageId, 0, "Subject", strSubject

    ' Update the ListBox and ProgressBar controls
    List1.AddItem nMessageId & " " & strSubject
    ProgressBar1.Value = nMessageId - 1
    DoEvents
Next
    
If nError Then MsgBox ImapClient1.LastErrorString, vbExclamation
ImapClient1.Disconnect

You'll notice that the code is substantially similar to the previous example, however there are a couple of important differences. The SelectMailbox method is used to explicitly select the user's Inbox, where new messages are stored until they are moved or deleted by the user. Unlike POP3 which only deals with new messages, IMAP4 is designed to manage multiple mailboxes, so you need to specify which mailbox you want to use. The mailbox "Inbox" is a special mailbox defined by the IMAP4 standard where all new messages are stored. You can list the available mailboxes by reading the Mailbox property array.

The other significant difference is the use the GetHeader method here. This example could have used the GetHeaders methods to retrieve the complete header block as in the previous example, however because IMAP4 has support for retrieving specific header values, it was a good way to explain the difference between the protocols. Unlike POP3 which depends on an extension to the protocol to retrieve a single header value, all IMAP4 servers support this capability so it is something that you can take advantage of without concerns about compatibility.

It should be noted that if you plan on retrieving more than two or three header fields from the message, it will usually be more efficient to retrieve the entire header block with the GetHeaders method and then use the Mail Message control to parse it.