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

Side by Side Diff: src/engine/NotificationWindow.h

Issue 6505394822184960: Issue 1109 - Support notifications (Closed)
Patch Set: fix obtaining of DPI value of content (NotificationWindow) of NotificationBorderWindow Created Aug. 18, 2015, 9:43 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #ifndef NOTIFICATION_WINDOW_H
19 #define NOTIFICATION_WINDOW_H
20
21 #include <atlbase.h>
22 #include <atlwin.h>
23 #include <atlctl.h>
24 #include <atlimage.h>
25 #include <AdblockPlus/JsValue.h>
26 #include <AdblockPlus/Notification.h>
27 #include <functional>
28 #include <MsHtmdid.h>
29
30 class IconStaticControl : public ATL::CWindow
31 {
32 public:
33 explicit IconStaticControl(HWND hWnd = nullptr) : ATL::CWindow(hWnd)
34 { }
35
36 IconStaticControl& operator=(HWND hWnd)
37 {
38 m_hWnd = hWnd;
39 return *this;
40 }
41
42 HWND Create(HWND hWndParent, ATL::_U_RECT rect = nullptr, LPCTSTR szWindowName = nullptr,
43 DWORD dwStyle = 0, DWORD dwExStyle = 0,
44 ATL::_U_MENUorID MenuOrID = nullptr, LPVOID lpCreateParam = nullptr)
45 {
46 return ATL::CWindow::Create(GetWndClassName(), hWndParent, rect.m_lpRect, sz WindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam);
47 }
48
49 static wchar_t* GetWndClassName()
50 {
51 return L"STATIC";
52 }
53
54 void SetBitmap(HBITMAP hBitmap)
55 {
56 ATLASSERT(::IsWindow(m_hWnd));
57 ::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_BITMAP, reinterpret_cast<LPARAM>(h Bitmap));
58 }
59 };
60
61 template<typename T>
62 class ScopedObjectHandle
63 {
64 public:
65 explicit ScopedObjectHandle(T handle = nullptr) : m_handle(handle)
66 { }
67
68 ~ScopedObjectHandle()
69 {
70 if(m_handle != nullptr)
71 {
72 ::DeleteObject(m_handle);
73 m_handle = nullptr;
74 }
75 }
76
77 ScopedObjectHandle& operator=(T handle)
78 {
79 if(m_handle != nullptr && m_handle != handle)
80 ::DeleteObject(m_handle);
81 m_handle = handle;
82 return *this;
83 }
84
85 T Detach()
86 {
87 T retValue = m_handle;
88 m_handle = nullptr;
89 return retValue;
90 }
91
92 operator T()
93 {
94 return m_handle;
95 }
96
97 operator bool() const
98 {
99 return m_handle == nullptr;
100 }
101 protected:
102 T m_handle;
103 private:
104 ScopedObjectHandle(const ScopedObjectHandle&);
105 ScopedObjectHandle& operator=(const ScopedObjectHandle&);
106 };
107
108 class CBrush : public ScopedObjectHandle<HBRUSH>
109 {
110 public:
111 explicit CBrush(HBRUSH brush = nullptr) : ScopedObjectHandle(brush)
112 {
113 }
114
115 void CreateSolidBrush(COLORREF crColor)
116 {
117 ATLASSERT(m_handle == nullptr);
118 m_handle = ::CreateSolidBrush(crColor);
119 }
120 };
121
122 class ScopedModule
123 {
124 public:
125 ScopedModule()
126 : m_hModule(nullptr)
127 {
128 }
129
130 bool Open(const wchar_t* fileName, int flags)
131 {
132 m_hModule = LoadLibraryEx(fileName, nullptr, flags);
133 return m_hModule != nullptr;
134 }
135
136 ~ScopedModule()
137 {
138 if (m_hModule != nullptr)
139 {
140 FreeLibrary(m_hModule);
141 m_hModule = nullptr;
142 }
143 }
144 operator HMODULE()
145 {
146 return m_hModule;
147 }
148 private:
149 ScopedModule(const ScopedModule&);
150 ScopedModule& operator=(const ScopedModule&);
151 private:
152 HMODULE m_hModule;
153 };
154
155 class DpiAwareness {
156 public:
157 DpiAwareness() : m_dpi(96)
158 {
159 }
160 protected:
161 uint32_t DPIAware(uint32_t value) const {
162 return MulDiv(value, m_dpi, 96);
163 }
164 SIZE DPIAware(SIZE value) const {
165 return CSize(DPIAware(value.cx), DPIAware(value.cy));
166 }
167 RECT DPIAware(RECT value) const {
168 return CRect(DPIAware(value.left), DPIAware(value.top), DPIAware(value.right ), DPIAware(value.bottom));
169 }
170 uint32_t m_dpi;
171 };
172
173 enum
174 {
175 // ID of HTMLDocument ActiveX control, it's used for event binding.
176 kHTMLDocumentCtrlID = 101
177 };
178
179 class NotificationWindow : public ATL::CWindowImpl<NotificationWindow>
180 , ATL::IDispEventImpl<kHTMLDocumentCtrlID, NotificationWindow, &DIID_HTMLDocum entEvents2, &LIBID_MSHTML, 4, 0>
181 , protected DpiAwareness
182 {
183 public:
184 explicit NotificationWindow(const AdblockPlus::Notification& notification, con st std::wstring& htmlFileDir);
185 ~NotificationWindow();
186 BEGIN_MSG_MAP(NotificationWindow)
187 if (uMsg == WM_CREATE)
188 {
189 SetMsgHandled(TRUE);
190 lResult = OnCreate(reinterpret_cast<CREATESTRUCT*>(lParam));
191 if(IsMsgHandled())
192 return TRUE;
193 }
194 MESSAGE_HANDLER(WM_LBUTTONUP, OnClick)
195 MESSAGE_HANDLER(WM_RBUTTONUP, OnClick)
196 MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColor)
197 if (uMsg == WM_SIZE)
198 {
199 SetMsgHandled(TRUE);
200 OnSize(static_cast<uint32_t>(wParam), CSize(GET_X_LPARAM(lParam), GET_Y_LP ARAM(lParam)));
201 lResult = 0;
202 if(IsMsgHandled())
203 return TRUE;
204 }
205 if (uMsg == WM_DESTROY)
206 {
207 SetMsgHandled(TRUE);
208 OnDestroy();
209 lResult = 0;
210 if(IsMsgHandled())
211 return TRUE;
212 }
213 END_MSG_MAP()
214
215 BEGIN_SINK_MAP(NotificationWindow)
216 SINK_ENTRY_EX(kHTMLDocumentCtrlID, DIID_HTMLDocumentEvents2, DISPID_HTMLDOCU MENTEVENTS2_ONCLICK, OnHTMLDocumentClick)
217 SINK_ENTRY_EX(kHTMLDocumentCtrlID, DIID_HTMLDocumentEvents2, DISPID_HTMLDOCU MENTEVENTS2_ONSELECTSTART, OnHTMLDocumentSelectStart)
218 END_SINK_MAP()
219
220 void SetOnClick(const std::function<void()>& callback)
221 {
222 m_onClickCallback = callback;
223 }
224 void SetOnLinkClicked(const std::function<void(const std::wstring& url)>& call back)
225 {
226 m_onLinkClickedCallback = callback;
227 }
228 void SetOnClose(const std::function<void()>& callback)
229 {
230 m_onCloseCallback = callback;
231 }
232 private:
233 LRESULT OnCreate(const CREATESTRUCT* createStruct);
234 LRESULT OnCtlColor(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled);
235 LRESULT OnClick(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled);
236 void OnSize(uint32_t wParam, CSize size);
237 void OnDestroy();
238
239 void __stdcall OnHTMLDocumentClick(IHTMLEventObj* pEvtObj);
240 void __stdcall OnHTMLDocumentSelectStart(IHTMLEventObj* pEvtObj);
241
242 void LoadABPIcon();
243 private:
244 std::wstring m_htmlPage;
245 CBrush m_bgColor;
246 ATL::CAxWindow m_axIE;
247 ATL::CImage m_iconImg;
248 IconStaticControl m_icon;
249 std::vector<std::wstring> m_links;
250 std::function<void()> m_onClickCallback;
251 std::function<void()> m_onCloseCallback;
252 std::function<void(const std::wstring& url)> m_onLinkClickedCallback;
253 };
254
255 typedef ATL::CWinTraits<WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_TOOL WINDOW | WS_EX_TOPMOST> NotificationBorderWindowStyles;
256 class NotificationBorderWindow : public ATL::CWindowImpl<NotificationBorderWindo w, ATL::CWindow, NotificationBorderWindowStyles>
257 , protected DpiAwareness
258 {
259 public:
260 DECLARE_WND_CLASS_EX(/*generate class name*/nullptr, CS_DROPSHADOW, WHITE_BRUS H);
261 NotificationBorderWindow(const AdblockPlus::Notification& notification, const std::wstring& htmlFileDir);
262 BEGIN_MSG_MAP(NotificationWindow)
263 if (uMsg == WM_CREATE)
264 {
265 SetMsgHandled(TRUE);
266 lResult = OnCreate(reinterpret_cast<CREATESTRUCT*>(lParam));
267 if(IsMsgHandled())
268 return TRUE;
269 }
270 MESSAGE_HANDLER(WM_LBUTTONUP, OnClick)
271 MESSAGE_HANDLER(WM_RBUTTONUP, OnClick)
272 if (uMsg == WM_SIZE)
273 {
274 SetMsgHandled(TRUE);
275 OnSize(static_cast<uint32_t>(wParam), CSize(GET_X_LPARAM(lParam), GET_Y_LP ARAM(lParam)));
276 lResult = 0;
277 if(IsMsgHandled())
278 return TRUE;
279 }
280 END_MSG_MAP()
281 void SetOnDestroyed(const std::function<void()>& callback)
282 {
283 m_onDestroyedCallback = callback;
284 }
285 void SetOnLinkClicked(const std::function<void(const std::wstring& url)>& call back)
286 {
287 m_content.SetOnLinkClicked(callback);
288 }
289 private:
290 LRESULT OnCreate(const CREATESTRUCT* createStruct);
291 void OnSize(uint32_t wParam, CSize size);
292 LRESULT OnClick(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled);
293
294 void OnFinalMessage(HWND) override;
295
296 // returns {windowX, windowY} of top left corner on the monitor
297 POINT GetWindowCoordinates();
298 private:
299 // m_content is used as a holder of all children and we need it to have a bord er.
300 // It seems the most correct way to have a border to set WS_POPUPWINDOW style
301 // and paint the border in WM_NCPAINT but it simply does not work here.
302 NotificationWindow m_content;
303 std::function<void()> m_onDestroyedCallback;
304 };
305 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld