I. Overview
This article mainly tells how to write E-mail programs with Visual C with MAPI. MAPI is included in Windows, so there is no need to install additional parts. MAPI has three forms:
SMAPI, Simple Mapi, Simple MAPI
CMC, Common Messaging Calls, General Communication Call
Complete MAPI SMAPI and CMC are included in full MAPI, when users want to perform some advanced operations, such as writing their own E-mail servers, you must use a complete MAPI. This article mainly explains how to write procedures that can send and receive email, so use SMAPI is sufficient.
Second, write an email program 3-1 initialization MAPI
To use MAPI, you must first initialize it. Initialization includes the following three steps:
Load Mapi32.dll Dynamic Link Library
Find the MAPI function address you want to call
Log in to email objects 3-1-1 load mapi32.dll
To load MAPI, the user must run a dynamic link library when running. The LoadLibrary function provides this feature, which locates a dynamic link library and returns the Hinstance link (you need to save the handle).
The syntax of LoadLibrary is as follows: LoadLibrary (LPLIBFileName); where lplibfilename is the LPCTSTR structure variable, the path and name of the library to be called.
Sample: // Call Mapi32.dll and calculate the function address hinstance hinstmail; hinstmail = :: loadLibrary ("mapi32.dll"); if (hinstmail == null) {// error handling // is limited, the following error Handling part omitted}
3-1-2 Determine the function address
Since Mapi32.dll is dynamically loaded, I don't know the function address to be called, and they can't call them at the beginning, but to get the address of the function through the function name, and find each function in the dynamic link library and verify . So first you must declare the pointer for these functions.
Example program: // is the function declaration MAPI32.DLL function pointer ULONG (PASCAL * lpfnMAPISendMail) (LHANDLE lhSession, ULONG ulUIParam, lpMapiMessage lpMessage, FLAGS flFlags, ULONG ulReserved); ULONG (PASCAL * lpfnMAPIResolveName) (LHANDLE lhSession, ULONG ulUIParam , LPTSTR lpszName, FLAGS ulFlags, ULONG ulReserved, lpMapiRecipDesc FAR * lppRecip); ULONG (FAR PASCAL * lpfnMAPILogon) (ULONG ulUIParam, LPSTR lpszProfileName, LPSTR lpszPassword, FLAGS flFlags, ULONG ulReserved, LPLHANDLE lplhSession); ULONG (FAR PASCAL * lpfnMAPILogoff) (lHANDLE lhSession, ULONG ulUIParam, FLAGS flFlags, ULONG ulReserved); ULONG (FAR PASCAL * lpfnMAPIFreeBuffer) (LPVOID lpBuffer); ULONG (FAR PASCAL * lpfnMAPIAddress) (lHANDLE lhSession, ULONG ulUIParam, LPSTR lpszCaption, ULONG nEditFields, LPSTR lpszLabels, ULONG nRecips, lpMapiRecipDesc lpRecips, FLAGS flFlags, ULONG ulReserved, LPULONG lpnNewRecips, lpMapiRecipDesc FAR * lppNewRecips); ULONG (FAR PASCAL * lpfnMAPIFindNext) (lHANDLE lhSession, ULONG ulUIParam, LPSTR lpszMessageType, LPSTR lpszSeedMe ssageID, FLAGS flFlags, ULONG ulReserved, LPSTR lpszMessageID); ULONG (FAR PASCAL * lpfnMAPIReadMail) (LHANDLE lhSession, ULONG ulUIParam, LPSTR lpszMessageID, FLAGS flFlags, ULONG ulReserved, lpMapiMessage FAR * lppMessage); in order to determine the address of each function must Call getProcAddress for each function.
GetProcaddress's grammar is: getProcaddress (HModule, LPPROCNAME); where hmodule is hmodule structure, the handle of the calling DLL module; LPPROCNAME is the LPCSTR structure, which is a function name.
Example program: // Address MAPI32.DLL function, and stores them in the function pointer variable li (FARPROC &) lpfnMAPISendMail = GetProcAddress (hInstMail, "MAPISendMail"); (FARPROC &) lpfnMAPIResolveName = GetProcAddress (hInstMail, "MAPIResolveName"); (FARPROC &) lpfnMAPILogon = GetProcAddress (hInstMail, "MAPILogon"); (FARPROC &) lpfnMAPILogoff = GetProcAddress (hInstMail, "MAPILogoff"); (FARPROC &) lpfnMAPIFreeBuffer = GetProcAddress (hInstMail, "MAPIFreeBuffer"); (FARPROC &) lpfnMAPIAddress = GetProcAddress (hInstMail , "MAPIAddress"); (FARPROC &) lpfnMAPIFindNext = GetProcAddress (hInstMail, "MAPIFindNext"); (FARPROC &) lpfnMAPIReadMail = GetProcAddress (hInstMail, "MAPIReadMail"); 3-1-3 to log on to e-mail objects
Users must log in in the email system to implement MAPI's various functions. MAPI provides three options for login:
Log in to an existing object.
Log in to a new object, determine new information with programming methods.
Use the dialog to prompt the user to log in. We usually choose to log in to an existing email object because network cooperation users typically keep their email programs are active. Login usually uses the function provided by MAPI lpfnmapilogon.
LPFNMapilogon's grammar is: LPFNMAPILOGON (LPSZPROFILENAME, LPSZPASSWORD, FLFLAGS, ULRESERVED, LPLHSession);
Where lpszprofilename points to a login name within a 256-character, LPSZPassword points to password, which are both LPTSTR structures. Flflags is a Flags structure, which is detailed in Table 1. Ulnderved must be 0. LPLHSession is a handle of the output SMAPI.
Table 1: The value value of FLFLAGS in the lpfnmapilogon function mappi_force_downloadloads all messages downloaded before the function call returns. If Mapi_Force_Download is not set, the letter can be downloaded after the function call returns after the background. Mapi_new_session builds a new session instead of gaining a shared session. If MAPI_New_Session is not set, Mapilogon uses an existing shared session. Mapi_logon_UI Displays a login dialog to prompt the user to enter login information. This is the case, for example, Outlook checks the user email. Mapi_password_ui Mapilogon only allows the user to enter the password of the email, and not to change the account.
Example: LHANDLE LRESESSITION; Ulong Lresult = LPFNMAPILOGON (0, NULL, NULL, 0, 0, & LRESSION); if (LRESULT! = Success_suCcess) // Success_suCcess is defined in mapi.h {// Error handling}
3-2 Read Email
MapIfindNext and Mapireadmail use two basic functions that read E-mail. MapIfindNext is used to locate the first seal or next e-mail and return identification number, Mapireadmail returns the content of email based on this identification number. In addition, a commonly used function is MapifreeBuffer for release memory. 3-2-1 positioning to the first letter
To find the first letter, you need to use the MapIfindNext function, its function is declared as follows:
Ulong Far Pascal MapiFindNext (LHANDLE LHSESSION, ULONG ULUIPARAM, LPTSTSTSTSTSTSTSZSEEDMESSAGEID, FLAGS FLFLAGS, ULONG ULRESERVED, LPTSTR LPSZMESSAGEID)
Among them, LHSession is a session handle submitting SMAPI; uluiparam is a handle of a parent form; LPSZMESSAGETYPE points to a string to authenticate the mail type, and look for; lpszseedMessageId is a pointer to the starting information ID, which is 0, MaPIFINDNEXT gets the first email; the value of FLFlags see Table 2; ulReServed must be 0; lpszMessageId is the output value, which is a pointer to the information ID address.
Table 2: Value of FLFLAGS in the mapifIndNext function
Value significance mapi_guarantee-only accepts emails in time sequence sent by email. MAPI_LONG_MSGID returns the letters identifier to 512 characters. Mapi_unread_only only lists the email that has not been read.
Sample example: // Find the first email char PMER PMESSAGEID [513]; Ulong LRESULT = LPFNMAPIFINDNEXT (LHSession, NULL, NULL, NULL, MAPI_LONG_MSGID | MAPI_UNREAD_ONLY, 0, PMESSAGEID); 3-2-2 Read information When the letter ID is being acquired, you can call Mapireadmail to read the actual E-mail information. MAPIReadMail function declaration is as follows: ULONG FAR PASCAL MAPIReadMail (LHANDLE lhSession, ULONG ulUIParam, LPTSTR lpszMessageID, FLAGS flFlags, ULONG ulReserved, lpMapiMessage FAR * lppMessage); wherein, lppMessage to point MapiMessage pointer; other parameters lpfnFindNext function except flFlags of The same name is the same, the value of the Flflags parameter is seen in Table 3:
Table 3: Value of FLFlags in the mapireadmail function: Value significance mappi_body_as_file writes mail information into a temporary file, and adds it as the first attachment to the attachment list. Mapi_envelope_only reads only the email title. Mapi_peek does not mark it as "read" after reading the email. The Mapi_Suppress_attach mapiReadmail function is not copied, but the message text is written to the MapimESSAGE structure.
Program Example: // e-mail long nFlags = MAPI_SUPPRESS_ATTACH read; if (bMarkAsRead!) NFlags = nFlags | MAPI_PEEK; lResult = lpfnMAPIReadMail (lhSession, NULL, pMessageID, nFlags, 0, & pMessage); if (lResult = SUCCESS_SUCCESS!); Return False; If the call is successful, you can access the mapimsSage structure (using piment ": pimentage-> ulreserved: 0 pimentage-> lpszsubject: mail title pimentage-> lpsznotetext: mail information pimentage-> lpszMerationType: Mail Type
PMessage-> DateReceived: Receive Time PMessage-> LPSZCONVERSATIONID: Session thread id pimentage-> flflags: It is shown in Table 4
Table 4: The Flflags value of the MapiMessage structure mAPI_Receipt_requested reception notification is applied. The client application sets the item when sending a message. MAPI_SENT mail has been sent. MAPI_UNREAD mail is "unread" state.
PMessage-> Lporiginator: Points to the MapiRecipdesc structure, including sender information. PMessage-> NRecipcount: The number of letters. PMessage-> lprecips: Points an array of mapiRecIpdesc structures that contain recipient information. PMessage-> nfilecount: The number of attachments. PMessage-> LPFiles: Points an array of mapifileDesc structures, each structure contains a file attachment.
3-2-3 Release Memory
The memory should be released before accessing another letter, otherwise the memory leak will occur.
Example:
/ / Release Memory LPFNMapiFreeBuffer (PMessage); 3-2-4 Positioning to the next letter is positioned to the next letter Still using the mapifIndnext function, the function declaration and parameter meanings are available 3-2-1. How to demonstrate how to locate the next letter.
Sample example: // Located to the next letter Ulong LRESULT = LPFNMAPIFINDNEXT (LHSession, NULL, NULL, PMESSAGEID, MAPI_LONG_MSGID | MAPI_UNREAD_ONLY, 0, PMESSAGEID);
3-3 Send Email
General steps in sending emails:
1. Establish MapIMessage structural objects
2. Call MapiResolvename to legalize the sender name
3. Add attachments
4. Call MAPISENDMAIL Send Email
5. Call MapifreeBuffer Release Memory
The following detailed description in detail below.
3-3-1 Establish MapIMessage structural objects
For the Mapimessage structure, 3-2-2 has already been described, and step by step How to set the value:
1. Assign memory for the Mapimessage object:
Mapimestage Message; MEMSET (& Message, 0, SIZEOF (Message);
2. Set UlReServed to 0: Message.ulReServed = 0;
3. Setting information Type Pointer LpszMessageType, you can be NULL:
Message.lpszMessageType = NULL;
4. Set the letter title (LPSZSUBJECT):
CHAR SUBJECT [512]; STRCPY (SUBJECT, SSUBJECT); Message.lpszsubject = SUBJECT;
5. Set the letter content:
Char Text [5000]; STRCPY (Text, SMESSAGE); Message.lpsznotetext = text;
6. Set the flflags ID, see Table 4 in Table 4 in 3-2-2:
Message.flflags = MAPI_SENT;
7. Set the sender information (LPORINATOR) with a pointer to the MapiRecipdesc structure, or set it to NULL:
Message.lporiginator = NULL;
8. Set the number of recipients (NRECIPCOUNT), can be 1 or more:
Message.nrecipcount = 1;
9. Set up recipient information (LPRECIPS), see Section 3-3-2 for details
10. Set the number of attachments (NfileCount)
11. Set attachment information, see Section 3-3-3 for details
B3-3-2 Correctly set recipient information
When the recipient information is set, the MapiResolvename function should be used to allocate memory for the MapiRecipdesc structure object and return a pointer, which will be saved in the LPRCIPS of the Mapimestage structure. The function declaration of MapiResolvename is as follows:
Ulong Far Pascal MapiresolventAme (LHANDLE LHSESSION, ULONG ULUIPARAM, LPTSTSTSTSTSZZNAME, FLAGS FLFLAGS, ULONG ULRESERVED, LPMAPIRECIPDESC FAR * LPPRECIP)
Where lpPrecip is the returned pointer mentioned earlier. The remaining parameters except FLFLAGS are the same as the first few functions. The value of FLFlags is detailed in Table 5.
Table 5: Value Value Value Value Significance Mapi_AB_Nomodify dialog in MapiResolvename is read-only. If Mapi_Dialog is set, the item will be ignored. Mapi_dialog Displays a name solution MAPI_LOGON_UI if needed, will display the dialog box to make the user log in to Mapi_New_SESSION to create a new session
Example: Char Recipient [512]; STRCPY (Recipient, STO); LRESULT = LPFNMapiResolvename (LHSession, 0, Recipient, 0, 0, & Message.lPrecips);
3-3-3 Add accessories
The following program example will demonstrate how to include attachments in an email. Only one thing needs to be explained: the value of FLFLAGS in the mapiFileDesc structure is shown in Table 6.
Table 6: Value value of FLFLAGS in the MapiFileDesc structure MAPI_OLE Accessories are OLE objects. The MAPI_OLE_STATIC attachment is a static OLE object. 0 Annex will be considered a data file program example: // Set attachment information CString Spath, sfilename; mapifiledesc fileinfo; char path [512]; char filename [512]; if (Sattachment == ") Message.nFileCount = 0; Else {int npos = Sattachment.reverseFind ('//'); if (npos == -1) {spath = sattachment;} else {spath = sattachment; sfilename = sattachment.mid (Npos 1);} strcpy , Spath); STRCPY (FileName, sfileName);
Message.nfilecount = 1; fileinfo.ulReServed = 0;
FileInfo.flflags = 0;
Fileinfo.nposition = SMESSAGE.GETLENGTH () -1; fileInfo.lpszpathname = path; fileinfo.lpszfilename = filename; fileinfo.lpfiletype = null; message.lpfiles = & m_fileinfo;}
3-3-4 Send Email
Send an email using MapISendmail, which is as follows:
Ulong Far Pascal Mapisndmail (LHANDLE LHSESSION, ULONG ULUIPAR, LPMAPIMESSAGE LPMESSAGE, FLAGS FLFLAGS, ULONG ULRESERVED)
Among them, the allowable value of FLFLAGS is MAPI_DIALOG, MAPI_LOGON_UI and MAPI_NEW_SESSION, which is the same as the identification meaning of the same name in the first few functions.
Example:
LResult = lpfnmapisndmail (0, 0, & m_message, 0, 0);
3-3-5 Release Memory
Example: lpfnmapifreebuffer (m_message.lprecips);
Fourth, small junction This article is more specific and demonstrates the core part of writing an email program. If the reader wants to write an email program, it needs to be processed:
1. Plus an error handling code. Because of a space limit, only two of the program examples of this article are erroneous processing, and they are more different. Email programs are very easy to make mistakes, thus adding error handles after the main function call is completed, or use the Try Throw Catch block to process exceptions.
2. Plus UI processing.
In addition, the methods described in this paper are relatively easy. In fact, the procedures for emails are much more complicated than this, so readers need to write a powerful email program, need to be proficient in MAPI and SMTP / POP3; If the reader wants to write an email server, you may wish to read some information about Exchange Server after proficiency MAPI and SMTP / POP3.