From a18364bfff41687541b07c07a8c09637bacaa712 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 5 Jan 2019 23:34:46 +0100 Subject: [PATCH] Add settings window --- src/launcher/html/doc_host_ui_handler.cpp | 2 +- src/launcher/html/html_dispatch.cpp | 2 +- src/launcher/{ => html}/html_frame.cpp | 10 +- src/launcher/{ => html}/html_frame.hpp | 16 ++-- src/launcher/html/ole_client_site.cpp | 2 +- src/launcher/html/ole_in_place_frame.cpp | 2 +- src/launcher/html/ole_in_place_site.cpp | 2 +- src/launcher/html_window.cpp | 35 +++++++ src/launcher/html_window.hpp | 16 ++++ src/launcher/launcher.cpp | 49 +++++----- src/launcher/launcher.hpp | 10 +- src/launcher/window.cpp | 110 ++++++++++++++++++++-- src/launcher/window.hpp | 21 ++++- src/resource.hpp | 24 ++--- src/resource.rc | 4 +- src/resources/main.html | 28 +++++- src/resources/settings.html | 40 ++++++++ src/std_include.hpp | 1 + 18 files changed, 303 insertions(+), 71 deletions(-) rename src/launcher/{ => html}/html_frame.cpp (97%) rename src/launcher/{ => html}/html_frame.hpp (86%) create mode 100644 src/launcher/html_window.cpp create mode 100644 src/launcher/html_window.hpp create mode 100644 src/resources/settings.html diff --git a/src/launcher/html/doc_host_ui_handler.cpp b/src/launcher/html/doc_host_ui_handler.cpp index 6dbbce1..515bf1d 100644 --- a/src/launcher/html/doc_host_ui_handler.cpp +++ b/src/launcher/html/doc_host_ui_handler.cpp @@ -1,5 +1,5 @@ #include -#include "../html_frame.hpp" +#include "html_frame.hpp" doc_host_ui_handler::doc_host_ui_handler(html_frame* frame): frame_(frame) { diff --git a/src/launcher/html/html_dispatch.cpp b/src/launcher/html/html_dispatch.cpp index 7ca438f..29b3046 100644 --- a/src/launcher/html/html_dispatch.cpp +++ b/src/launcher/html/html_dispatch.cpp @@ -1,5 +1,5 @@ #include -#include "../html_frame.hpp" +#include "html_frame.hpp" html_dispatch::html_dispatch(html_frame* frame) : frame_(frame) { diff --git a/src/launcher/html_frame.cpp b/src/launcher/html/html_frame.cpp similarity index 97% rename from src/launcher/html_frame.cpp rename to src/launcher/html/html_frame.cpp index 60069cd..d3f53de 100644 --- a/src/launcher/html_frame.cpp +++ b/src/launcher/html/html_frame.cpp @@ -2,6 +2,8 @@ #include "html_frame.hpp" #include "utils/nt.hpp" +std::atomic html_frame::frame_count_ = 0; + html_frame::callback_params::callback_params(DISPPARAMS* params, VARIANT* res) : result(res) { for (auto i = params->cArgs; i > 0; --i) @@ -14,7 +16,7 @@ html_frame::callback_params::callback_params(DISPPARAMS* params, VARIANT* res) : html_frame::html_frame() : in_place_frame_(this), in_place_site_(this), ui_handler_(this), client_site_(this), html_dispatch_(this) { - if (OleInitialize(nullptr) != S_OK) + if (frame_count_++ == 0 && OleInitialize(nullptr) != S_OK) { throw std::runtime_error("Unable to initialize the OLE library"); } @@ -25,7 +27,11 @@ html_frame::html_frame() : in_place_frame_(this), in_place_site_(this), ui_handl html_frame::~html_frame() { - OleUninitialize(); + if (--frame_count_ <= 0) + { + frame_count_ = 0; + OleUninitialize(); + } } void html_frame::object_deleter(IUnknown* object) diff --git a/src/launcher/html_frame.hpp b/src/launcher/html/html_frame.hpp similarity index 86% rename from src/launcher/html_frame.hpp rename to src/launcher/html/html_frame.hpp index fcb2cc8..5fe7da2 100644 --- a/src/launcher/html_frame.hpp +++ b/src/launcher/html/html_frame.hpp @@ -1,12 +1,12 @@ #pragma once -#include "html/ole_in_place_frame.hpp" -#include "html/ole_in_place_site.hpp" -#include "html/doc_host_ui_handler.hpp" -#include "html/ole_client_site.hpp" -#include "html/html_dispatch.hpp" -#include "html/html_argument.hpp" +#include "ole_in_place_frame.hpp" +#include "ole_in_place_site.hpp" +#include "doc_host_ui_handler.hpp" +#include "ole_client_site.hpp" +#include "html_dispatch.hpp" +#include "html_argument.hpp" -class html_frame final +class html_frame { public: class callback_params final @@ -62,4 +62,6 @@ private: static void set_browser_feature(const std::string& feature, DWORD value); static void object_deleter(IUnknown* object); + + static std::atomic frame_count_; }; diff --git a/src/launcher/html/ole_client_site.cpp b/src/launcher/html/ole_client_site.cpp index 2bc2b11..6e3914e 100644 --- a/src/launcher/html/ole_client_site.cpp +++ b/src/launcher/html/ole_client_site.cpp @@ -1,5 +1,5 @@ #include -#include "../html_frame.hpp" +#include "html_frame.hpp" ole_client_site::ole_client_site(html_frame* frame): frame_(frame) { diff --git a/src/launcher/html/ole_in_place_frame.cpp b/src/launcher/html/ole_in_place_frame.cpp index b9612d5..172e5db 100644 --- a/src/launcher/html/ole_in_place_frame.cpp +++ b/src/launcher/html/ole_in_place_frame.cpp @@ -1,5 +1,5 @@ #include -#include "../html_frame.hpp" +#include "html_frame.hpp" ole_in_place_frame::ole_in_place_frame(html_frame* frame): frame_(frame) { diff --git a/src/launcher/html/ole_in_place_site.cpp b/src/launcher/html/ole_in_place_site.cpp index 0623eb2..d6cd3d8 100644 --- a/src/launcher/html/ole_in_place_site.cpp +++ b/src/launcher/html/ole_in_place_site.cpp @@ -1,5 +1,5 @@ #include -#include "../html_frame.hpp" +#include "html_frame.hpp" ole_in_place_site::ole_in_place_site(html_frame* frame) : frame_(frame) { diff --git a/src/launcher/html_window.cpp b/src/launcher/html_window.cpp new file mode 100644 index 0000000..39c871a --- /dev/null +++ b/src/launcher/html_window.cpp @@ -0,0 +1,35 @@ +#include +#include "html_window.hpp" + +html_window::html_window() +{ + this->set_callback(std::bind(&html_window::handler, this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); +} + +window* html_window::get_window() +{ + return this; +} + +html_frame* html_window::get_html_frame() +{ + return this; +} + +LRESULT html_window::handler(const UINT message, const WPARAM w_param, const LPARAM l_param) +{ + if (message == WM_SIZE) + { + this->resize(LOWORD(l_param), HIWORD(l_param)); + return 0; + } + + if (message == WM_CREATE) + { + this->initialize(*this); + return 0; + } + + return DefWindowProc(*this, message, w_param, l_param); +} diff --git a/src/launcher/html_window.hpp b/src/launcher/html_window.hpp new file mode 100644 index 0000000..14bacce --- /dev/null +++ b/src/launcher/html_window.hpp @@ -0,0 +1,16 @@ +#pragma once +#include "window.hpp" +#include "html/html_frame.hpp" + +class html_window final : public window, public html_frame +{ +public: + html_window(); + ~html_window() = default; + + window* get_window(); + html_frame* get_html_frame(); + +private: + LRESULT handler(const UINT message, const WPARAM w_param, const LPARAM l_param); +}; diff --git a/src/launcher/launcher.cpp b/src/launcher/launcher.cpp index 9338726..05027e5 100644 --- a/src/launcher/launcher.cpp +++ b/src/launcher/launcher.cpp @@ -1,14 +1,10 @@ #include #include "launcher.hpp" -#include "html_frame.hpp" #include "utils/nt.hpp" launcher::launcher() { - this->window_.set_callback(std::bind(&launcher::handler, this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - - this->html_frame_.register_callback("selectMode", [this](html_frame::callback_params* params) + this->main_window_.register_callback("selectMode", [this](html_frame::callback_params* params) { if(params->arguments.empty()) return; @@ -22,47 +18,44 @@ launcher::launcher() } }); - this->window_.create("Open-IW5", 615, 300); - this->html_frame_.load_html(load_content()); + this->main_window_.register_callback("showSettings", [this](html_frame::callback_params*) + { + this->settings_window_.show(); + }); + + this->settings_window_.set_hide_on_close(true); + this->settings_window_.create("Open-IW5 Settings", 615, 300); + this->settings_window_.load_html(load_content(MENU_SETTINGS)); + + this->main_window_.set_close_all_on_close(true); + this->main_window_.create("Open-IW5", 615, 300); + this->main_window_.load_html(load_content(MENU_MAIN)); + this->main_window_.show(); } launcher::mode launcher::run() const { - this->window_.run(); + window::run(); return this->mode_; } -LRESULT launcher::handler(const UINT message, const WPARAM w_param, const LPARAM l_param) -{ - if (message == WM_SIZE) - { - this->html_frame_.resize(LOWORD(l_param), HIWORD(l_param)); - return 0; - } - if (message == WM_CREATE) - { - this->html_frame_.initialize(this->window_); - return 0; - } - - return DefWindowProc(this->window_, message, w_param, l_param); -} void launcher::select_mode(const mode mode) { this->mode_ = mode; - this->window_.close(); + this->settings_window_.close(); + this->main_window_.close(); } -std::string launcher::load_content() +std::string launcher::load_content(int res) { - const auto res = FindResource(::utils::nt::module(), MAKEINTRESOURCE(MAIN_MENU), RT_RCDATA); + const auto resource = FindResource(::utils::nt::module(), MAKEINTRESOURCE(res), RT_RCDATA); if (!res) return {}; - const auto handle = LoadResource(nullptr, res); + const auto handle = LoadResource(nullptr, resource); if (!handle) return {}; - return std::string(LPSTR(LockResource(handle)), SizeofResource(nullptr, res)); + return std::string(LPSTR(LockResource(handle)), SizeofResource(nullptr, resource)); } diff --git a/src/launcher/launcher.hpp b/src/launcher/launcher.hpp index 9f3e880..d18dfc4 100644 --- a/src/launcher/launcher.hpp +++ b/src/launcher/launcher.hpp @@ -1,6 +1,5 @@ #pragma once -#include "window.hpp" -#include "html_frame.hpp" +#include "html_window.hpp" class launcher final { @@ -20,11 +19,10 @@ public: private: mode mode_ = none; - window window_; - html_frame html_frame_; + html_window main_window_; + html_window settings_window_; - LRESULT handler(const UINT message, const WPARAM w_param, const LPARAM l_param); void select_mode(mode mode); - static std::string load_content(); + static std::string load_content(int res); }; diff --git a/src/launcher/window.cpp b/src/launcher/window.cpp index 06af416..1abd3d5 100644 --- a/src/launcher/window.cpp +++ b/src/launcher/window.cpp @@ -1,6 +1,9 @@ #include #include "window.hpp" +std::mutex window::mutex_; +std::vector window::windows_; + window::window() { ZeroMemory(&this->wc_, sizeof(this->wc_)); @@ -21,11 +24,16 @@ window::window() void window::create(const std::string& title, const int width, const int height) { + { + std::lock_guard _(mutex_); + windows_.push_back(this); + } + const auto x = (GetSystemMetrics(SM_CXSCREEN) - width) / 2; const auto y = (GetSystemMetrics(SM_CYSCREEN) - height) / 2; this->handle_ = CreateWindowExA(NULL, this->wc_.lpszClassName, title.data(), - (WS_OVERLAPPEDWINDOW | WS_VISIBLE) & ~(WS_THICKFRAME | WS_MAXIMIZEBOX), x, y, width, + WS_OVERLAPPEDWINDOW & ~(WS_THICKFRAME | WS_MAXIMIZEBOX), x, y, width, height, nullptr, nullptr, this->wc_.hInstance, this); } @@ -33,7 +41,6 @@ window::~window() { this->close(); UnregisterClass(this->wc_.lpszClassName, this->wc_.hInstance); - DeleteObject(this->wc_.hbrBackground); } void window::close() @@ -44,18 +51,90 @@ void window::close() this->handle_ = nullptr; } -void window::run() const +void window::run() { MSG msg; while (GetMessage(&msg, nullptr, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); - - //if(!this->handle_) break; } } +void window::close_all() +{ + std::unique_lock lock(mutex_); + auto window_list = windows_; + lock.unlock(); + + const auto current_thread_id = GetCurrentThreadId(); + for (auto& window : window_list) + { + const auto thread_id = GetWindowThreadProcessId(*window, nullptr); + + if (thread_id == current_thread_id) + { + window->close(); + } + } +} + +void window::remove_window(const window* window) +{ + std::lock_guard _(mutex_); + + for (auto i = windows_.begin(); i != windows_.end(); ++i) + { + if (*i == window) + { + windows_.erase(i); + break; + } + } +} + +int window::get_window_count() +{ + std::lock_guard _(mutex_); + + auto count = 0; + const auto current_thread_id = GetCurrentThreadId(); + + for (const auto& window : windows_) + { + const auto thread_id = GetWindowThreadProcessId(*window, nullptr); + + if (thread_id == current_thread_id) + { + ++count; + } + } + + return count; +} + +void window::show() const +{ + ShowWindow(this->handle_, SW_SHOW); + UpdateWindow(this->handle_); +} + +void window::hide() const +{ + ShowWindow(this->handle_, SW_HIDE); + UpdateWindow(this->handle_); +} + +void window::set_hide_on_close(const bool value) +{ + this->hide_on_close_ = value; +} + +void window::set_close_all_on_close(const bool value) +{ + this->close_all_on_close_ = value; +} + void window::set_callback(const std::function& callback) { this->callback_ = callback; @@ -63,9 +142,28 @@ void window::set_callback(const std::function& ca LRESULT CALLBACK window::processor(const UINT message, const WPARAM w_param, const LPARAM l_param) const { + if (message == WM_CLOSE) + { + if (this->hide_on_close_) + { + this->hide(); + return TRUE; + } + else if (this->close_all_on_close_) + { + close_all(); + } + } + if (message == WM_DESTROY) { - PostQuitMessage(0); + remove_window(this); + + if (get_window_count() == 0) + { + PostQuitMessage(0); + } + return TRUE; } diff --git a/src/launcher/window.hpp b/src/launcher/window.hpp index 3bbc1d2..22f3a4f 100644 --- a/src/launcher/window.hpp +++ b/src/launcher/window.hpp @@ -2,7 +2,7 @@ #define WM_KILL_WINDOW (WM_USER+0) -class window final +class window { public: window(); @@ -11,13 +11,24 @@ public: void create(const std::string& title, int width, int height); void close(); - void run() const; + + void show() const; + void hide() const; + + void set_hide_on_close(bool value); + void set_close_all_on_close(bool value); void set_callback(const std::function& callback); operator HWND() const; + static void run(); + static void close_all(); + private: + bool hide_on_close_ = false; + bool close_all_on_close_ = false; + WNDCLASSEX wc_{}; HWND handle_ = nullptr; std::string classname_; @@ -25,4 +36,10 @@ private: LRESULT CALLBACK processor(UINT message, WPARAM w_param, LPARAM l_param) const; static LRESULT CALLBACK static_processor(HWND hwnd, UINT message, WPARAM w_param, LPARAM l_param); + + static std::mutex mutex_; + static std::vector windows_; + + static void remove_window(const window* window); + static int get_window_count(); }; diff --git a/src/resource.hpp b/src/resource.hpp index 48a8b97..9f35f65 100644 --- a/src/resource.hpp +++ b/src/resource.hpp @@ -1,14 +1,16 @@ #pragma once -#define MAIN_MENU 300 -#define BINARY_SP 301 -#define BINARY_MP 302 +#define BINARY_SP 300 +#define BINARY_MP 301 -#define DW_HEATMAP 303 -#define DW_MOTD 304 -#define DW_IMG 305 -#define DW_WAD 306 -#define DW_PLAYLIST 307 -#define DW_CONFIG 308 -#define DW_IOTD_TXT 309 -#define DW_IOTD_IMG 310 +#define DW_HEATMAP 302 +#define DW_MOTD 303 +#define DW_IMG 304 +#define DW_WAD 305 +#define DW_PLAYLIST 306 +#define DW_CONFIG 307 +#define DW_IOTD_TXT 308 +#define DW_IOTD_IMG 309 + +#define MENU_MAIN 310 +#define MENU_SETTINGS 311 diff --git a/src/resource.rc b/src/resource.rc index dd37b6c..72a3912 100644 --- a/src/resource.rc +++ b/src/resource.rc @@ -84,7 +84,6 @@ END 102 ICON "resources/icon.ico" -MAIN_MENU RCDATA "resources/main.html" BINARY_SP RCDATA "resources/iw5sp.exe.diff" BINARY_MP RCDATA "resources/iw5mp.exe.diff" @@ -97,6 +96,9 @@ DW_CONFIG RCDATA "resources/dw/social_tu1.cfg" DW_IOTD_TXT RCDATA "resources/dw/iotd-english.txt" DW_IOTD_IMG RCDATA "resources/dw/iotd-english.jpg" +MENU_MAIN RCDATA "resources/main.html" +MENU_SETTINGS RCDATA "resources/settings.html" + #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/resources/main.html b/src/resources/main.html index 856e31b..ab5236a 100644 --- a/src/resources/main.html +++ b/src/resources/main.html @@ -46,14 +46,14 @@ .button>img { width: 120px; height: 120px; - border-radius: 10px; - transition: all 0.1s ease-out; + border-radius: 7px; + transition: all 0.08s ease-out; cursor: pointer; box-shadow: 0px 2px 40px 10px rgba(0, 0, 0, 0.3); } .button>img:hover { - box-shadow: 0px 2px 40px 10px rgba(0, 0, 0, 0); + box-shadow: 0px 1px 5px 2px rgba(0, 0, 0, 0.1); } .button:first-of-type { @@ -70,6 +70,21 @@ margin: auto; display: table; } + + #settings { + position: fixed; + right: 3px; + top: 3px; + width: 25px; + height: 25px; + cursor:pointer; + opacity: 0.1; + transition: all 0.08s ease-out; + } + + #settings:hover { + opacity: 0.4; + } @@ -88,6 +103,8 @@ + + diff --git a/src/resources/settings.html b/src/resources/settings.html new file mode 100644 index 0000000..f5049b9 --- /dev/null +++ b/src/resources/settings.html @@ -0,0 +1,40 @@ + + + + + + + Open-IW5 Settings + + + + + +
+ +
+ + + \ No newline at end of file diff --git a/src/std_include.hpp b/src/std_include.hpp index c2373fb..8522f97 100644 --- a/src/std_include.hpp +++ b/src/std_include.hpp @@ -27,6 +27,7 @@ #endif #include +#include #include #include #include