| 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 |