Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
DiscussionsAccessExcelInfoPathOutlookPowerPointPublisherWord
DirectoryUser Groups
Related Topics
Outlook ExpressInternet ExplorerWindowsMS Server ProductsMore Topics ...

MS Office Forum / Outlook / Programming Add-Ins / August 2006

Tip: Looking for answers? Try searching our database.

No PR_EMAIL_ADDRESS for recipient?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Slava Barouline - 14 Jul 2006 05:04 GMT
I noticed something strange when testing my Outlook Add-in

If I create a new email in Outlook 2003 and start to type some email
address, a blue drop-down appears and helps me to complete the address.

Sometimes it suggests only email address without display name, i.e.
sdsdfs@dfdf.com instead of say John Smith <sdsdfs@dfdf.com>

If I select the address from email,  it appears that Outlook treats these
addresses differently.

If I look at recipients table using Outlook Spy, I can see recipients email
address only in PR_DISPLAY_NAME, PR_RECIPIENT_DISPLAY_NAME and strange tag
0x6001 (0x6001001E)

PR_EMAIL_ADDRESS is not found

I thought PR_EMAIL_ADDRESS is always present

Should I use PR_DISPLAY_NAME if PR_EMAIL_ADDRESS is not found?

Thanks
Ken Slovak - [MVP - Outlook] - 14 Jul 2006 14:44 GMT
Have you tried saving the email before looking for PR_EMAIL_ADDRESS?

Signature

Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Author: Absolute Beginner's Guide to Microsoft Office Outlook 2003
Reminder Manager, Extended Reminders, Attachment Options
http://www.slovaktech.com/products.htm

>I noticed something strange when testing my Outlook Add-in
>
[quoted text clipped - 18 lines]
>
> Thanks
Slava Barouline - 17 Jul 2006 03:03 GMT
Yes, not much difference

> Have you tried saving the email before looking for PR_EMAIL_ADDRESS?
Ken Slovak - [MVP - Outlook] - 17 Jul 2006 16:06 GMT
Well, here at least until I save the email or send it there is nothing in
the Recipients table when I open the item using the IMessage button in
OutlookSpy. Once I do that I have PR_EMAIL_ADDRESS no matter whether the
suggestion was just email address or name + email address. I don't have that
strange property you mention.

I tested this on a Exchange profile, is that similar to yours or are you
using only a PST file?

If the display name property gives you what you want then use it.

Signature

Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Author: Absolute Beginner's Guide to Microsoft Office Outlook 2003
Reminder Manager, Extended Reminders, Attachment Options
http://www.slovaktech.com/products.htm

> Yes, not much difference
>
>> Have you tried saving the email before looking for PR_EMAIL_ADDRESS?
Slava Barouline - 21 Aug 2006 07:42 GMT
I do MailItem.Save in the code, but it dosn't seem to help.

If I press button in OutlookSpy, it works OK - I can see PR_EMAIL_ADDRESS
fine.

Maybe doing MailItem.Save is not enough?

Sometimes popup has only display name and no email address - it's worse as I
cannot use display name as email address.

I have Exchange profile

> Well, here at least until I save the email or send it there is nothing in
> the Recipients table when I open the item using the IMessage button in
[quoted text clipped - 6 lines]
>
> If the display name property gives you what you want then use it.
Ken Slovak - [MVP - Outlook] - 21 Aug 2006 14:36 GMT
Saving the item should be enough.

If you can see the property in OutlookSpy then it's there in the recipient
entry in the recipients table.

Maybe it's the code used. You haven't shown a code sample, let's see that
and see if anyone spots anything.

Signature

Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Author: Absolute Beginner's Guide to Microsoft Office Outlook 2003
Reminder Manager, Extended Reminders, Attachment Options
http://www.slovaktech.com/products.htm

>I do MailItem.Save in the code, but it dosn't seem to help.
>
[quoted text clipped - 7 lines]
>
> I have Exchange profile
Slava Barouline - 29 Aug 2006 04:28 GMT
Just to remind the problem
If I create a new email and start typing email address in To, Outlook
suggests some emails in a popup
Most emails look like Slava Barouline < email@com > , but sme have only
address or display name
The later fill recipients table incorrectly and don't get resolved even if I
call MailItem.Save in my code
I suspect Outlook delays resolving for some reason.
If I save email in Outlook by pressing a button, emails get resolved and
look OK in recipients table

