Index: src/engine/NotificationWindow.h |
diff --git a/src/engine/NotificationWindow.h b/src/engine/NotificationWindow.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c8501f371bbfe62beb93e4cf0f3a9e5a09ca8bbd |
--- /dev/null |
+++ b/src/engine/NotificationWindow.h |
@@ -0,0 +1,234 @@ |
+#pragma once |
+#include <atlbase.h> |
+#include <atlwin.h> |
+#include <atlctl.h> |
+#include <atlimage.h> |
+#include <AdblockPlus/JsValue.h> |
+#include <AdblockPlus/Notification.h> |
+#include <functional> |
+#include <MsHtmdid.h> |
+ |
+class IconStaticControl : public ATL::CWindow |
+{ |
+public: |
+ explicit IconStaticControl(HWND hWnd = nullptr) : ATL::CWindow(hWnd) |
+ { } |
+ |
+ IconStaticControl& operator=(HWND hWnd) |
+ { |
+ m_hWnd = hWnd; |
+ return *this; |
+ } |
+ |
+ HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL, |
+ DWORD dwStyle = 0, DWORD dwExStyle = 0, |
+ ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL) |
Oleksandr
2015/06/24 01:22:34
nullptr instead of NULL, for consistency? Also 2 l
sergei
2015/06/25 13:19:18
Done.
|
+ { |
+ return ATL::CWindow::Create(GetWndClassName(), hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, MenuOrID.m_hMenu, lpCreateParam); |
+ } |
+ |
+ static wchar_t* GetWndClassName() |
+ { |
+ return L"STATIC"; |
+ } |
+ |
+ void SetBitmap(HBITMAP hBitmap) |
+ { |
+ ATLASSERT(::IsWindow(m_hWnd)); |
+ ::SendMessage(m_hWnd, STM_SETIMAGE, IMAGE_BITMAP, reinterpret_cast<LPARAM>(hBitmap)); |
+ } |
+}; |
+ |
+template<typename T> |
+class ScopedObjectHandle |
+{ |
+public: |
+ explicit ScopedObjectHandle(T handle = nullptr) : m_handle(handle) |
+ { } |
+ |
+ ~ScopedObjectHandle() |
+ { |
+ if(m_handle != nullptr) |
+ { |
+ ::DeleteObject(m_handle); |
+ m_handle = nullptr; |
+ } |
+ } |
+ |
+ ScopedObjectHandle& operator=(T handle) |
+ { |
+ if(m_handle != nullptr && m_handle != handle) |
+ ::DeleteObject(m_handle); |
+ m_handle = handle; |
+ return *this; |
+ } |
+ |
+ T Detach() |
+ { |
+ T retValue = m_handle; |
+ m_handle = nullptr; |
+ return retValue; |
+ } |
+ |
+ operator T() |
+ { |
+ return m_handle; |
+ } |
+ |
+ operator bool() const |
+ { |
+ return m_handle == nullptr; |
+ } |
+protected: |
+ T m_handle; |
+private: |
+ ScopedObjectHandle(const ScopedObjectHandle&); |
+ ScopedObjectHandle& operator=(const ScopedObjectHandle&); |
+}; |
+ |
+class CFont : public ScopedObjectHandle<HFONT> |
+{ |
+public: |
+ explicit CFont(HFONT hFont = nullptr) : ScopedObjectHandle(hFont) |
+ { |
+ } |
+ |
+ void CreateFontIndirect(const LOGFONT* logFontArg, uint32_t dpi) |
+ { |
+ ATLASSERT(m_handle == nullptr); |
+ LOGFONT logFont = *logFontArg; |
+ logFont.lfHeight = -MulDiv(dpi, logFont.lfHeight, 72); |
+ m_handle = ::CreateFontIndirect(&logFont); |
+ } |
+}; |
+ |
+class CBrush : public ScopedObjectHandle<HBRUSH> |
+{ |
+public: |
+ explicit CBrush(HBRUSH brush = nullptr) : ScopedObjectHandle(brush) |
+ { |
+ } |
+ |
+ void CreateSolidBrush(COLORREF crColor) |
+ { |
+ ATLASSERT(m_handle == nullptr); |
+ m_handle = ::CreateSolidBrush(crColor); |
+ } |
+}; |
+ |
+class ScopedModule |
+{ |
+public: |
+ ScopedModule() |
+ : m_hModule(nullptr) |
+ { |
+ } |
+ |
+ bool Open(const wchar_t* fileName, int flags) |
+ { |
+ m_hModule = LoadLibraryEx(fileName, nullptr, flags); |
+ return m_hModule != nullptr; |
+ } |
+ |
+ ~ScopedModule() |
+ { |
+ if (m_hModule != nullptr) |
+ { |
+ FreeLibrary(m_hModule); |
+ m_hModule = nullptr; |
+ } |
+ } |
+ operator HMODULE() |
+ { |
+ return m_hModule; |
+ } |
+private: |
+ ScopedModule(const ScopedModule&); |
+ ScopedModule& operator=(const ScopedModule&); |
+private: |
+ HMODULE m_hModule; |
+}; |
+ |
+typedef ATL::CWinTraits<WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_TOOLWINDOW | WS_EX_TOPMOST> NotificationWindowStyles; |
+enum |
+{ |
+ // ID of HTMLDocument ActiveX control, it's used for event binding. |
+ kHTMLDocumentCtrlID = 101 |
+}; |
+ |
+class NotificationWindow : public ATL::CWindowImpl<NotificationWindow, ATL::CWindow, NotificationWindowStyles> |
+ , ATL::IDispEventImpl<kHTMLDocumentCtrlID, NotificationWindow, &DIID_HTMLDocumentEvents2, &LIBID_MSHTML, 4, 0> |
+{ |
+public: |
+ explicit NotificationWindow(const AdblockPlus::Notification& notification, const std::wstring& htmlFileDir); |
+ ~NotificationWindow(); |
+ BEGIN_MSG_MAP(NotificationWindow) |
+ if (uMsg == WM_CREATE) |
+ { |
+ SetMsgHandled(TRUE); |
+ lResult = OnCreate(reinterpret_cast<CREATESTRUCT*>(lParam)); |
+ if(IsMsgHandled()) |
+ return TRUE; |
+ } |
+ MESSAGE_HANDLER(WM_LBUTTONUP, OnClick) |
+ MESSAGE_HANDLER(WM_RBUTTONUP, OnClick) |
+ MESSAGE_HANDLER(WM_CTLCOLORSTATIC, OnCtlColor) |
+ if (uMsg == WM_SIZE) |
+ { |
+ SetMsgHandled(TRUE); |
+ OnSize(static_cast<uint32_t>(wParam), CSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); |
+ lResult = 0; |
+ if(IsMsgHandled()) |
+ return TRUE; |
+ } |
+ if (uMsg == WM_DESTROY) |
+ { |
+ SetMsgHandled(TRUE); |
+ OnDestroy(); |
+ lResult = 0; |
+ if(IsMsgHandled()) |
+ return TRUE; |
+ } |
+ END_MSG_MAP() |
+ |
+ BEGIN_SINK_MAP(NotificationWindow) |
+ SINK_ENTRY_EX(kHTMLDocumentCtrlID, DIID_HTMLDocumentEvents2, DISPID_HTMLDOCUMENTEVENTS2_ONCLICK, OnHTMLDocumentClick) |
+ SINK_ENTRY_EX(kHTMLDocumentCtrlID, DIID_HTMLDocumentEvents2, DISPID_HTMLDOCUMENTEVENTS2_ONSELECTSTART, OnHTMLDocumentSelectStart) |
+ END_SINK_MAP() |
+ |
+ std::function<void()> destroyed; |
+ std::function<void(const std::wstring& url)> linkClicked; |
+private: |
+ LRESULT OnCreate(const CREATESTRUCT* createStruct); |
+ LRESULT OnCtlColor(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled); |
+ LRESULT OnClick(UINT msg, WPARAM wParam, LPARAM lParam, BOOL& handled); |
+ void OnGetMinMaxInfo(MINMAXINFO* minMaxInfo); |
+ void OnSize(uint32_t wParam, CSize size); |
+ void OnDestroy(); |
+ |
+ void __stdcall OnHTMLDocumentClick(IHTMLEventObj* pEvtObj); |
+ void __stdcall OnHTMLDocumentSelectStart(IHTMLEventObj* pEvtObj); |
+ |
+ void OnFinalMessage(HWND) override; |
+ void LoadABPIcon(); |
+ // returns {windowX, windowY} of top left corner on the monitor |
+ POINT GetWindowCoordinates(); |
+ |
+ uint32_t DPIAware(uint32_t value) const { |
+ return MulDiv(value, m_dpi, 96); |
+ } |
+ SIZE DPIAware(SIZE value) const { |
+ return CSize(DPIAware(value.cx), DPIAware(value.cy)); |
+ } |
+ RECT DPIAware(RECT value) const { |
+ return CRect(DPIAware(value.left), DPIAware(value.top), DPIAware(value.right), DPIAware(value.bottom)); |
+ } |
+private: |
+ uint32_t m_dpi; |
+ std::wstring m_htmlPage; |
+ CBrush m_bgColor; |
+ ATL::CAxWindow m_axIE; |
+ ATL::CImage m_iconImg; |
+ IconStaticControl m_icon; |
+ std::vector<std::wstring> m_links; |
+}; |