# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  VB6-pop3 email

## mebhas

Hey, thanx to all the guys in here, i have done some code for retrieving email messages from a pop3 server. this is just a part of my new project. i just put it here so people can see what to do and not to fall into stupid traps i fell in. so here it goes.

1. in a module, create these enums and types.

VB Code:
Public Enum POP_STATUS 'this is for the status of the pop getter
    pop_Connect
    pop_User
    pop_Password
    pop_Stat
    pop_List
    pop_Retr
    pop_CRetr
    pop_Delete
    pop_Quit
End Enum
 Public Type MSG_STATS 'this is for the messages in the server
    msg_Len As Long
    msg_ThisLen As Long
    msg_Body As String
    msg_File As String
End Type
 Public Type POP_SERVER 'this is for the pop server settings
    srv_Name As String
    srv_Address As String
    srv_Port As Long
    srv_User As String
    srv_Password As String
    srv_Messages As Long
End Type

then there are some variable declarations, name it whatever u want but here is what i have done.

VB Code:
Public pStat As POP_STATUS
Public myMsg() As MSG_STATS
Public myServer As POP_SERVER
  Public mError As Long
Public curMsg As Long
 Public myMsgList As String
Public myMsgListNum As Long
 Public fso As New FileSystemObject' use this if u want to save data using the file system objects, or omit the 2 lines here.
Public ***ile As TextStream

now for the settings part, as we already have some settings put up as a datatype, we will access it here.

VB Code:
With myServer
        .srv_Address = "<your pop3 server>"
        .srv_Name = "<Name of your ISP, not needed explicitly>"
        .srv_User = "<your pop3 username>"
        .srv_Password = "<your pop3 password>"
        .srv_Port = 110 'this is the default pop3 port.
    End With

and then the connection part. u know the drill

VB Code:
pStat = pop_Connect 'we set the status enum to connecting stage
    With myServer
        ws.Connect .srv_Address, .srv_Port
    End With

----------


## mebhas

2. Now comes the real part of retrieving mail. the code

VB Code:
Private Sub ws_DataArrival(ByVal bytesTotal As Long)
    Dim myData As String
    
    ws.GetData myData
    
    Select Case pStat
        Case Is = pop_Connect
            'this is still in connection state
            showprint myData
            If Left(myData, 1) = "+" Then
                'we got a +OK message, now for user authentication
                pStat = pop_User
                sSend "user " & myServer.srv_User
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 1
            End If
            
        Case Is = pop_User
            showprint myData
            'we are now in user authentication stage
            If Left(myData, 1) = "+" Then
                'we got a +OK message, now for password authentication
                pStat = pop_Password
                sSend "pass " & myServer.srv_Password
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 2
            End If
            
        Case Is = pop_Password
            'we are now in password authentication stage
            showprint myData
            If Left(myData, 1) = "+" Then
                'we got a +OK message, now for checking number of emails in the server
                pStat = pop_Stat
                sSend "stat"
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 3
            End If
            
        Case Is = pop_Stat
            'we are now checking for number of messages
            showprint myData
            If Left(myData, 1) = "+" Then
                'we got a +OK message, now for checking individual messages
                
                myServer.srv_Messages = getMsgNum(myData) 'we got the number of messages in the server
                
                If myServer.srv_Messages > 0 Then
                    'we have messages
                    curMsg = 1
                    pStat = pop_List
                    sSend "list " & curMsg
                Else
                    'we have no messages just quit
                    pStat = pop_Quit
                    sSend "quit"
                End If
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 4
            End If
            
        Case Is = pop_List
            'we are checking individual messages
            showprint myData
            If Left(myData, 1) = "+" Then
                If curMsg > 0 And curMsg <= myServer.srv_Messages Then
                    'we are ready to recieve messages
                    ReDim Preserve myMsg(curMsg) As MSG_STATS
                    With myMsg(curMsg)
                        .msg_Body = ""
                        .msg_File = getMsgFile(curMsg)
                        .msg_Len = thisMsgLen(myData)
                        .msg_ThisLen = 0
                    End With
                
                    'send command to recieve the particular message
                    pStat = pop_Retr
                    sSend "retr " & curMsg
                ElseIf curMsg > myServer.srv_Messages Then
                    'all messages have been downloaded
                    pStat = pop_Quit
                    sSend "quit"
                End If
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 5
            End If
            
        Case Is = pop_Retr
            'we recieve the actual message here
            showprint myData
            If Left(myData, 1) = "+" Then
                'straight write to file
                Open_And_Write_File myMsg(curMsg).msg_File, myData
                
                'calculate the size recieved
                With myMsg(curMsg)
                    .msg_ThisLen = bytesTotal + .msg_ThisLen
                End With
                
                If Mid(myData, Len(myData) - 2, 1) = "." Then
                    Close_And_Save_File
                    pStat = pop_Delete
                    sSend "dele " & curMsg
                Else
                    pStat = pop_CRetr
                End If
                
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 6
            End If
            
        Case Is = pop_CRetr
            Just_Write_To_File myData
            showprint myData
            
            With myMsg(curMsg)
                .msg_ThisLen = bytesTotal + .msg_ThisLen
            End With
                
            If Mid(myData, Len(myData) - 2, 1) = "." Then
                Close_And_Save_File
                pStat = pop_Delete
                sSend "dele " & curMsg
            End If
            
                        
        Case Is = pop_Delete
            'we just recieved the delete command's reply
            showprint myData
            If Left(myData, 1) = "+" Then
                If CheckForMore(curMsg) = True Then
                    pStat = pop_List
                    curMsg = curMsg + 1
                    sSend "list " & curMsg
                Else
                    pStat = pop_Quit
                    sSend "quit"
                End If
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 7
            End If
            
        Case Is = pop_Quit
            showprint myData
            If Left(myData, 1) = "-" Then
                mError = 8
            End If
            
    End Select
