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

Delta Between Two Patch Sets: src/plugin/PluginClass.h

Issue 29332848: Issue #3432 - Manage COM events with a resource class
Left Patch Set: rebase Created Jan. 5, 2016, 4:21 p.m.
Right Patch Set: rebase only Created July 27, 2016, 8:55 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/plugin/PluginClass.cpp » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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-2016 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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
(...skipping 30 matching lines...) Expand all
44 /** 44 /**
45 * Resource class for COM events. 45 * Resource class for COM events.
46 * If an instance exists, there's an active connection behind it. 46 * If an instance exists, there's an active connection behind it.
47 * 47 *
48 * \tparam Sink 48 * \tparam Sink
49 * subclass of ATL::IDispEventImpl. 49 * subclass of ATL::IDispEventImpl.
50 * \tparam Source 50 * \tparam Source
51 * Type of event source. Implements IConnectionPoint 51 * Type of event source. Implements IConnectionPoint
52 */ 52 */
53 template<class Sink, class Source> 53 template<class Sink, class Source>
54 class AtlEventRegistration 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 { 55 {
56 CComPtr<Sink> consumer; 56 CComPtr<Sink> consumer;
57 CComPtr<Source> producer; 57 CComPtr<Source> producer;
58 public: 58 public:
59 /** 59 /**
60 * \throw std::runtime_error 60 * \throw std::runtime_error
61 * If connection is not established 61 * If connection is not established
62 * 62 *
63 * \par Precondition 63 * \par Precondition
64 * - consumer is not nullptr (not checked) 64 * - consumer is not nullptr (not checked)
65 * - producer is not nullptr (not checked) 65 * - producer is not nullptr (not checked)
66 */ 66 */
67 AtlEventRegistration(Sink* consumer, Source* producer) 67 AtlEventRegistration(Sink* consumer, Source* producer)
68 : consumer(consumer), producer(producer) 68 : consumer(consumer), producer(producer)
69 { 69 {
70 auto hr = consumer->DispEventAdvise(producer); 70 auto hr = consumer->DispEventAdvise(producer);
71 if (FAILED(hr)) 71 if (FAILED(hr))
72 { 72 {
73 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVICE, " AtlEventRegistrationImpl::<constructor> - Advise"); 73 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADVICE, " AtlEventRegistrationImpl::<constructor> - Advise");
74 throw std::runtime_error("DispEventAdvise() failed"); 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 } 75 }
76 } 76 }
77 77
78 ~AtlEventRegistration() // noexcept 78 ~AtlEventRegistration() // noexcept
79 { 79 {
80 try 80 try
81 { 81 {
82 // Smart pointer members ensure that this statement does not fail because of life span 82 // Smart pointer members ensure that this statement does not fail because of life span
83 auto hr = consumer->DispEventUnadvise(producer); 83 auto hr = consumer->DispEventUnadvise(producer);
84 if (FAILED(hr)) 84 if (FAILED(hr))
(...skipping 19 matching lines...) Expand all
104 * \tparam Source 104 * \tparam Source
105 * Type of event source. Implements IConnectionPoint 105 * Type of event source. Implements IConnectionPoint
106 */ 106 */
107 template<class Sink, class Source> 107 template<class Sink, class Source>
108 class AtlEventRegistrationHolder 108 class AtlEventRegistrationHolder
109 { 109 {
110 typedef AtlEventRegistration<Sink, Source> ImplType; 110 typedef AtlEventRegistration<Sink, Source> ImplType;
111 std::unique_ptr<ImplType> impl; 111 std::unique_ptr<ImplType> impl;
112 112
113 public: 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 114 bool Start(Sink* consumer, Source* producer) // noexcept
122 { 115 {
123 try 116 try
124 { 117 {
125 impl = new ImplType(consumer, producer); 118 impl.reset(new ImplType(consumer, producer));
126 } 119 }
127 catch (...) 120 catch (...)
128 { 121 {
129 impl = nullptr; 122 impl.reset();
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; 123 return false;
131 } 124 }
132 return true; 125 return true;
133 } 126 }
134 127
135 Stop() // noexcept 128 void Stop() // noexcept
136 { 129 {
137 impl = nullptr; 130 impl.reset();
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 } 131 }
139 }; 132 };
140
141 class ATL_NO_VTABLE CPluginClass : 133 class ATL_NO_VTABLE CPluginClass :
142 public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>, 134 public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>,
143 public ATL::CComCoClass<CPluginClass, &CLSID_PluginClass>, 135 public ATL::CComCoClass<CPluginClass, &CLSID_PluginClass>,
144 public ATL::IObjectWithSiteImpl<CPluginClass>, 136 public ATL::IObjectWithSiteImpl<CPluginClass>,
145 public IOleCommandTarget, 137 public IOleCommandTarget,
146 public ATL::IDispEventImpl<1, CPluginClass, &DIID_DWebBrowserEvents2, &LIBID_S HDocVw, 1, 1> 138 public ATL::IDispEventImpl<1, CPluginClass, &DIID_DWebBrowserEvents2, &LIBID_S HDocVw, 1, 1>
147 { 139 {
148 140
149 friend class CPluginTab; 141 friend class CPluginTab;
150 142
(...skipping 24 matching lines...) Expand all
175 ~CPluginClass(); 167 ~CPluginClass();
176 168
177 // IObjectWithSite 169 // IObjectWithSite
178 STDMETHOD(SetSite)(IUnknown *pUnkSite); 170 STDMETHOD(SetSite)(IUnknown *pUnkSite);
179 171
180 // IOleCommandTarget 172 // IOleCommandTarget
181 STDMETHOD(QueryStatus)(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT* pCmdText); 173 STDMETHOD(QueryStatus)(const GUID* pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT* pCmdText);
182 STDMETHOD(Exec)(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, VARIANTARG* pva Out); 174 STDMETHOD(Exec)(const GUID*, DWORD nCmdID, DWORD, VARIANTARG*, VARIANTARG* pva Out);
183 175
184 176
185 static CPluginTab* GetTab(DWORD dwThreadId); 177 static CPluginTab* GetTabForCurrentThread();
186 CPluginTab* GetTab(); 178 CPluginTab* GetTab();
187 179
188 void UpdateStatusBar(); 180 void UpdateStatusBar();
189 181
190 private: 182 private:
191 183
192 bool SetMenuBar(HMENU hMenu, const std::wstring& url); 184 bool SetMenuBar(HMENU hMenu, const std::wstring& url);
193 HMENU CreatePluginMenu(const std::wstring& url); 185 HMENU CreatePluginMenu(const std::wstring& url);
194 186
195 void DisplayPluginMenu(HMENU hMenu, int nToolbarCmdID, POINT pt, UINT nMenuFla gs); 187 void DisplayPluginMenu(HMENU hMenu, int nToolbarCmdID, POINT pt, UINT nMenuFla gs);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 void ShowStatusBar(); 223 void ShowStatusBar();
232 bool IsStatusBarEnabled(); 224 bool IsStatusBarEnabled();
233 225
234 /** 226 /**
235 * A browser interface pointer to our site object 227 * A browser interface pointer to our site object
236 * 228 *
237 * It's values are set and reset solely in SetSite(). 229 * It's values are set and reset solely in SetSite().
238 */ 230 */
239 CComPtr<IWebBrowser2> m_webBrowser2; 231 CComPtr<IWebBrowser2> m_webBrowser2;
240 /** 232 /**
241 * Event manager for events coming from our site object. 233 * 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 */ 234 */
243 AtlEventRegistrationHolder<CPluginClass, IWebBrowser2> browserEvents; 235 AtlEventRegistrationHolder<CPluginClass, IWebBrowser2> browserEvents;
244 bool detachedInitializationFailed; 236 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 237
246 HWND m_hBrowserWnd; 238 HWND m_hBrowserWnd;
247 HWND m_hTabWnd; 239 HWND m_hTabWnd;
248 HWND m_hStatusBarWnd; 240 HWND m_hStatusBarWnd;
249 HWND m_hPaneWnd; 241 HWND m_hPaneWnd;
250 242
251 WNDPROC m_pWndProcStatus; 243 WNDPROC m_pWndProcStatus;
252 int m_nPaneWidth; 244 int m_nPaneWidth;
253 HANDLE m_hTheme; 245 HANDLE m_hTheme;
254 246
(...skipping 13 matching lines...) Expand all
268 static DWORD s_hIconTypes[ICON_MAX]; 260 static DWORD s_hIconTypes[ICON_MAX];
269 261
270 static HICON GetIcon(int type); 262 static HICON GetIcon(int type);
271 263
272 // Main thread 264 // Main thread
273 static HANDLE s_hMainThread; 265 static HANDLE s_hMainThread;
274 static bool s_isMainThreadDone; 266 static bool s_isMainThreadDone;
275 267
276 static HINSTANCE s_hUxtheme; 268 static HINSTANCE s_hUxtheme;
277 static std::set<CPluginClass*> s_instances; 269 static std::set<CPluginClass*> s_instances;
278 static std::map<DWORD,CPluginClass*> s_threadInstances;
279 static CComAutoCriticalSection s_criticalSectionLocal; 270 static CComAutoCriticalSection s_criticalSectionLocal;
280 static CComAutoCriticalSection s_criticalSectionWindow; 271 static CComAutoCriticalSection s_criticalSectionWindow;
281 272
282 // Async browser 273 // Async browser
283 static CComQIPtr<IWebBrowser2> s_asyncWebBrowser2; 274 static CComQIPtr<IWebBrowser2> s_asyncWebBrowser2;
284 static CComQIPtr<IWebBrowser2> GetAsyncBrowser(); 275 static CComQIPtr<IWebBrowser2> GetAsyncBrowser();
285 }; 276 };
286 277
287 OBJECT_ENTRY_AUTO(__uuidof(PluginClass), CPluginClass) 278 OBJECT_ENTRY_AUTO(__uuidof(PluginClass), CPluginClass)
288 279
289
290 #endif // _PLUGIN_CLASS_H_ 280 #endif // _PLUGIN_CLASS_H_
LEFTRIGHT

Powered by Google App Engine
This is Rietveld