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