End Sub

----------


## mebhas

if you have an idea of how pop3 works, u will know these simple facts.



> 1. connect ->                      returns +OK <some message>
> 2. user <username> ->          returns +OK <some message>
> 3. pass <password> ->          returns +OK <some message> 'we are now ready for data arrival
> 4. stat ->                            returns +OK <number of messages> <sum of size of messages>
> 5. list <message number> ->   returns +OK <message number> <size of message in octets>
> 6. retr <message number> ->  returns +OK followed by the contents of the message *NOTE1
> 7. dele <message number> -> returns +OK and queues the message for delete at user logoff
> 8. quit ->                            returns +OK <some message> and closes connection


NOTE1: all messages are ended by a ".", this, I found eventually, was undocumented.

----------


## mebhas

there are some parts missing in the code in post#2.

->the open_and_write_to_file procedure does nothing except do a 
VB Code:
myMsgList = wData 'wData is the string recieved

->the just_write_to_file does this 
VB Code:
myMsgList = myMsgList & wData

->the save_and _close_file does this 
VB Code:
mF = FreeFile
Open mFile for Output as #nF
Print #mF, myMsgList
Close #mF

----------


## mebhas

forgot to mention. when saving the files, save it with .eml extension so it can be opened by outlook/outlook express even by double clicking the file.

----------


## mfurqan

it says invalid outside procedure

----------


## mfurqan

do i need to add a componene or refrence ?

----------


## mebhas

exactly where does it say that?
u have to add a component, winsock, of course.

----------


## mfurqan

it syas user-defined type not found i added MS Winsock 6.0 component

----------


## mfurqan

may be there is a problem :::

Public fso As New FileSystemObject
Public ***ile As TextStream

----------


## mebhas

oh yeah, u need the reference to microsoft scripting object, that is if u want to use the file system object to write down the recieved data. or u can omit the two lines. i used the classic vb way to write down the data, as is stated in my post #4.

----------


## mfurqan

and yeh do i need to make text boxes and other things ?

can't u please provide a zip package it really difficult this way :P

----------


## mfurqan

okay i did it all... no errors now but now i see blank form nothin else no messages.. nothing

----------


## mebhas

on demand...

----------


## mfurqan

thanks but i get error # 11004 May be i don't have MSWINSCK.OCX it says 'Valid Name, no data record of requested type' and source is 'C;\windows\system32\MSWINSCK.OCX'

----------


## mfurqan

self resolved problem.

its working great  :Big Grin: 
but it only downloads Unread Messages ?

and really don't know what that Text4 box realy is for  :Smilie:

----------


## mfurqan

hello.. all fixed by myself... and u know i m making a mod for this ... user download all messages as .txt and a form read message, From , Subject , To, Date & Time,  :Smilie:  i m almost done with it  :Big Grin: 

now can u tell me is it not possible to save message with its Subject Name ?

----------


## mebhas

sure, just scan the message line by line until u get the left(text,9)="<subject>" u can get the subject there. set the filename as the subject text....

----------


## mfurqan

well does it delete all messages from pop3 account after downloading them. ?

----------


## mfurqan

> sure, just scan the message line by line until u get the left(text,9)="<subject>" u can get the subject there. set the filename as the subject text....


can u please post an example i really can't understand it  :Frown:

----------


## mebhas

yes it deletes the messages after downloading them. and for the example of the saving by subject. u'll have to wait a couple of days, i am a bit busy right now.

