delphipascaloffice-communicator

Why do I get an access violation when I call Microsoft Communicator 2007's IMessengerContacts.Count method?


I want to display the contacts from my list onto a TListBox. I have Communicator installed and running on my Windows 7 PC, running Delphi XE. I am using CommunicatorAPI_TLB and CommunicatorPrivate_TLB.

I click on the login and logout buttons, and the programs works as expected: my Communicator logs in and out. Cool.

The problem is when I try to click on the list-users button. The Contacts.Count method seems to throw me an access violation. I tried it with groups, and the same results. Can anyone spot what I am doing wrong?

  { This IMessenger3 Class Inherits from the IMessenger2 interface -> IMessenger... }
  Communicator : IMessenger3;
  Contacts     : IMessengerContacts;
  Contact      : IMessengerContact;
  Groups       : IMessengerGroups;
  Connected    : Boolean;

End;

Var
  frmMain: TfrmMain;

Implementation

{$R *.dfm}

{ ---------------------------------------------------------------------------- }

Procedure TfrmMain.FormCreate(Sender: TObject);
Begin    
  Communicator := CoMessenger.Create;      
End; { FormCreate Procedure }

Procedure TfrmMain.btnSignInClick(Sender: TObject);
Begin    
  Communicator.AutoSignin;
  Connected := True;        
End;  { btnSignInClick Procedure }

Procedure TfrmMain.btnSignOutClick(Sender: TObject);
Begin    
  Communicator.Signout;
  Connected := False;      
End;  { btnSignOutClick Procedure }


Procedure TfrmMain.btnLoadContactsClick(Sender: TObject);
Var
  ContactIndex : Integer;                                                       
Begin      
  { Load my contacts into a listbox }
  Contacts := IMessengerContacts (Communicator.MyContacts);
  Groups   := IMessengerGroups (Communicator.MyGroups);

  If (Contacts <> Nil) Then Begin

    try
      showmessage (inttostr(Groups.Count));
      showmessage (inttostr(Contacts.count));
    except    
    end;
  (*
    For ContactIndex := 0 To (Contacts.Count) Do Begin

     Contact := IMessengerContact (Contacts.Item (ContactIndex));

     { Add the contact to the list }
     lbxContacts.AddItem (Contact.FriendlyName, Nil);

    End; { For }
  *)
  End; { If <> Nil }

End;

Solution

  • Change the two typecasts to use as instead. If the problem is that the interface isn't available, you'll at least get an error message that's meaningful.

    Change

    Contacts := IMessengerContacts(Communicator.MyContacts); 
    Groups   := IMessengerGroups (Communicator.MyGroups);
    

    to

    Contacts := Communicator.MyContacts as ImessengerContacts; 
    Groups   := Communicator.MyGroups as IMessengerGroups;
    

    You should probably do the same thing to other places you're typecasting to get interfaces. It's always better when possible to ask for them politely than to forcibly grab them. :)