TMail
Source: source/classes/tmail.prg
TMail is FiveWin's MAPI (Messaging API) email class. It uses the Windows Simple MAPI interface to send emails through the default email client (such as Microsoft Outlook, Windows Mail, or any MAPI-compliant email application). TMail supports subject, body text, multiple recipients, file attachments, read receipts, and originator information.
Architecture
Key DATA Members
| DATA | Type | Default | Description |
|---|---|---|---|
cSubject | Character | "" | Email subject line |
cNoteText | Character | "" | Email body text |
cMsgType | Character | Message type (optional, e.g. "IPM.Note") | |
cConversationID | Character | "" | Conversation thread identifier |
dDate | Date | Date() | Message date |
cTime | Character | Time() | Message time |
lReceipt | Logical | .F. | Request a read receipt |
lFromUser | Logical | .T. | Prompt user before sending |
aOrigin | Array | {} | Originator address information |
aRecipients | Array | {} | Array of recipients; each item is { cName [, cAddress ] } |
aFiles | Array | {} | Array of file paths to attach |
nRetCode | Numeric | 0 | Return code from MAPISendMail (0 = success) |
Methods
| Method | Description |
|---|---|
New( cSubject, cNoteText, cMsgType, cConversationID, dDate, cTime, lReceipt, lFromUser, aOrigin, aRecipients, aFiles ) | Create a new mail message with all optional parameters. Defaults: empty subject, empty body, today's date, current time, no receipt, prompt user. |
Activate() | Send the email via MAPI. Calls MAPISendMail() with all configured properties. Stores the return code in nRetCode. |
End() | Log off from the MAPI session. Calls MAPILogOff(). |
Example: Send Email with Attachments
#include "FiveWin.ch"
function Main()
local oMail
// Configure the email
oMail := TMail():New( "Report for May 2026", ;
"Please find the attached report.",,,, .T. )
// Add recipients: each entry is { cName [, cAddress ] }
// Single string alone is not enough for all MAPI clients (e.g. Thunderbird).
oMail:aRecipients := { { "user@example.com" }, ;
{ "Manager", "manager@example.com" } }
// Attach files
oMail:aFiles := { "C:\reports\may2026.xlsx", "C:\reports\summary.pdf" }
// Request read receipt
oMail:lReceipt := .T.
// Send without prompting the user
oMail:lFromUser := .F.
// Activate sends the email
oMail:Activate()
if oMail:nRetCode == 0
MsgInfo( "Email sent successfully!" )
else
MsgStop( "Failed to send email. Error code: " + Str( oMail:nRetCode ) )
endif
oMail:End()
return nil
MAPI Return Codes
| Code | Description |
|---|---|
0 | Success |
1 | User aborted |
2 | General failure |
3 | Login failure |
4 | Disk full |
5 | Insufficient memory |
6 | Access denied |
14 | Unknown recipient |
15 | Bad recipient type |
DEFINE MAIL command
#include "FiveWin.ch"
#include "Mail.ch"
function Main()
local oMail, cEmail := "user@example.com"
DEFINE MAIL oMail ;
SUBJECT "Report" ;
TEXT "Please find the attached report." ;
TO cEmail ; // name only — OK (FWH fills address if empty)
// TO cEmail, cEmail ; // explicit name + address (always safe)
FILES "C:\reports\may2026.xlsx", "may2026.xlsx" ;
FROM USER
ACTIVATE MAIL oMail
MsgInfo( oMail:nRetCode )
return nil
TO <cName> [,<cAddress>] maps to a MapiRecipDesc pair.
If only one parameter is given and the address would otherwise be empty, FWH
fills it with the typed form SMTP:cName when the name looks like an
e-mail (contains @), so clients such as Thunderbird fill the
To: field and Outlook/Exchange deliver attachments correctly.
Call SetMapiAddrFill( .F. ) before sending to disable the fill and
leave lpszAddress empty for the client to resolve (pre-26.07
behaviour). Prefer TO cEmail, cEmail when you want the dual form
explicit in source — the explicit address is never rewritten.
Notes
- TMail uses the default MAPI client installed on the system. Outlook, Windows Mail, Thunderbird (with MAPI plugin), and most email clients support MAPI.
- When
lFromUseris.T.(default), the email client's compose window opens for the user to review and send. When.F., the email is sent silently. - The
aFilesarray accepts pairs{ cFullPath, cDisplayName }(as produced by theFILESclause ofDEFINE MAIL). - Each element of
aRecipientsshould be an array{ cName [, cAddress ] }. IfcAddressis omitted or empty,MAPISendMail()fills it withSMTP:cNamewhencNamecontains@(needed for Thunderbird and other strict Simple MAPI clients); otherwise it is left empty for the client to resolve. CallSetMapiAddrFill( .F. )to disable the fill entirely. - Check
nRetCodeafterActivate()to determine if the send was successful.