Here it is (very scary code):

//Save before processing sent email:
.....

 //Save before accessing PR_BODY
 FMailItemToProcess.Save;
 ASubject := FMailItemToProcess.Subject;
 ABody := GetEmailBody;

...

 //Get Recipients List
 AnEmailAddresses := GetRecipientEmailAddresses;

.....

//Get emails from recipients table

function TMessageProcessor.GetRecipientEmailAddresses: TStringList;
var
 OneMessage: IMessage;
 RecTable:IMAPITable;
begin

 RecTable:=nil;
 OneMessage :=IUnknown(FMailItemToProcess.MAPIOBJECT) as IMessage;
 OleCheck(OneMessage.GetRecipientTable(0,RecTable));
 result := GetRecipientEmailAddressesFromTable(RecTable);
 RecTable := nil;
 OneMessage := nil;

end;

function
TMessageProcessor.GetRecipientEmailAddressesFromTable(RecTable:IMAPITable):
TStringList;
type
 LTSPropTagArray =
   record
     cValues : ULONG;
     aulPropTag : array[0..3] of ULONG;
   end;
 const
 FPropTagArray : LTSPropTagArray = (cValues:4;
                                  aulPropTag:(
                                  PR_DISPLAY_NAME,
                                  PR_EMAIL_ADDRESS,
                                  PR_ADDRTYPE,
                                  PR_ENTRYID)
                                  );
var
 NRec :integer;
 ListRecTable:IMAPITable;
 RecCount:Ulong;
 lppRows:PSRowSet;
 EMailAddress, AnAddressType, ADisplayName: string;
 i: Integer;
 DistList: IDistList;
 AddrBook: IAddrBook;
 lpcbeid, ulObjectType: ULONG;
 lppeid: PENTRYID;
 ProcessInternalEmails, AskConfirmation: Boolean;
begin

 result := TStringList.Create;
 lppRows:=nil;
 ProcessInternalEmails := False;
 AskConfirmation := True;

 OleCheck(RecTable.SetColumns(@FPropTagArray,TBL_BATCH));
 OleCheck(RecTable.GetRowCount(0,RecCount));

 dmMain.LogLine('Found ' + IntToStr(RecCount) + ' recipient(s)');

 if RecCount>0 then
 try

   OleCheck(RecTable.QueryRows(RecCount,TBL_NOADVANCE,lppRows));
   for Nrec:=0 to RecCount-1 do
   begin

     // PR_EMAIL_ADDRESS is an optional property
     // therefore we must access it in a try except
     try
       AnAddressType :=
