Left: | ||
Right: |
OLD | NEW |
---|---|
(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 }; | |
OLD | NEW |