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

Powered by Google App Engine
This is Rietveld