----------


## mfurqan

okay sir no problem  :Smilie:

----------


## mfurqan

i wish if u can do it earlier because i have made .TXT email reader  :Big Grin:

----------


## mebhas

ok, here's some quick code, see if you can make it any better....

VB Code:
'make reference to microsoft scripting runtime, we need it for file system object
'make these variables, fso as filesystemobjects, readFile as textstream, readString as string
set readfile=fso.opentextfile "your file name", forreading
do while not readfile.eof
    readfile.readline readstring
    processString readstring 'processString is a sub, need some thinking for that
loop

now create a sub processString(inString as string)

some part of the code.

VB Code:
'i am using if statements here coz i know there are more conditions than a select case can handle.
 if ucase$(left$(instring,5))="FROM:" then
    'this is whom u recieved the message from. the remaining part of the line is the sender.
elseif ucase$(left$(instring,5))="DATE:" then
    'this is the date u recieved the message.
elseif ucase$(left$(instring,3))="TO:" then
    'this is the reciever of the message
elseif ucase$(left$(instring,8))="SUBJECT:" then
    'this is the subject of the message.
elseif len(instring)=0 then
    'we have reached the beginning of the message, we can now write all the remining part of the email as the body.
endif

----------


## mebhas

as u can see, i have just typed in the code and it should be debugged thoroughly and proper declarations should be made.

----------


## mfurqan

really can't understand it  :Frown:  sorry...

----------


## rory

Very well done mebhas ...   :Thumb:  

The zip you posted  should be enough for anyone to get started ..
you did all the hard work already .. i know this thread is kind of old but just wanted to say thanks ..

----------


## try.test.abc

hello 
I downloaded the attachment ws.zip from this thread abd try to run the project using yahoo Pop server "pop.mail.yahoo.com" and use the username and password but it gives error while checking password. Note that password which i enterd is right. i also use another Username and Password but still it shows the Password Inccorect. can u suggest waht s the problem?

----------


## teguh123

I tried that with a throw away hotmail and it doesn't work

daveyhoin0@hotmail.com|nzdr9p
POP server: pop3.live.com (Port 995)

POP SSL required? Yes

----------


## martind1

Hmm, why can't i find the winsock control?

----------


## mebhas

> Hmm, why can't i find the winsock control?


you have to add the control to the project. hit ctrl-t and look for winsock, or try browsing for <windows folder>\system32\winsock.ocx

----------


## martind1

Shoot. Does this not do SSL pop?

----------


## mebhas

nope, just plain pop

----------


## Fenrir

> 2. Now comes the real part of retrieving mail. the code
> 
> VB Code:
> Private Sub ws_DataArrival(ByVal bytesTotal As Long)
    Dim myData As String
    
    ws.GetData myData
    
    Select Case pStat
        Case Is = pop_Connect
            'this is still in connection state
            showprint myData
            If Left(myData, 1) = "+" Then
                'we got a +OK message, now for user authentication
                pStat = pop_User
                sSend "user " & myServer.srv_User
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 1
            End If
            
        Case Is = pop_User
            showprint myData
            'we are now in user authentication stage
            If Left(myData, 1) = "+" Then
                'we got a +OK message, now for password authentication
                pStat = pop_Password
                sSend "pass " & myServer.srv_Password
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 2
            End If
            
        Case Is = pop_Password
            'we are now in password authentication stage
            showprint myData
            If Left(myData, 1) = "+" Then
                'we got a +OK message, now for checking number of emails in the server
                pStat = pop_Stat
                sSend "stat"
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 3
            End If
            
        Case Is = pop_Stat
            'we are now checking for number of messages
            showprint myData
            If Left(myData, 1) = "+" Then
                'we got a +OK message, now for checking individual messages
                
                myServer.srv_Messages = getMsgNum(myData) 'we got the number of messages in the server
                
                If myServer.srv_Messages > 0 Then
                    'we have messages
                    curMsg = 1
                    pStat = pop_List
                    sSend "list " & curMsg
                Else
                    'we have no messages just quit
                    pStat = pop_Quit
                    sSend "quit"
                End If
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 4
            End If
            
        Case Is = pop_List
            'we are checking individual messages
            showprint myData
            If Left(myData, 1) = "+" Then
                If curMsg > 0 And curMsg <= myServer.srv_Messages Then
                    'we are ready to recieve messages
                    ReDim Preserve myMsg(curMsg) As MSG_STATS
                    With myMsg(curMsg)
                        .msg_Body = ""
                        .msg_File = getMsgFile(curMsg)
                        .msg_Len = thisMsgLen(myData)
                        .msg_ThisLen = 0
                    End With
                
                    'send command to recieve the particular message
                    pStat = pop_Retr
                    sSend "retr " & curMsg
                ElseIf curMsg > myServer.srv_Messages Then
                    'all messages have been downloaded
                    pStat = pop_Quit
                    sSend "quit"
                End If
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 5
            End If
            
        Case Is = pop_Retr
            'we recieve the actual message here
            showprint myData
            If Left(myData, 1) = "+" Then
                'straight write to file
                Open_And_Write_File myMsg(curMsg).msg_File, myData
                
                'calculate the size recieved
                With myMsg(curMsg)
                    .msg_ThisLen = bytesTotal + .msg_ThisLen
                End With
                
                If Mid(myData, Len(myData) - 2, 1) = "." Then
                    Close_And_Save_File
                    pStat = pop_Delete
                    sSend "dele " & curMsg
                Else
                    pStat = pop_CRetr
                End If
                
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 6
            End If
            
        Case Is = pop_CRetr
            Just_Write_To_File myData
            showprint myData
            
            With myMsg(curMsg)
                .msg_ThisLen = bytesTotal + .msg_ThisLen
            End With
                
            If Mid(myData, Len(myData) - 2, 1) = "." Then
                Close_And_Save_File
                pStat = pop_Delete
                sSend "dele " & curMsg
            End If
            
                        
        Case Is = pop_Delete
            'we just recieved the delete command's reply
            showprint myData
            If Left(myData, 1) = "+" Then
                If CheckForMore(curMsg) = True Then
                    pStat = pop_List
                    curMsg = curMsg + 1
                    sSend "list " & curMsg
                Else
                    pStat = pop_Quit
                    sSend "quit"
                End If
            ElseIf Left(myData, 1) = "-" Then
                'oops we got a -ERR message means we have an error of some sorts
                mError = 7
            End If
            
        Case Is = pop_Quit
            showprint myData
            If Left(myData, 1) = "-" Then
                mError = 8
            End If
            
    End Select
