Un client per la posta elettronica    (III Parte)

Articolo di Diego La Monica
Grado: ***
Con la prima e la seconda parte di questo articolo siamo riusciti a creare un cliente di ricezione per la posta elettronica funzionante al 50%. Infatti manca la possibilità di scrivere un e-mail, inoltrare o rispondere ad un messaggio.
In più c’è un controllo parziale degli errori... ad esempio se compare il prompt per il login quando si apre una sessione di posta elettronica e viene premuto il tasto annulla il programma va in debug notificando l’errore 32003 Accesso fallito. Ma di questo non ci preoccupiamo ancora.

Adesso ci serve creare un sistema per la scrittura e l’invio dell’e-mail.
Aggiungiamo sul form tre commandButton e li chiamiamo tutti e tre cmdNuovoMessaggio creando un array. Ad ognuno degli elementi di questo array gli assegnamo come caption rispettivamente:
  • Nuovo messaggio all’elemento di indice 0
  • Rispondi al messaggio all’elemento di indice 1
  • Inoltra il messaggio all’elemento di indice 2
Creiamo un altro form che chiameremo frmInvia ed aggiungiamo i seguenti elementi 2 TextBox che rinominiamo rispettivamente txtIniviaA e txtOggetto poi aggiungiamo accanto alla casella di testo txtInviaA un commandButton che rinominiamo in cmdRubrica.
Poi aggiungiamo una textBox dove impostiamo la proprietà multiline a True e lo rinominiamo in txtMessaggio.
Aggiungiamo un commandButton che etichettiamo come “Invia e Chiudi” e lo rinominiamo in cmdInvia.

Iniziamo con il rinominare il form che riceve i messaggi  come frmMessaggi.
Nell’evento click del commandButton cmdInvia scriviamo il seguente codice:

Private Sub cmdInvia_Click()
   If frmMessaggi.MSClient.SessionID = 0 Then
       frmMessaggi.MSClient.SignOn
       frmMessaggi.MMClient.SessionID = frmMessaggi.MSClient.SessionID
   
End If
   
With frmMessaggi.MMClient
       .Compose
       .MsgSubject = txtOggetto
       .RecipAddress = txtInviaA
       .MsgNoteText = txtMessaggio
       .ResolveName
       .Send

   End With
End Sub

Ed ora andiamo a spiegare il significato di ciò che è scritto nella sub:

Come prima istruzione c’è un controllo per verificare che la Sessione sia aperta altrimenti crea una Sessione MAPI valida per l’invio immediato del messaggio, quindi compila tutti i campi per l’invio e richiama il metodo Send dell’oggetto MMClient.

Ma soffermiamoci un momento proprio sulla seconda parte dove notiamo che ci sono delle istruzioni particolari.
Poiché quando andiamo a leggere un messaggio il buffer di composizione del nuovo messaggio è in sola lettura, dobbiamo fare in modo che in quest’ultimo sia possibile inserire il messaggio da inviare al nostro utente quindi richiamiamo il metodo Compose che imposta la proprietà msgIndex a –1 e svuota il buffer di composizione del messaggio. Quindi compila i campi dell’invio e richiama la funzione ResolveName che risolve i nomi brevi in indirizzi e-mail estesi, per esempio:

se io in rubrica avessi un amico classificato col nome Diego e con indirizzo mail diego@pippo.com questa funzione consente di convertire il nome Diego nel suo indirizzo e-mail.
Quindi come ultima operazione effettuiamo l’invio del messaggio tramite il metodo Send.

Adesso sulla frmMessaggi nell’evento click di cmdNuovoMessaggio scriviamo:

Private Sub cmdNuovoMessaggio_Click(Index As Integer)
    Select Case Index
       Case 0
           frmInvia.Show
       Case 1
       Case 2
   End Select
End Sub

In modo da mostrare la maschera di composizione del messaggio quando si preme il bottone NuovoMessaggio.

Adesso pensiamo ad abilitare la funzionalità “Rispondi al messaggio”.

Ed a questo punto modifichiamo il codice nell’evento Click del commandButton cmdNuovoMessaggio del form frmMessaggi come segue:

Private Sub cmdNuovoMessaggio_Click(Index As Integer)
Select Case Index
       Case 0
           frmInvia.Show
       Case 1
           frmInvia.ReplyMessage
           frmInvia.Show
       Case 2
   End Select
End Sub



Nel form frmInvia inseriamo nella sezione dichiarativa la seguente dichiarazione:
 
Private Reply As Boolean

Aggiungiamo questa funzione e subito dopo andiamo a spiegarla:

Public Function ReplyMessage()
    If frmMessaggi.MSClient.SessionID = 0 Then
       frmMessaggi.MSClient.SignOn
       frmMessaggi.MMClient.SessionID = frmMessaggi.MSClient.SessionID
    End If
    frmMessaggi.MMClient.Reply
    txtOggetto = frmMessaggi.MMClient.MsgSubject
    txtInviaA = frmMessaggi.MMClient.RecipAddress
    txtMessaggio = Replace(frmMessaggi.MMClient.MsgNoteText, vbCrLf, vbCrLf & ">")
    txtMessaggio = ">" & txtMessaggio
    Reply = True
End Function


Le prime quattro righe della funzione servono per verificare l’esistenza di una sessione valida ed attiva, in caso contrario la stabiliamo.
Subito dopo richiamiamo il metodo Reply dell’oggetto MMClient che ritorna nella proprietà MsgSubject l’oggetto del messaggio originale preceduto dall’indicativo di risposta “R:” ed in RecipAddress che contiene gli indirizzi dei destinatari inserisce l’indirizzo del mittente del messaggio. Infine compiliamo il campo txtInviaA e txtMessaggio.
In txtMessaggio però come si può notare non inseriamo il messaggio integralmente ma aggiungiamo dei simboli “>” all’inizio di ogni riga:

  txtMessaggio = Replace(frmMessaggi.MMClient.MsgNoteText, vbCrLf,vbCrLf & ">")
  txtMessaggio = ">" & txtMessaggio

a questo punto ci tocca modificare anche l’evento sul bottone cmdInvia come segue:

Private Sub cmdInvia_Click()
    If frmMessaggi.MSClient.SessionID = 0 Then
       frmMessaggi.MSClient.SignOn
       frmMessaggi.MMClient.SessionID = frmMessaggi.MSClient.SessionID
   End If
   With
frmMessaggi.MMClient
        If Not Reply Then
           .Compose
           .MsgSubject = txtOggetto
           .RecipAddress = txtInviaA
           .ResolveName
       End If
       .MsgNoteText = txtMessaggio
       .Send
    End With
    Reply = False
End Sub

Il codice non ha bisogno di spiegazioni in quanto è stato aggiunto un solo controllo della variable Reply per sapere se c’è bisogno di compilare dei campi e se il metodo Compose deve essere richiamato.

Il programma attualmente già ha un aspetto più completo.