WIndows MAPI unicode problem

It seems to me that MAPI (Windows Mail API) has problems with UTF8 (or maybe I did something wrong).

Sample code:

HMODULE m_hLib = LoadLibraryA("MAPI32.DLL");
if (m_hLib == NULL)
    return SEND_MAIL_CANCELED;
LPMAPISENDMAIL SendMail;
SendMail = (LPMAPISENDMAIL) GetProcAddress(m_hLib, "MAPISendMail");
if (!SendMail)
    return;

MapiFileDesc fileDesc;
ZeroMemory(&fileDesc, sizeof(fileDesc));
fileDesc.nPosition = (ULONG) -1;
fileDesc.lpszPathName = (LPSTR) filePath.toUtf8();
fileDesc.lpszFileName = (LPSTR) fileName.toUtf8();

MapiRecipDesc recipientData;
ZeroMemory(&recipientData, sizeof(recipientData));
recipientData.lpszName = (LPSTR) recipient.toUtf8();
recipientData.ulRecipClass = MAPI_TO;

MapiMessage message;
ZeroMemory(&message, sizeof(message));
message.ulReserved = CP_UTF8;
message.lpszSubject = (LPSTR) title.toUtf8();
message.nFileCount = 1;
message.lpFiles = &fileDesc;
message.nRecipCount = 1;
message.lpRecips = &recipientData;

int nError = SendMail(0, NULL, &message, MAPI_LOGON_UI | MAPI_DIALOG, 0);

      

title

, filePath

, fileName

And recipient

- all the std::string

s. As far as I know, UTF8 is ASCII compliant (also NULL terminated), so its string can contain values ​​like this without any problem.

I am converting to UTF8 from wstring like this:

int requiredSize = WideCharToMultiByte(CP_UTF8, 0, data.c_str(), -1, 0, 0, 0, 0);
if(requiredSize > 0)
{
    std::vector<char> buffer(requiredSize);
    WideCharToMultiByte(CP_UTF8, 0, data.c_str(), -1, &buffer[0], requiredSize, 0, 0);
    this->container.append(buffer.begin(), buffer.end() - 1);
}

      

container

- object std::string

.

+3


source to share


1 answer


MAPISendMail()

doesn't support UTF-8, only Ansi. If you need to send Unicode data, you must use it MAPISendMailHelper()

on Windows 7 and earlier, or MAPISendMailW()

Windows 8 and later. This is clearly stated in the documentation MAPISendMail()

.

On a side note, WideCharToMultiByte()

enables a zero terminator when you set the parameter cchWideChar

to -1. This way you code and include this null delimiter in your data container

. Instead, it should be set cchWideChar

to the actual length of the string to eliminate the null terminator entirely:



int requiredSize = WideCharToMultiByte(CP_UTF8, 0, data.c_str(), data.length(), 0, 0, 0, 0); 
if (requiredSize > 0) 
{ 
    std::vector<char> buffer(requiredSize); 
    WideCharToMultiByte(CP_UTF8, 0, data.c_str(), data.length(), &buffer[0], requiredSize, 0, 0); 
    container.append(buffer.begin(), buffer.end()); 
} 

      

In http://msdn.microsoft.com/en-us/library/windows/desktop/dd296721.aspx reads: "In Windows 7 and earlier versions use MAPISendMailHelper to send a message," but the bottom of the http: // msdn. microsoft.com/en-us/library/windows/desktop/hh802867.aspx it states that "Minimum Support" is Windows 8. Seems like conflicting information and so it is not clear if MAPISendMailHelper is valid for Windows 7 and earlier.

+8


source







All Articles