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

StackOverflow https://stackoverflow.com/questions/10177021

Question

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;
Was it helpful?

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. :)

OTHER TIPS

It's been a loooooong time since i've written any Delphi (about 14 years) but i'm going to hazard a guess at this.

For security reasons some of the methods in the IMessenger interfaces are marked as NotScriptable. My guess is that your Delphi app is being treated by the interface as a scripting language, i.e. not native C++ code, and that's causing the Access Violation. You could prove this by looking at the reference to work out which are scriptable and which are not, and see which throw the Access Violation.

As for fixing it - as I said, i'm no Delphi expert, but is there another way you can instantiate the IMessenger objects? Or create a wrapper around the API in another language, to call from Delphi (there is an example of this here)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top