Для этого нам понадобится небольшой класс. Он слегка недоделан: отправка почты и получение списка аттачей, но это доделать не так сложно.
Описание протокола Simple MAPI можно почитать по адресу: http://msdn.microsoft.com/en-us/library/dd296728(v=VS.85).aspx
Итак, описание класса на C++ (Builder):
#ifndef SimpleMapiH #define SimpleMapiH using namespace std; #include <windows.h> #include <windowsx.h> #include <mapi.h> #include <winbase.h> #include <vector> //структура с информацией о письме struct TMail { AnsiString from; AnsiString subj; unsigned int files; TDateTime date; //указатели на письмо LPSTR lpszMessageID; MapiMessage *lpMessage; }; class SimpleMapi { private: //библиотека и указатели на нужные нам функции HANDLE hMAPILib; LPMAPILOGON lpfnMAPILogon; LPMAPIFINDNEXT lpfnMAPIFindNext; LPMAPILOGOFF lpfnMAPILogoff; LPMAPIREADMAIL lpfnMAPIReadMail; LPMAPIFREEBUFFER lpfnMAPIFreeBuffer; //текущая сессия LHANDLE lhSession; //буфферы char szSeedMessageID[512]; char szMessageID[512]; LPSTR lpszSeedMessageID; LPSTR lpszMessageID; //указатель на письмо MapiMessage *lpMessage; //тип ошибки ULONG err; //разбор даты TDateTime __fastcall ParseDate(AnsiString date); public: //полный список писем vector<tmail> MailList; __fastcall SimpleMapi(); //подключение к Exchenge bool __fastcall Connect(); //перейти к первому письму из списка bool __fastcall GetFirst(); //перейти к следующему письму из списка bool __fastcall GetNext(); //получить указатель на полную информацию о текущем письме bool __fastcall GetElement(); //заполнить структуру текущим письмом TMail __fastcall Fetch(); //получить список всех писем (заполняем вектор) bool __fastcall GetList(); //отключаемся от Exchange void __fastcall Disconnect(); //отправить письмо - не реализовано void __fastcall SendMail(); //получить список приложений письма по указателю vector<ansistring> __fastcall GetAttachs(LPSTR lmID, MapiMessage *lpMes); }; #endif
#include <vcl.h> #pragma hdrstop #include "SimpleMapi.h" #pragma package(smart_init) __fastcall SimpleMapi::SimpleMapi() { lpszSeedMessageID=&szSeedMessageID[0]; lpszMessageID=&szMessageID[0]; *lpszSeedMessageID = '\0'; //необходимые нам функции из мапи hMAPILib = LoadLibrary("MAPI32.DLL"); lpfnMAPILogon = (LPMAPILOGON) GetProcAddress(hMAPILib, "MAPILogon"); lpfnMAPILogoff = (LPMAPILOGOFF) GetProcAddress(hMAPILib, "MAPILogoff"); lpfnMAPIFindNext = (LPMAPIFINDNEXT) GetProcAddress(hMAPILib, "MAPIFindNext"); lpfnMAPIReadMail = (LPMAPIREADMAIL) GetProcAddress(hMAPILib, "MAPIReadMail"); lpfnMAPIFreeBuffer = (LPMAPIFREEBUFFER) GetProcAddress(hMAPILib, "MAPIFreeBuffer"); } //подключаемся к мапи bool __fastcall SimpleMapi::Connect() { err = (*lpfnMAPILogon)(0L, "Microsoft Outlook", NULL, 0L, 0L, &lhSession); if(err != SUCCESS_SUCCESS) { FreeLibrary(hMAPILib); return false; } return true; } //получаем первое письмо bool __fastcall SimpleMapi::GetFirst() { //MAPI_GUARANTEE_FIFO - сортировка по дате err = (*lpfnMAPIFindNext)(lhSession, 0L, NULL, lpszSeedMessageID, MAPI_GUARANTEE_FIFO, 0L, lpszMessageID); return err == SUCCESS_SUCCESS; } //получаем следующее письмо bool __fastcall SimpleMapi::GetNext() { //MAPI_GUARANTEE_FIFO - сортировка по дате //чистим буфер (*lpfnMAPIFreeBuffer)(lpMessage); lstrcpy(lpszSeedMessageID, lpszMessageID); //переходим err = (*lpfnMAPIFindNext)(lhSession, 0L, NULL, lpszSeedMessageID, MAPI_GUARANTEE_FIFO, 0L, lpszMessageID); return err == SUCCESS_SUCCESS; } //заполняет указатель на письмо bool __fastcall SimpleMapi::GetElement() { //MAPI_SUPPRESS_ATTACH - аттачи тоже загружаем err = (*lpfnMAPIReadMail)(lhSession, 0L, lpszMessageID, MAPI_SUPPRESS_ATTACH, 0L, &lpMessage); return err == SUCCESS_SUCCESS; } //заполним структуру данными письма TMail __fastcall SimpleMapi::Fetch() { TMail buf; if((lpMessage->lpOriginator->lpszName != NULL) && lpMessage->lpOriginator->lpszName[0] != '\0') { buf.from = lpMessage->lpOriginator->lpszName; } else { buf.from = lpMessage->lpOriginator->lpszAddress; } buf.subj = AnsiString(lpMessage->lpszSubject); buf.files = (unsigned int)lpMessage->nFileCount; buf.date = SimpleMapi::ParseDate(AnsiString(lpMessage->lpszDateReceived)); buf.lpszMessageID = lpszMessageID; buf.lpMessage = lpMessage; return buf; } //распарсить дату письма (учтем перевод стрелок) TDateTime __fastcall SimpleMapi::ParseDate(AnsiString date) { //пример: 2010/04/02 12:02 unsigned short y,m,d,h,i,s; y = (unsigned short)date.SubString(1, 4).ToInt(); m = (unsigned short)date.SubString(6, 2).ToInt(); d = (unsigned short)date.SubString(9, 2).ToInt(); h = (unsigned short)date.SubString(12, 2).ToInt(); i = (unsigned short)date.SubString(15, 2).ToInt(); TTimeZoneInformation tzi; if(GetTimeZoneInformation(&tzi) == TIME_ZONE_ID_STANDARD) { //в зимнее время добавляем 1 час h++; } TDateTime dt(y, m, d); TDateTime tm(h, i, 0, 0); return dt + tm; } //заполним вектор письмами bool __fastcall SimpleMapi::GetList() { if(!Connect()) return false; if(!GetFirst()) return false; TMail buf; int i = 0; while(err == SUCCESS_SUCCESS) { if(GetElement()) { buf = Fetch(); MailList.push_back(buf); } GetNext(); if(i%1000 == 0 && i > 0) { //переделать на вопрос if( Application->MessageBox("Загрузка списка писем может занять продолжительное время. Продолжить?", Application->Title.c_str(), MB_ICONQUESTION | MB_YESNO) == IDNO ) break; } i++; } Disconnect(); return true; } //отключаемся void __fastcall SimpleMapi::Disconnect() { //закрываем подключение (*lpfnMAPILogoff)(lhSession, 0L, 0L, 0L); //освобождаем библиотеку FreeLibrary(hMAPILib); } void __fastcall SimpleMapi::SendMail() { //TODO /* документация: http://msdn.microsoft.com/en-us/library/dd296721(v=VS.85).aspx примеры: - http://stackoverflow.com/questions/2350011/how-do-i-programmatically-send-email-w-attachment-to-a-known-recipient-using-mapi - http://www.codeproject.com/KB/IP/SendTo.aspx - http://www.codeguru.com/forum/archive/index.php/t-105158.html (без приложений) */ } //получить список аттачей //аттачи сохраняются во временную дирректорию vector<AnsiString> __fastcall SimpleMapi::GetAttachs(LPSTR lmID, MapiMessage *lpMes) { vector<AnsiString> atachs; err = (*lpfnMAPIReadMail)(lhSession, 0L, lmID, MAPI_SUPPRESS_ATTACH, 0L, &lpMes); if(err == SUCCESS_SUCCESS) { //TODO //for(int i = 0; i < lpMes->nFileCount; i++) { //lpMes->lpFiles->lpszPathName; //lpMes->lpFiles->lpszFileName; //lpMes->lpFiles++; //} } return atachs; }
Комментариев нет:
Отправить комментарий