WIndows MAPI unicode问题

在我看来,MAPI(Windows Mail API)与UTF8的问题(或者我做错了什么)。

代码示例:

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); 

titlefilePathfileNamerecipient都是std::string s。 据我所知,UTF8兼容ASCII(也是NULL终止),所以它的string可以保存这样的值没有任何问题。

我以这种方式从wstring转换为UTF8:

 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是一个std::string对象。

MAPISendMail()不支持UTF-8,只有Ansi。 如果您需要发送Unicode数据,则必须在Windows 7及更早版本上使用MAPISendMailHelper() ,或者在Windows 8及更高版本上使用MAPISendMailHelper() 。 这在MAPISendMail()文档中有明确说明。

在附注中,当您将cchWideChar参数设置为-1时, WideCharToMultiByte()包含空终止符。 因此,您正在编码并在您的container数据中container空终止符。 您应该将cchWideChar设置为字符串的实际长度以完全避免空终止符:

 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()); } 

http://msdn.microsoft.com/en-us/library/windows/desktop/dd296721.aspx它声明“在Windows 7和更早版本:使用MAPISendMailHelper发送消息”,但在http:// msdn的底部它声明“最低支持”是Windows 8.似乎是矛盾的信息,因此目前还不清楚MAPISendMailHelper是否真的适用于Windows 7和更早版本。