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

Side by Side Diff: src/plugin/PluginClass.h

Issue 29332848: Issue #3432 - Manage COM events with a resource class
Patch Set: rebase Created Jan. 5, 2016, 4:21 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/plugin/PluginClass.cpp » ('j') | src/plugin/PluginClass.cpp » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 23 matching lines...) Expand all
34 34
35 #define ICON_PLUGIN_DISABLED 0 35 #define ICON_PLUGIN_DISABLED 0
36 #define ICON_PLUGIN_ENABLED 1 36 #define ICON_PLUGIN_ENABLED 1
37 #define ICON_PLUGIN_DEACTIVATED 2 37 #define ICON_PLUGIN_DEACTIVATED 2
38 #define ICON_MAX 3 38 #define ICON_MAX 3
39 39
40 #define WM_LAUNCH_INFO (WM_APP + 10) 40 #define WM_LAUNCH_INFO (WM_APP + 10)
41 41
42 class CPluginMimeFilterClient; 42 class CPluginMimeFilterClient;
43 43
44 /**
45 * Resource class for COM events.
46 * If an instance exists, there's an active connection behind it.
47 *
48 * \tparam Sink
49 * subclass of ATL::IDispEventImpl.
50 * \tparam Source
51 * Type of event source. Implements IConnectionPoint
52 */
53 template<class Sink, class Source>
54 class AtlEventRegistration
sergei 2016/01/06 08:41:58 I doubt that we need two classes here, AtlEventReg
Eric 2016/01/07 16:24:48 It's not overengineering. You actually want two cl
sergei 2016/02/04 13:45:50 Answered in the message.
Eric 2016/02/04 17:00:27 Perhaps you are unclear about PImpl. PImpl = Poin
sergei 2016/02/04 19:41:57 I don't want to debate here, but it's not PIMPL, I
Eric 2016/02/04 20:13:25 I don't want to debate here either, so I'll forgo
55 {
56 CComPtr<Sink> consumer;
57 CComPtr<Source> producer;
58 public:
59 /**
60 * \throw std::runtime_error
61 * If connection is not established
62 *
63 * \par Precondition
64 * - consumer is not nullptr (not checked)
65 * - producer is not nullptr (not checked)
66 */
67 AtlEventRegistration(Sink* consumer, Source* producer)
68 : consumer(consumer), producer(producer)
69 {
70 auto hr = consumer->DispEventAdvise(producer);
71 if (FAILED(hr))
72 {
73 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVICE, " AtlEventRegistrationImpl::<constructor> - Advise");
74 throw std::runtime_error("DispEventAdvise() failed");
sergei 2016/01/06 08:41:57 I would prefer to make private constructor and hav
Eric 2016/01/07 16:24:48 I consider this suggestion an inferior design. See
sergei 2016/02/04 13:45:49 I consider the current impl as overengineering and
Eric 2016/02/04 17:00:27 Yes, I know. You said that already.
sergei 2016/02/04 19:41:57 I have not said whether I like exceptions or not,
Eric 2016/02/04 20:13:25 You'll have to tell me what "logic" you're talking
75 }
76 }
77
78 ~AtlEventRegistration() // noexcept
79 {
80 try
81 {
82 // Smart pointer members ensure that this statement does not fail because of life span
83 auto hr = consumer->DispEventUnadvise(producer);
84 if (FAILED(hr))
85 {
86 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_UNADVIS E, "AtlEventRegistrationImpl::<destructor> - Unadvise");
87 }
88 }
89 catch (...)
90 {
91 // Suppress exceptions
92 }
93 }
94 };
95
96 /**
97 * Resource holder for COM events.
98 *
99 * Manages the life time of an 'AtlEventRegistration' instance.
100 * Allows events to be started and stopped at some time other than construction/ destruction.
101 *
102 * \tparam Sink
103 * subclass of ATL::IDispEventImpl.
104 * \tparam Source
105 * Type of event source. Implements IConnectionPoint
106 */
107 template<class Sink, class Source>
108 class AtlEventRegistrationHolder
109 {
110 typedef AtlEventRegistration<Sink, Source> ImplType;
111 std::unique_ptr<ImplType> impl;
112
113 public:
114 AtlEventRegistrationHolder()
115 : impl(nullptr)
sergei 2016/01/06 08:41:58 This line as well as the empty constructor and des
Eric 2016/01/07 16:24:48 Done.
116 {}
117
118 ~AtlEventRegistrationHolder() // = default;
119 {}
120
121 bool Start(Sink* consumer, Source* producer) // noexcept
122 {
123 try
124 {
125 impl = new ImplType(consumer, producer);
126 }
127 catch (...)
128 {
129 impl = nullptr;
sergei 2016/01/06 08:41:58 This line is not needed.
Eric 2016/01/07 16:24:48 It is. Start() has the semantics of stopping whate
sergei 2016/02/04 13:45:50 Actually expecting that Start can be called severa
130 return false;
131 }
132 return true;
133 }
134
135 Stop() // noexcept
136 {
137 impl = nullptr;
sergei 2016/01/06 08:41:58 it's correct, but I find it better to use impl.res
Eric 2016/01/07 16:24:48 Done.
138 }
139 };
44 140
45 class ATL_NO_VTABLE CPluginClass : 141 class ATL_NO_VTABLE CPluginClass :
46 public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>, 142 public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>,
47 public ATL::CComCoClass<CPluginClass, &CLSID_PluginClass>, 143 public ATL::CComCoClass<CPluginClass, &CLSID_PluginClass>,
48 public ATL::IObjectWithSiteImpl<CPluginClass>, 144 public ATL::IObjectWithSiteImpl<CPluginClass>,
49 public IOleCommandTarget, 145 public IOleCommandTarget,
50 public ATL::IDispEventImpl<1, CPluginClass, &DIID_DWebBrowserEvents2, &LIBID_S HDocVw, 1, 1> 146 public ATL::IDispEventImpl<1, CPluginClass, &DIID_DWebBrowserEvents2, &LIBID_S HDocVw, 1, 1>
51 { 147 {
52 148
53 friend class CPluginTab; 149 friend class CPluginTab;
(...skipping 12 matching lines...) Expand all
66 COM_INTERFACE_ENTRY(IObjectWithSite) 162 COM_INTERFACE_ENTRY(IObjectWithSite)
67 COM_INTERFACE_ENTRY(IOleCommandTarget) 163 COM_INTERFACE_ENTRY(IOleCommandTarget)
68 END_COM_MAP() 164 END_COM_MAP()
69 165
70 BEGIN_SINK_MAP(CPluginClass) 166 BEGIN_SINK_MAP(CPluginClass)
71 SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, OnBeforeNa vigate2) 167 SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, OnBeforeNa vigate2)
72 SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOWNLOADCOMPLETE, OnDownloa dComplete) 168 SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOWNLOADCOMPLETE, OnDownloa dComplete)
73 SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumen tComplete) 169 SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumen tComplete)
74 SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_WINDOWSTATECHANGED, OnWindo wStateChanged) 170 SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_WINDOWSTATECHANGED, OnWindo wStateChanged)
75 SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_COMMANDSTATECHANGE, OnComma ndStateChange) 171 SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_COMMANDSTATECHANGE, OnComma ndStateChange)
76 SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_ONQUIT, OnOnQuit)
77 END_SINK_MAP() 172 END_SINK_MAP()
78 173
79 CPluginClass(); 174 CPluginClass();
80 ~CPluginClass(); 175 ~CPluginClass();
81 176
82 // IObjectWithSite 177 // IObjectWithSite
83 STDMETHOD(SetSite)(IUnknown *pUnkSite); 178 STDMETHOD(SetSite)(IUnknown *pUnkSite);
84 179
85 // IOleCommandTarget 180 // IOleCommandTarget
86 STDMETHOD(QueryStatus)(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT* pCmdText); 181 STDMETHOD(QueryStatus)(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT* pCmdText);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 VARIANT* URL /**< [in] */, 220 VARIANT* URL /**< [in] */,
126 VARIANT* Flags /**< [in] */, 221 VARIANT* Flags /**< [in] */,
127 VARIANT* TargetFrameName /**< [in] */ , 222 VARIANT* TargetFrameName /**< [in] */ ,
128 VARIANT* PostData /**< [in] */, 223 VARIANT* PostData /**< [in] */,
129 VARIANT* Headers /**< [in] */, 224 VARIANT* Headers /**< [in] */,
130 VARIANT_BOOL* Cancel /* [in, out] */) ; 225 VARIANT_BOOL* Cancel /* [in, out] */) ;
131 void STDMETHODCALLTYPE OnDownloadComplete(); 226 void STDMETHODCALLTYPE OnDownloadComplete();
132 void STDMETHODCALLTYPE OnDocumentComplete(IDispatch* frameBrowserDisp, VARIANT * /*urlOrPidl*/); 227 void STDMETHODCALLTYPE OnDocumentComplete(IDispatch* frameBrowserDisp, VARIANT * /*urlOrPidl*/);
133 void STDMETHODCALLTYPE OnWindowStateChanged(unsigned long flags, unsigned long validFlagsMask); 228 void STDMETHODCALLTYPE OnWindowStateChanged(unsigned long flags, unsigned long validFlagsMask);
134 void STDMETHODCALLTYPE OnCommandStateChange(long command, VARIANT_BOOL enable) ; 229 void STDMETHODCALLTYPE OnCommandStateChange(long command, VARIANT_BOOL enable) ;
135 void STDMETHODCALLTYPE OnOnQuit(); 230
136 void Unadvise();
137
138 void ShowStatusBar(); 231 void ShowStatusBar();
139 bool IsStatusBarEnabled(); 232 bool IsStatusBarEnabled();
140 233
141 /** 234 /**
142 * A browser interface pointer to our site object 235 * A browser interface pointer to our site object
143 * 236 *
144 * It's values are set and reset solely in SetSite(). 237 * It's values are set and reset solely in SetSite().
145 */ 238 */
146 CComPtr<IWebBrowser2> m_webBrowser2; 239 CComPtr<IWebBrowser2> m_webBrowser2;
240 /**
241 * Event manager for events coming from our site object.
sergei 2016/01/06 08:41:58 Why do we need this comment?
Eric 2016/01/07 16:24:48 Because we have multiple sources of events. We ha
sergei 2016/02/04 13:45:49 I mean, it's clear from line `AtlEventRegistration
Eric 2016/02/04 17:00:27 It's a Doxygen comment.
242 */
243 AtlEventRegistrationHolder<CPluginClass, IWebBrowser2> browserEvents;
244 bool detachedInitializationFailed;
sergei 2016/01/06 08:41:58 The member naming is not consistent with other mem
sergei 2016/01/06 08:41:58 Since it's accessed from different threads, there
Eric 2016/01/07 16:24:48 You're raising a valid issue, certainly, but I've
Eric 2016/01/07 16:24:48 Right. It's not there because "m_" prefixes are ag
245
147 HWND m_hBrowserWnd; 246 HWND m_hBrowserWnd;
148 HWND m_hTabWnd; 247 HWND m_hTabWnd;
149 HWND m_hStatusBarWnd; 248 HWND m_hStatusBarWnd;
150 HWND m_hPaneWnd; 249 HWND m_hPaneWnd;
151 250
152 WNDPROC m_pWndProcStatus; 251 WNDPROC m_pWndProcStatus;
153 int m_nPaneWidth; 252 int m_nPaneWidth;
154 HANDLE m_hTheme; 253 HANDLE m_hTheme;
155 254
156 CriticalSection m_csStatusBar; 255 CriticalSection m_csStatusBar;
157 256
158 NotificationMessage notificationMessage; 257 NotificationMessage notificationMessage;
159 258
160 bool m_isAdvised;
161 bool m_isInitializedOk; 259 bool m_isInitializedOk;
162 260
163 // Atom pane class 261 // Atom pane class
164 static ATOM s_atomPaneClass; 262 static ATOM s_atomPaneClass;
165 263
166 static ATOM GetAtomPaneClass(); 264 static ATOM GetAtomPaneClass();
167 265
168 // Icons 266 // Icons
169 static HICON s_hIcons[ICON_MAX]; 267 static HICON s_hIcons[ICON_MAX];
170 static DWORD s_hIconTypes[ICON_MAX]; 268 static DWORD s_hIconTypes[ICON_MAX];
(...skipping 12 matching lines...) Expand all
183 281
184 // Async browser 282 // Async browser
185 static CComQIPtr<IWebBrowser2> s_asyncWebBrowser2; 283 static CComQIPtr<IWebBrowser2> s_asyncWebBrowser2;
186 static CComQIPtr<IWebBrowser2> GetAsyncBrowser(); 284 static CComQIPtr<IWebBrowser2> GetAsyncBrowser();
187 }; 285 };
188 286
189 OBJECT_ENTRY_AUTO(__uuidof(PluginClass), CPluginClass) 287 OBJECT_ENTRY_AUTO(__uuidof(PluginClass), CPluginClass)
190 288
191 289
192 #endif // _PLUGIN_CLASS_H_ 290 #endif // _PLUGIN_CLASS_H_
OLDNEW
« no previous file with comments | « no previous file | src/plugin/PluginClass.cpp » ('j') | src/plugin/PluginClass.cpp » ('J')

Powered by Google App Engine
This is Rietveld