| Index: src/engine/Main.cpp |
| diff --git a/src/engine/Main.cpp b/src/engine/Main.cpp |
| index 478b3f7181b5ec6ff7649561d87adb64ee2ca97f..59e84facfc7f8e4511e565c8dfe3674121545c6a 100644 |
| --- a/src/engine/Main.cpp |
| +++ b/src/engine/Main.cpp |
| @@ -15,6 +15,10 @@ |
| * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| +#pragma comment(linker,"\"/manifestdependency:type='win32' \ |
| + name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ |
| + processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") |
| + |
|
Oleksandr
2015/06/24 01:22:34
We have the same in PluginStdAfx.h. Maybe it makes
sergei
2015/06/24 17:31:35
I don't think it's time to unite them.
Even more,
|
| #include <AdblockPlus.h> |
| #include <functional> |
| #include <vector> |
| @@ -31,9 +35,14 @@ |
| #include "AdblockPlus.h" |
| #include "Debug.h" |
| #include "Updater.h" |
| +#include "NotificationWindow.h" |
| namespace |
| { |
| + class MyModule : public ATL::CAtlExeModuleT<MyModule> { |
| + public: |
| + } _AtlModule; |
| + |
| std::auto_ptr<AdblockPlus::FilterEngine> filterEngine; |
| std::auto_ptr<Updater> updater; |
| int activeConnections = 0; |
| @@ -456,7 +465,6 @@ namespace |
| updater->Update(params[0]->AsString()); |
| } |
| -} |
| std::auto_ptr<AdblockPlus::FilterEngine> CreateFilterEngine(const std::wstring& locale) |
| { |
| @@ -485,7 +493,132 @@ std::auto_ptr<AdblockPlus::FilterEngine> CreateFilterEngine(const std::wstring& |
| return filterEngine; |
| } |
| -int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) |
| +class ScopedTimer |
| +{ |
| +public: |
| + explicit ScopedTimer(HWND hwnd, UINT_PTR timerId, UINT elapse, TIMERPROC timerProc) |
| + : m_hwnd(hwnd), m_timerId(timerId) |
| + { |
| + m_timerId = SetTimer(m_hwnd, m_timerId, elapse, timerProc); |
| + } |
| + ~ScopedTimer() |
| + { |
| + Close(); |
| + } |
| + |
| + UINT_PTR GetID() |
| + { |
| + return m_timerId; |
| + } |
| + |
| + operator bool() const |
| + { |
| + return m_timerId != 0; |
| + } |
| + |
| + void Close() |
| + { |
| + if (m_timerId) |
| + { |
| + KillTimer(m_hwnd, m_timerId); |
| + m_timerId = 0; |
| + } |
| + } |
| +private: |
| + ScopedTimer(const ScopedTimer&); |
| + ScopedTimer& operator=(const ScopedTimer&); |
| +private: |
| + HWND m_hwnd; |
| + UINT_PTR m_timerId; |
| +}; |
| + |
| +struct ScopedAtlAxInitializer |
| +{ |
| + ScopedAtlAxInitializer() |
| + { |
| + ATL::AtlAxWinInit(); |
| + } |
| + ~ScopedAtlAxInitializer() |
| + { |
| + ATL::AtlAxWinTerm(); |
| + } |
| +}; |
| + |
| +void ApplicationMessageLoop(HINSTANCE hInstance) |
| +{ |
| + const std::wstring className = L"ABPEngineMessageWindow"; |
| + WNDCLASS wc; |
| + wc.style = 0; |
| + wc.lpfnWndProc = DefWindowProcW; |
| + wc.cbClsExtra = 0; |
| + wc.cbWndExtra = 0; |
| + wc.hInstance = hInstance; |
| + wc.hIcon = nullptr; |
| + wc.hCursor = nullptr; |
| + wc.hbrBackground = nullptr; |
| + wc.lpszMenuName = nullptr; |
| + wc.lpszClassName = className.c_str(); |
| + ATOM atom = RegisterClass(&wc); |
| + if (!atom) |
| + { |
| + DebugLastError("Cannot register class for message only window"); |
| + return; |
| + } |
| + HWND msgHWnd = CreateWindowW(className.c_str(), |
| + nullptr, // window name |
| + 0, // style |
| + 0, 0, 0, 0, // geometry (x, y, w, h) |
| + HWND_MESSAGE, // parent |
| + nullptr, // menu handle |
| + hInstance, |
| + 0); // windows creation data. |
| + if (!msgHWnd) |
| + { |
| + DebugLastError("Cannot create message only window"); |
| + return; |
| + } |
| + MSG msg = {}; |
| + ScopedTimer notificationTimer(msgHWnd, /*timer ID*/1, 3000/*msec*/, nullptr); |
| + std::unique_ptr<NotificationWindow> notificationWindow; |
| + while (GetMessage(&msg, /*hwnd*/nullptr, /*msgFilterMin*/0, /*msgFilterMax*/0)) |
| + { |
| + if (msg.hwnd == msgHWnd) |
| + { |
| + if (msg.message == WM_TIMER) |
| + { |
| + if (msg.wParam == notificationTimer.GetID()) |
| + { |
| + notificationTimer.Close(); |
| + auto notification = filterEngine->GetNextNotificationToShow(); |
| + if (notification) |
| + { |
| + notificationWindow.reset(new NotificationWindow(*notification, GetExeDir())); |
| + notificationWindow->destroyed = [¬ificationWindow] |
| + { |
| + notificationWindow.reset(); |
| + }; |
| + notificationWindow->linkClicked = [](const std::wstring& url) |
| + { |
| + ShellExecute(nullptr, L"open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL); |
|
Oleksandr
2015/06/24 01:22:34
This will open a default browser, not necessarily
sergei
2015/06/24 17:31:35
I was trying to launch internet explorer using CoC
|
| + }; |
| + notificationWindow->Create(/*parent window*/nullptr); |
| + if (notificationWindow->operator HWND() != nullptr) |
| + { |
| + notificationWindow->ShowWindow(SW_SHOWNOACTIVATE); |
| + notificationWindow->UpdateWindow(); |
| + } |
| + } |
| + } |
| + } |
| + } |
| + TranslateMessage(&msg); |
| + DispatchMessage(&msg); |
| + } |
| +} |
| + |
| +} // namespace { |
| + |
| +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int) |
| { |
| AutoHandle mutex(CreateMutexW(0, false, L"AdblockPlusEngine")); |
| if (!mutex) |
| @@ -508,32 +641,43 @@ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) |
| filterEngine = CreateFilterEngine(locale); |
| updater.reset(new Updater(filterEngine->GetJsEngine())); |
| - for (;;) |
| + std::thread communicationThread([] |
| { |
| - try |
| + for (;;) |
| { |
| - auto pipe = std::make_shared<Communication::Pipe>(Communication::pipeName, Communication::Pipe::MODE_CREATE); |
| - |
| - // TODO: we should wait for the finishing of the thread before exiting from this function. |
| - // It works now in most cases because the browser waits for the response in the pipe, and the |
| - // thread has time to finish while this response is being processed and the browser is |
| - // disposing all its stuff. |
| - std::thread([pipe]() |
| + try |
| { |
| - ClientThread(pipe.get()); |
| - }).detach(); |
| - } |
| - catch(const std::system_error& ex) |
| - { |
| - DebugException(ex); |
| - return 1; |
| - } |
| - catch (const std::runtime_error& e) |
| - { |
| - DebugException(e); |
| - return 1; |
| + auto pipe = std::make_shared<Communication::Pipe>(Communication::pipeName, Communication::Pipe::MODE_CREATE); |
| + |
| + // TODO: we should wait for the finishing of the thread before exiting from this function. |
| + // It works now in most cases because the browser waits for the response in the pipe, and the |
| + // thread has time to finish while this response is being processed and the browser is |
| + // disposing all its stuff. |
| + std::thread([pipe]() |
| + { |
| + ClientThread(pipe.get()); |
| + }).detach(); |
| + } |
| + catch(const std::system_error& ex) |
| + { |
| + DebugException(ex); |
| + return 1; |
| + } |
| + catch (const std::runtime_error& e) |
| + { |
| + DebugException(e); |
| + return 1; |
| + } |
| } |
| + }); |
| + |
| + ScopedAtlAxInitializer atlAxInit; |
| + ApplicationMessageLoop(hInstance); |
| + if (communicationThread.joinable()) |
| + { |
| + communicationThread.join(); |
| } |
| + |
| return 0; |
| } |