End Sub


Hello  :Smilie: 

I gave a look at the code below and at the zip file attached to the thread but I can't understand how this code works yet. I have some questions to ask:

1) what is bytesTotal argument and what I have to pass to it?
2) how has the ws_DataArrival function to be called to retreive all the incoming mails and dowload them?

I really don't understand how to use this code  :Frown:  help me please

----------


## dilettante

The ws_DataArrival subroutine is an event handler.  Its bytesTotal argument is passed to your event handler subroutine by the Winsock control.  However most serious code ignores it since by the time your handler gets run its value might be out of date anyway, and relying on it could mean losing or corrupting data.  It is pretty obsolete but retained for compatibility with old programs.

If you don't know this you need to work on your VB skills.  It is all pretty basic stuff.

Reliance on bytesTotal here (in the code above) is pathological.  The myData variable could well have more characters in it than this, and later bytesTotal is used instead of the far more reliable Len(myData).  This is a bad indicator of the quality of all of this code, which indeed has a ton of "well it might work if you get lucky" things in it.

All in all, this is sort of flaky more-or-less-working code for the way email worked in the late 1990s.  You'd be far better off to pay for a licensed 3rd party POP3 library, which is likely to support SSL/TLS and modern authentication too.

----------


## Fenrir

> The ws_DataArrival subroutine is an event handler.


You're totally right, dude. I didn't notice this when I opened the project. What kind of stupid I can be sometimes  :Blush: 




> Its bytesTotal argument is passed to your event handler subroutine by the Winsock control.  However most serious code ignores it since by the time your handler gets run its value might be out of date anyway, and relying on it could mean losing or corrupting data.  It is pretty obsolete but retained for compatibility with old programs.
> 
> If you don't know this you need to work on your VB skills. It is all pretty basic stuff.


I am an autodidact of these stuff. I have never used Winsock control in the past and I don't know well how it works, I'm trying lo learn it. However thank you for this explaination. 




> Reliance on bytesTotal here (in the code above) is pathological.  The myData variable could well have more characters in it than this, and later bytesTotal is used instead of the far more reliable Len(myData).  This is a bad indicator of the quality of all of this code, which indeed has a ton of "well it might work if you get lucky" things in it.
> 
> All in all, this is sort of flaky more-or-less-working code for the way email worked in the late 1990s.  You'd be far better off to pay for a licensed 3rd party POP3 library, which is likely to support SSL/TLS and modern authentication too.


Ok, now that I know that I still don't want to pay for a 3rd party library LOL
I'd like to develope something with my hands (if it's possible) but I need a start point to study this matter.

Thank you.

----------


## quyenvo

How to know mail that unread? because need to get unread mail

If Who know Pls help me. Thanks

----------

