Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: src/plugin/PluginClass.h

Issue 29332848: Issue #3432 - Manage COM events with a resource class
Patch Set: rebase, address comments Created Jan. 7, 2016, 4:21 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/plugin/PluginClass.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/plugin/PluginClass.h
===================================================================
--- a/src/plugin/PluginClass.h
+++ b/src/plugin/PluginClass.h
@@ -41,6 +41,95 @@
class CPluginMimeFilterClient;
+/**
+ * Resource class for COM events.
+ * If an instance exists, there's an active connection behind it.
+ *
+ * \tparam Sink
+ * subclass of ATL::IDispEventImpl.
+ * \tparam Source
+ * Type of event source. Implements IConnectionPoint
+ */
+template<class Sink, class Source>
+class AtlEventRegistration
+{
+ CComPtr<Sink> consumer;
+ CComPtr<Source> producer;
+public:
+ /**
+ * \throw std::runtime_error
+ * If connection is not established
+ *
+ * \par Precondition
+ * - consumer is not nullptr (not checked)
+ * - producer is not nullptr (not checked)
+ */
+ AtlEventRegistration(Sink* consumer, Source* producer)
sergei 2016/02/04 13:45:50 Just noticed, it would be better to call them as l
Eric 2016/02/04 17:00:28 Neither pair of words "source/sink" and "listener/
sergei 2016/02/04 19:41:57 I think we should not write the code how it would
Eric 2016/02/04 20:13:25 We've entered bikeshedding territory here. You hav
+ : consumer(consumer), producer(producer)
+ {
+ auto hr = consumer->DispEventAdvise(producer);
+ if (FAILED(hr))
+ {
+ DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVICE, "AtlEventRegistrationImpl::<constructor> - Advise");
+ throw std::runtime_error("DispEventAdvise() failed");
+ }
+ }
+
+ ~AtlEventRegistration() // noexcept
+ {
+ try
+ {
+ // Smart pointer members ensure that this statement does not fail because of life span
+ auto hr = consumer->DispEventUnadvise(producer);
+ if (FAILED(hr))
+ {
+ DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_UNADVISE, "AtlEventRegistrationImpl::<destructor> - Unadvise");
+ }
+ }
+ catch (...)
+ {
+ // Suppress exceptions
+ }
+ }
+};
+
+/**
+ * Resource holder for COM events.
+ *
+ * Manages the life time of an 'AtlEventRegistration' instance.
+ * Allows events to be started and stopped at some time other than construction/destruction.
+ *
+ * \tparam Sink
+ * subclass of ATL::IDispEventImpl.
+ * \tparam Source
+ * Type of event source. Implements IConnectionPoint
+ */
+template<class Sink, class Source>
+class AtlEventRegistrationHolder
+{
+ typedef AtlEventRegistration<Sink, Source> ImplType;
+ std::unique_ptr<ImplType> impl;
+
+public:
+ bool Start(Sink* consumer, Source* producer) // noexcept
+ {
+ try
+ {
+ impl.reset(new ImplType(consumer, producer));
+ }
+ catch (...)
+ {
+ impl.reset();
+ return false;
+ }
+ return true;
+ }
+
+ void Stop() // noexcept
+ {
+ impl.reset();
+ }
+};
class ATL_NO_VTABLE CPluginClass :
public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>,
@@ -73,7 +162,6 @@
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_WINDOWSTATECHANGED, OnWindowStateChanged)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_COMMANDSTATECHANGE, OnCommandStateChange)
- SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_ONQUIT, OnOnQuit)
END_SINK_MAP()
CPluginClass();
@@ -132,9 +220,7 @@
void STDMETHODCALLTYPE OnDocumentComplete(IDispatch* frameBrowserDisp, VARIANT* /*urlOrPidl*/);
void STDMETHODCALLTYPE OnWindowStateChanged(unsigned long flags, unsigned long validFlagsMask);
void STDMETHODCALLTYPE OnCommandStateChange(long command, VARIANT_BOOL enable);
- void STDMETHODCALLTYPE OnOnQuit();
- void Unadvise();
-
+
void ShowStatusBar();
bool IsStatusBarEnabled();
@@ -144,6 +230,12 @@
* It's values are set and reset solely in SetSite().
*/
CComPtr<IWebBrowser2> m_webBrowser2;
+ /**
+ * Event manager for events coming from our site object.
+ */
+ AtlEventRegistrationHolder<CPluginClass, IWebBrowser2> browserEvents;
+ bool detachedInitializationFailed;
+
HWND m_hBrowserWnd;
HWND m_hTabWnd;
HWND m_hStatusBarWnd;
@@ -157,7 +249,6 @@
NotificationMessage notificationMessage;
- bool m_isAdvised;
bool m_isInitializedOk;
// Atom pane class
« no previous file with comments | « no previous file | src/plugin/PluginClass.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld