Request # 19
How to resolve display name to e-mail address and bind the Global Address List (GAL) to TClientDataSet/TDataSource/TDBNavigator/etc..
Code snip:
procedure TfrmMain.btLogOnClick(Sender: TObject);
var
IsANSI: Boolean;
TagArray: PSPropTagArray;
uCount: ULONG;
RowSet: PSRowSet;
iCount, jCount: Integer;
PropValue: PSPropValue;
Proxy: String;
Cursor: TCursor;
const
GALColumnsA: record
cValues: ULONG;
aulPropTag: array [0 .. 4] of ULONG;
end = (cValues: 5;
aulPropTag: (PR_ENTRYID, PR_DISPLAY_NAME_A, PR_SMTP_ADDRESS_A,
PR_DEPARTMENT_NAME_A, PR_EMS_AB_PROXY_ADDRESSES_A);
);
GALColumnsW: record
cValues: ULONG;
aulPropTag: array [0 .. 4] of ULONG;
end = (cValues: 5;
aulPropTag: (PR_ENTRYID, PR_DISPLAY_NAME_W, PR_SMTP_ADDRESS_W,
PR_DEPARTMENT_NAME_W, PR_EMS_AB_PROXY_ADDRESSES_W);
);
begin
RowSet := nil;
Cursor := Screen.Cursor;
try
Screen.Cursor := crHourGlass;
GetGAL;
// Open GAL Contents Table
hr := FGAL.GetContentsTable(MAPI_UNICODE, FContentsTable);
// Table supports UNICODE ??
if hr = MAPI_E_BAD_CHARWIDTH then
begin
hr := FGAL.GetContentsTable(0, FContentsTable);
IsANSI := True;
end
else
IsANSI := False;
if failed(hr) then
raise EMapiError.CreateMAPI(FGAL, hr);
if IsANSI then
TagArray := @GALColumnsA
else
TagArray := @GALColumnsW;
// Set Fields
hr := FContentsTable.SetColumns(TagArray, TBL_BATCH);
if failed(hr) then
raise EMapiError.CreateMAPI(FContentsTable, hr);
uCount := 0;
hr := FContentsTable.GetRowCount(0, uCount);
if failed(hr) then
raise EMapiError.CreateMAPI(FContentsTable, hr);
// Empty GAL ????
if Int64(uCount) < 1 then
Exit;
// Set/Clear ClientDataSet
ClientDataSet.DisableControls;
ClientDataSet.EmptyDataSet;
while True do
begin
RowSet := nil;
// We will Query Table by 25 records
hr := FContentsTable.QueryRows(25, 0, RowSet);
if failed(hr) then
raise EMapiError.CreateMAPI(FContentsTable, hr);
if not Assigned(RowSet) or (RowSet.cRows < 1) then
break;
for iCount := 0 to RowSet.cRows - 1 do
begin
// Look for EntryID
PropValue := PpropFindProp(RowSet.aRow[iCount].lpProps,
RowSet.aRow[iCount].cValues, PR_ENTRYID);
if not Assigned(PropValue) then
Continue;
// Add a new record(GAL user)
ClientDataSet.Append;
// PR_ENTRYID
{$IF NOT DEFINED(DELPHI2009)}
SetAsBytes(
TBinaryField(ClientDataSet.FieldByName('EntryID')),
BinaryToBytes(PSPropValueArray(RowSet.aRow[iCount].lpProps)[0].Value.bin));
{$ELSE}
ClientDataSet.FieldByName('EntryID').AsBytes :=
BinaryToBytes(PSPropValueArray(RowSet.aRow[iCount].lpProps)[0].Value.bin);
{$IFEND}
// PR_DISPLAY_NAME
PropValue := PpropFindProp(RowSet.aRow[iCount].lpProps,
RowSet.aRow[iCount].cValues,
CHANGE_PROP_TYPE(PR_DISPLAY_NAME, PT_UNSPECIFIED)
);
if Assigned(PropValue) and (PROP_TYPE(PropValue.ulPropTag) <> PT_ERROR)
then
ClientDataSet.FieldByName('DisplayName').AsString :=
MAPIUtils.GetPropString(PropValue);
// PR_SMTP_ADDRESS
PropValue := PpropFindProp(RowSet.aRow[iCount].lpProps,
RowSet.aRow[iCount].cValues,
CHANGE_PROP_TYPE(PR_SMTP_ADDRESS, PT_UNSPECIFIED)
);
if Assigned(PropValue) and (PROP_TYPE(PropValue.ulPropTag) <> PT_ERROR)
then
ClientDataSet.FieldByName('SMTP').AsString := MAPIUtils.GetPropString(PropValue);
// PR_DEPARTMENT_NAME
PropValue := PpropFindProp(RowSet.aRow[iCount].lpProps,
RowSet.aRow[iCount].cValues,
CHANGE_PROP_TYPE(PR_DEPARTMENT_NAME, PT_UNSPECIFIED)
);
if Assigned(PropValue) and (PROP_TYPE(PropValue.ulPropTag) <> PT_ERROR)
then
ClientDataSet.FieldByName('Department').AsString := MAPIUtils.GetPropString(PropValue);
// PR_EMS_AB_PROXY_ADDRESSES
PropValue := PpropFindProp(RowSet.aRow[iCount].lpProps,
RowSet.aRow[iCount].cValues,
CHANGE_PROP_TYPE(PR_EMS_AB_PROXY_ADDRESSES, PT_UNSPECIFIED));
if Assigned(PropValue) and (PROP_TYPE(PropValue.ulPropTag) <> PT_ERROR)
then
begin
Proxy := '';
if PROP_TYPE(PropValue.ulPropTag) = PT_MV_UNICODE then
begin
for jCount := 0 to PropValue.Value.MVszW.cValues - 1 do
Proxy := Proxy + PWideCharArray(PropValue.Value.MVszW.lppszW)[jCount] + #10;
end
else
for jCount := 0 to PropValue.Value.MVszA.cValues - 1 do
Proxy := Proxy + String(PAnsiCharArray(PropValue.Value.MVszA.lppszA)[jCount]) + #10;
ClientDataSet.FieldByName('ProxyAddr').AsString := Proxy;
end;
end;
if Assigned(RowSet) then
FreePRows(RowSet);
end;
finally
if Assigned(RowSet) then
FreePRows(RowSet);
RowSet := nil;
if ClientDataSet.Active then
begin
ClientDataSet.EnableControls;
ClientDataSet.First;
lbRecords.Caption := 'Record Count:' + IntToStr(ClientDataSet.RecordCount);
end;
Screen.Cursor := Cursor;
btLogOn.Enabled := not Assigned(FMAPISession);
btLogOff.Enabled := not btLogOn.Enabled;
end;
end;
Download Request #19 as Compiled Application
Download Project (DELPHI 10.4) ZIP file
Source Code: In package

