1

[continued from Is there a way to tell whether two COM interface references point at the same instance?]

I've got references to Inspector objects from two different sources and need to be able to tell which item from one source corresponds to which item from the other source. However, none of the approaches I have been able to come up with so far worked (reliably):

  • I couldn't simply compare the IUnknown interfaces as it seems that the Inspectors.Item() method is returning a reference to a created-on-the-fly proxy object rather than the inspector instance itself. Try it: Accessing the same index twice will return two distinctly different pointers.

  • Comparing Inspector.CurrentItem.EntryID is no good either. A new/unsaved items' EntryID is always blank and there could potentially be more than one unsaved item open at a time.

  • Inspector.Caption or Inspector.CurrentItem.Subject is likewise ambiguous.

  • Temporarily setting Inspector.CurrentItem.Subject (or any other item property really) to an unambiguous value and then looking for that in the other list kind of works but has the annoying side-effect of marking the item in the inspector as "dirty", i.e. upon closing the inspector again the user will be asked to save the item (even if he was just viewing a received mail).

Any other ideas?


Context:

I'm trying to work around the well-known bug/feature that new email messages initiated via Simple MAPI (e.g. Send to>Mail recipient in Explorer context menu) do not generate an Inspectors.NewInspector event thus making it impossible to add any addin functionality to those inspectors (e.g. adding toolbar buttons or executing code on message creation). In my COM-addin I've got an internal list of wrapper objects to catch Inspector-events. Items are added and removed to this list by monitoring the Inspectors.NewInspector and Inspector.Close events.

As an alternative approach I'm using a shell hook: I am now able to get notified whenever a new inspector window is created or destroyed so that appears to be a good spot to jump in and match my internal list of wrapper objects with the Application.Inspectors collection and add or remove new or orphaned wrapper objects accordingly.

Community
  • 1
  • 1
Oliver Giesen
  • 8,745
  • 5
  • 43
  • 81

2 Answers2

1

I now found that comparing Inspector.CurrentItem.CreationTime was sufficiently reliable for me.

Oliver Giesen
  • 8,745
  • 5
  • 43
  • 81
0

You could also use the Is operator to see if two object references are referring to the same object.

Ex:

Debug.Print InspectorObj1 Is InspectorObj2

This will print True to the Immediate Window if both references refer to the same Inspector.

JimmyPena
  • 8,424
  • 5
  • 40
  • 62
  • Is that VB(A) code? Assuming `Is` would translate to the equality operator in other languages, this will unfortunately not work unless both references came from the same source (also see my first bullet point). That's kind of the whole problem here: One reference is obtained as an argument of an event handler and the other one comes from the `Application.Inspectors` collection. In that case, simply comparing the two will *always* identify them as different objects. – Oliver Giesen Nov 09 '11 at 11:37
  • Yes it is VBA code. I'm not sure I understand your objection. The source of the objects shouldn't matter. If both object references point to the same object, the equality operator will return **True**. I could easily see a passed reference in an event handler and a reference from Application.Inspectors pointing to the same object. – JimmyPena Nov 09 '11 at 13:17
  • Also you may want to tag questions with the programming language you are using. It isn't always clear and you probably don't want someone giving you a code solution you can't use. It also makes it easier for people looking for those types of questions to find them. – JimmyPena Nov 09 '11 at 13:19
  • Well, the whole point of the question was that the source /does/ matter, otherwise your approach would of course have been a no-brainer... (I'm still assuming that `is` is simply an equality operator for objects in VBA) I think the problem is that Outlook internally creates wrapper objects on the fly and hands you references to those rather than to the actual underlying objects - and it does this each and every time you request them. So, effectively the references do really not (directly) point at the same object. [tbc...] – Oliver Giesen Nov 09 '11 at 17:02
  • [ctd...] If VBA's `Is`-operator can indeed overcome this problem then I'd really love to know what is going on under the hood... – Oliver Giesen Nov 09 '11 at 17:02
  • Oh, and I'm using Delphi. But as it's all COM anyway I don't think it makes enough of a difference to add the tag. Also, adding a language tag will often result in people *not* even reading the question because they don't know the language. – Oliver Giesen Nov 09 '11 at 17:08
  • Sorry I can't be more help here. I agree that the source shouldn't make a difference. Doesn't Delphi have a method for comparing object references? – JimmyPena Nov 09 '11 at 17:14
  • It surely does but, as I said, the references are simply not the same. Have you tried your example? Are you able to look up an inspector you got from an event (e.g. `NewInspector`) in the `Application.Inspectors` collection? – Oliver Giesen Nov 10 '11 at 11:01