lppRows.aRow[Nrec].lpProps[lppRows.aRow[Nrec].cValues-2].Value.lpsza;
       if UpperCase(AnAddressType) = 'MAPIPDL' then
       begin
         dmMain.LogLine('Found private distribution list - trying to
expand');

         //!!! Get DistList
         AddrBook := GetAddressBook;

//The IAddrBook.OpenEntry method opens an address book entry
//and returns a pointer to an interface that can be used
//to access the entry.

         lpcbeid :=
lppRows.aRow[Nrec].lpProps[lppRows.aRow[Nrec].cValues-1].Value.bin.cb;
         lppeid :=
LPENTRYID(lppRows.aRow[Nrec].lpProps[lppRows.aRow[Nrec].cValues-1].Value.bin.lpb);

         DistList:=nil;
         ulObjectType:=8;  //MAPI_DISTLIST

         OleCheck(AddrBook.OpenEntry(
             lpcbeid,
             lppeid,
             @IID_IDistList,
             MAPI_BEST_ACCESS or MAPI_DEFERRED_ERRORS,
             ulObjectType,
             IUnknown(DistList)));

         OleCheck(DistList.GetContentsTable(0,ListRecTable));

         with GetRecipientEmailAddressesFromTable(ListRecTable) do
           for i:= 0 to Count - 1 do
             result.AddObject(Strings[i], Objects[i]);

         DistList:=nil;
         ListRecTable := nil;

       end

       //Check Exchange email address type and ProcessInternalEmails
setting
       else if (UpperCase(AnAddressType) = 'EX')
         and not dmMain.ProcessInternalEmails then
       begin

         if ProcessInternalEmails then
         begin
           EMailAddress :=
lppRows.aRow[Nrec].lpProps[lppRows.aRow[Nrec].cValues-3].Value.lpsza;
           ADisplayName :=
lppRows.aRow[Nrec].lpProps[lppRows.aRow[Nrec].cValues-4].Value.lpsza;
           dmMain.LogLine('Recipient #' + IntToStr(Nrec + 1) +  ' - email
address: ' + EMailAddress + ' , display name: ' + ADisplayName);
           result.AddObject(EMailAddress,
TStringObject.Create(ADisplayName));
         end
         else
         begin
           EMailAddress :=
lppRows.aRow[Nrec].lpProps[lppRows.aRow[Nrec].cValues-3].Value.lpsza;
           ADisplayName :=
lppRows.aRow[Nrec].lpProps[lppRows.aRow[Nrec].cValues-4].Value.lpsza;
           dmMain.LogLine('Recipient #' + IntToStr(Nrec + 1) +  ' - email
address: ' + EMailAddress + ' , display name: ' + ADisplayName);
           dmMain.LogLine('Email address has Exchange address type');

           //Manual processing
           if AskConfirmation and FIsManualProcessing then
           begin
             if MessageDlg(strExchangeRecipientAddressTypeConfirmation,
mtConfirmation, [mbYes, mbNo], 0) = mrYes then
             begin
               ProcessInternalEmails := True;
               result.AddObject(EMailAddress,
TStringObject.Create(ADisplayName));
             end
             else
             begin
               ProcessInternalEmails := False;
               dmMain.LogLine('Email address skipped');
             end;
             AskConfirmation := False;
           end
           //Automatic processing - skip
           else
             dmMain.LogLine('Email address skipped');

         end;

       end
       else
       begin

         //In case PR_EMAIL_ADDRESS is not found, use PR_DISPLAY_NAME
instead
         ADisplayName :=
lppRows.aRow[Nrec].lpProps[lppRows.aRow[Nrec].cValues-4].Value.lpsza;
         try
           EMailAddress :=
lppRows.aRow[Nrec].lpProps[lppRows.aRow[Nrec].cValues-3].Value.lpsza;
         except
           dmMain.LogLine('Failed to read PR_EMAIL_ADDRESS, using
PR_DISPLAY_NAME instead');
           EMailAddress := ADisplayName;
         end;

         dmMain.LogLine('Recipient #' + IntToStr(Nrec + 1) +  ' - email
address: ' + EMailAddress + ' , display name: ' + ADisplayName);
         result.AddObject(EMailAddress,
TStringObject.Create(ADisplayName));
       end;

     except
       on e: Exception do
         dmMain.LogLine('Failed to read email address from recipient table
row with error message: ' + e.Message);
     end;
   end;

 except
   on e: Exception do
     dmMain.LogLine('Failed to retrieve recipients table with error
message: ' + e.Message);
 end;

 // Free each element in the pRows buffer
 FreeProws(lppRows);

end;

> Saving the item should be enough.
>
[quoted text clipped - 3 lines]
> Maybe it's the code used. You haven't shown a code sample, let's see that
> and see if anyone spots anything.
Ken Slovak - [MVP - Outlook] - 29 Aug 2006 14:53 GMT
I don't see anything offhand but I'm no C++ programmer or even Extended MAPI
programmer.

Have you tried resolving the recipients collection (Recipients.ResolveAll)
and seeing if that helps?

One thing is if the email addresses are in the GAL and the email display
name is not unique in the GAL then resolution will fail. In that case the
alias must be fully qualified to resolve ("joe@foobar.com") and not just
"joe".

Signature

Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Author: Absolute Beginner's Guide to Microsoft Office Outlook 2003
Reminder Manager, Extended Reminders, Attachment Options
http://www.slovaktech.com/products.htm

> Just to remind the problem
> If I create a new email and start typing email address in To, Outlook
[quoted text clipped - 223 lines]
>
> end;
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2010 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.