Advising an HTML control: when should I call DispE

2019-07-17 02:27发布

问题:

I use DispEventAdvise in a BHO in order to capture onclick events of a specific checkbox. You can see the code in my previous question (although it's not that relevant).

In order to be able to call DispEventUnadvise later, I keep a reference to the IHTMLElement object of the checkbox.

  1. When should I call DispEventUnadvise? Is there a way to know when the checkbox is going away?

  2. Is it even legal to keep a reference to the IHTMLElement object? I mean, when the page is destroyed, and there's still a reference to the object of that checkbox, what happens to it?

回答1:

You are expected to unadvise from event source/connection point when you no longer want to receive events. The call, in particular, make the connection point release your sink interface pointer. Before unadvising, connection point holds a reference and extends your sink object lifetime.

That is, you call it any time you want to opt out, there is no specific good time where you should do it at, other than general considerations.

The other part of the question "when checkbox is going away" however is not related directly. Being connected to connection point you don't receive "going away" notification. It is legal to keep holding an interface pointer even if the entire page went away: the checkbox, alone or together with its owner, will remain in terminating state until all external references (including yours) are released. As a part of safe termination, when the page/document goes away it might strip connection point connections from its side because no events are going to follow and the document is doing sanity cleanup to avoid circular references and leaks.

In your case, I suppose your best way out is to find another suitable event to see when the entire document goes away and assume that checkbox is going away as well. Another [less safe] option is to watch your sink interface object: once its external reference is unexpectedly release by connection point, it means that its doing cleanup and checkbox is going away.