MapiW Ostatnia aktualizacja: sobota 25 kwietnia 2020r. Plik PAS przeznaczony dla Delphi XE lub nowszych, zawierający nagłówki biblioteki interfejsu Simple MAPI wraz z strukturami i funkcjami w wersjach Unicode (WideChar).
Mimo, iż rozwiązania w interfejsie Simple MAPI istnieją już od czasu wydania Windows 8, Embarcadero wciąż nie rozbudowało swojej biblioteki WinAPI.MAPI o nowododane funkcje. Co więcej, nie znajdziemy ich też w plikach pakietu JCL - autorzy twierdzą, że nie dodadzą czegoś, co nie jest kombatybilne z Windows 7.
Zatem, aby ułatwić wszystkim, którzy chcą jednak korzystać w pełni z możliwości standardu Unicode używając interfejsu Simple MAPI, zamiszczam własną wersję pliku o nazwie WinAPI.MapiW .
Plik rozbudowany jest o funkcję MAPISendMailW wraz ze wszystkimi strukturami, które są przez nią wykorzystywane, zgodnie ze specyfikacją Microsoft.
Dodatkowo w pliku znajdują się jesszcze dwie funkcje:
CheckWMode - zwraca rezultat SUCCESS_SUCCESS w przypadku istnienia w zaisntalowanej w systemie bibliotece funkcji MapiSendMailW lub kod błędu w przypadku błędu ładowania - standardowy kod systemu Windows.
MAPIErrorToString - tłumaczy zwracane kody błędów na czytelną treść.
Ponadto wszystkie funkcje posiadają jeszcze jedną modyfikację - o ile w oryginale jakikolwiek problem z ładowaniem biblioteki MAPI kończy się zwróceniem wartości 1 , tak w mojej wersji zwracany jest konkretny kod błędu, ale z ujemnym znakiem. Zatem błędy MAPI (zwracane przez funkcje interfejsu) będą miały znak dodatni, a błędy związane z obsługą DLL standardowe kody Windows lecz ze znakiem ujemnym. Z tego też powodu - inaczej niż w specyfikacji - funkcje zwracają typ Int64 a nie Cardinal !
Plik można pobrać i używać we własnych aplikacjach zupełnie za darmo! Poniżej zajduje się przykład funkcji używającej omawiany plik do wysłania wiadomości, wraz ze sprawdzeniem obsługiwanego standardu:
uses System.Math, Winapi.Windows, Winapi.MapiW, Vcl.Forms;
...
function SendEmailWithAttach(const aLogon: Boolean; const aProfileName, aPassword: PAnsiChar; const aTo, aSubject, aBody, aFileName: PChar; aUnicode: Boolean; const aShowUI: Boolean): Int64;
type
TAttachAccessArray = array [0 .. 0] of TMapiFileDesc;
PAttachAccessArray = ^TAttachAccessArray;
TAttachAccessArrayW = array [0 .. 0] of TMapiFileDescW;
PAttachAccessArrayW = ^TAttachAccessArrayW;
var
MapiMessage: TMapiMessage;
MapiMessageW: TMapiMessageW;
Recip: array of TMapiRecipDesc;
RecipW: array of TMapiRecipDescW;
Attachments: PAttachAccessArray;
AttachmentsW: PAttachAccessArrayW;
FileName: String;
MAPI_Session: NativeUInt;
WndList: Pointer;
Odbiorcy: TStringList;
RClass, Email: String;
p, i: Integer;
tmpS: String;
begin
if not aShowUI and (aTo = '') then
Exit(MAPI_E_INVALID_RECIPS);
Result := 1 shl 32;
try
if aUnicode then
begin
if CheckWMode <> SUCCESS_SUCCESS then
aUnicode := False;
end;
if aLogon then
Result := MapiLogon(Application.Handle, aProfileName, aPassword, IfThen(aShowUI, MAPI_LOGON_UI) or MAPI_NEW_SESSION, 0, @MAPI_Session)
else
begin
Result := SUCCESS_SUCCESS;
MAPI_Session := lhSessionNull;
end;
if (Result <> SUCCESS_SUCCESS) and aShowUI then
MessageBox(Application.Handle, PChar('Błąd podczas wysłania maila!'#13 + MAPIErrorToString(Result)), 'Błąd logowania MAPI', MB_ICONERROR + MB_OK)
else
begin
FillChar(MapiMessage, SizeOf(MapiMessage), #0);
Attachments := nil;
FillChar(MapiMessageW, SizeOf(MapiMessageW), #0);
AttachmentsW := nil;
Odbiorcy := TStringList.Create;
with Odbiorcy do
begin
Delimiter := ';';
DelimitedText := String(aTo);
for i := Count - 1 downto 0 do
if (Strings[i] = '') then
Delete(i);
if aUnicode then
SetLength(RecipW, Count)
else
SetLength(Recip, Count);
end;
if aUnicode then
begin
for i := 0 to Length(RecipW) - 1 do
begin
with RecipW[i] do
begin
ulReserved := 0;
Email := Odbiorcy[i];
p := PosEx(':', Email);
if p > 0 then
begin
RClass := LeftStr(Email, p - 1);
Delete(Email, 1, p);
if RClass = 'CC' then
ulRecipClass := MAPI_CC
else if RClass = 'BCC' then
ulRecipClass := MAPI_BCC
else
ulRecipClass := MAPI_TO;
end
else
ulRecipClass := MAPI_TO;
lpszName := System.SysUtils.StrNew(PChar(Email));
lpszAddress := System.SysUtils.StrNew(PChar('SMTP:' + Email));
ulEIDSize := 0;
end;
end;
with MapiMessageW do
begin
nRecipCount := Odbiorcy.Count;
lpRecips := @RecipW[0];
end;
if aFileName <> '' then
begin
GetMem(AttachmentsW, SizeOf(TMapiFileDescW));
FileName := aFileName;
with AttachmentsW[0] do
begin
ulReserved := 0;
flFlags := 0;
nPosition := ULONG($FFFFFFFF);
lpszPathName := System.SysUtils.StrNew(aFileName);
tmpS := ExtractFileName(FileName);
lpszFileName := System.SysUtils.StrNew(PChar(tmpS));
lpFileType := nil;
end;
MapiMessageW.nFileCount := 1;
MapiMessageW.lpFiles := @AttachmentsW^;
end;
if aSubject <> '' then
MapiMessageW.lpszSubject := aSubject;
if aBody <> '' then
MapiMessageW.lpszNoteText := aBody;
WndList := DisableTaskWindows(0);
try
Result := MapiSendMailW(MAPI_Session, Application.Handle, MapiMessageW, IfThen(aShowUI, MAPI_DIALOG or MAPI_LOGON_UI), 0);
finally
EnableTaskWindows(WndList);
end;
if aFileName <> '' then
begin
System.SysUtils.StrDispose(AttachmentsW[0].lpszPathName);
System.SysUtils.StrDispose(AttachmentsW[0].lpszFileName);
end;
for i := 0 to Length(RecipW) - 1 do
begin
with RecipW[i] do
begin
if Assigned(lpszAddress) then
System.SysUtils.StrDispose(lpszAddress);
if Assigned(lpszName) then
System.SysUtils.StrDispose(lpszName);
end;
end;
end
else
begin // non Unicode
for i := 0 to Length(Recip) - 1 do
begin
with Recip[i] do
begin
ulReserved := 0;
Email := Odbiorcy[i];
p := PosEx(':', Email);
if p > 0 then
begin
RClass := LeftStr(Email, p - 1);
Delete(Email, 1, p);
if RClass = 'CC' then
ulRecipClass := MAPI_CC
else if RClass = 'BCC' then
ulRecipClass := MAPI_BCC
else
ulRecipClass := MAPI_TO;
end
else
ulRecipClass := MAPI_TO;
lpszName := System.AnsiStrings.StrNew(PAnsiChar(AnsiString(Email)));
lpszAddress := System.AnsiStrings.StrNew(PAnsiChar(AnsiString('SMTP:' + Email)));
ulEIDSize := 0;
end;
end;
with MapiMessage do
begin
nRecipCount := Odbiorcy.Count;
lpRecips := @Recip[0];
end;
if aFileName <> '' then
begin
GetMem(Attachments, SizeOf(TMapiFileDesc));
FileName := aFileName;
with Attachments[0] do
begin
ulReserved := 0;
flFlags := 0;
nPosition := ULONG($FFFFFFFF);
lpszPathName := System.AnsiStrings.StrNew(PAnsiChar(AnsiString(aFileName)));
tmpS := ExtractFileName(FileName);
lpszFileName := System.AnsiStrings.StrNew(PAnsiChar(AnsiString(tmpS)));
lpFileType := nil;
end;
MapiMessage.nFileCount := 1;
MapiMessage.lpFiles := @Attachments^;
end;
if aSubject <> '' then
MapiMessage.lpszSubject := System.AnsiStrings.StrNew(PAnsiChar(AnsiString(String(aSubject))));
if aBody <> '' then
MapiMessage.lpszNoteText := System.AnsiStrings.StrNew(PAnsiChar(AnsiString(String(aBody))));
WndList := DisableTaskWindows(0);
try
Result := MapiSendMail(MAPI_Session, Application.Handle, MapiMessage, IfThen(aShowUI, MAPI_DIALOG or MAPI_LOGON_UI), 0);
finally
EnableTaskWindows(WndList);
end;
if aFileName <> '' then
begin
System.AnsiStrings.StrDispose(Attachments[0].lpszPathName);
System.AnsiStrings.StrDispose(Attachments[0].lpszFileName);
end;
for i := 0 to Length(Recip) - 1 do
begin
with Recip[i] do
begin
if Assigned(lpszAddress) then
System.AnsiStrings.StrDispose(lpszAddress);
if Assigned(lpszName) then
System.AnsiStrings.StrDispose(lpszName);
end;
end;
if MapiMessage.lpszSubject <> '' then
System.AnsiStrings.StrDispose(MapiMessage.lpszSubject);
if MapiMessage.lpszNoteText <> '' then
System.AnsiStrings.StrDispose(MapiMessage.lpszNoteText);
end;
Odbiorcy.Free;
if (Result <> SUCCESS_SUCCESS) and> aShowUI then
MessageBox(Application.Handle, PChar('Błąd podczas wysłania maila!'#13' + MAPIErrorToString(Result)), 'Błąd wysyłania wiadomości MAPI', MB_ICONERROR + MB_OK);
SetLength(Recip, 0);
SetLength(RecipW, 0);
if MAPI_Session <> lhSessionNull then
MapiLogOff(MAPI_Session, Application.Handle, 0, 0);
end;
except
on E: Exception do
if aShowUI then
Application.MessageBox(PChar('Nieprzewidziany błąd:'#13 + E.Message), PChar('Błąd'), MB_ICONERROR + MB_OK);
end;
end;
Download
Wróć
|