aboutsummaryrefslogtreecommitdiff
path: root/CruUI/application.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CruUI/application.cpp')
-rw-r--r--CruUI/application.cpp66
1 files changed, 44 insertions, 22 deletions
diff --git a/CruUI/application.cpp b/CruUI/application.cpp
index 3ee7817d..c60bb043 100644
--- a/CruUI/application.cpp
+++ b/CruUI/application.cpp
@@ -1,10 +1,13 @@
#include "application.h"
+#include <fmt/format.h>
+
#include "timer.h"
#include "ui/window.h"
#include "graph/graph.h"
namespace cru {
+ constexpr auto god_window_class_name = L"GodWindowClass";
constexpr int invoke_later_message_id = WM_USER + 2000;
Application* Application::instance_ = nullptr;
@@ -21,6 +24,20 @@ namespace cru {
instance_ = this;
+ god_window_class_ = std::make_unique<ui::WindowClass>(god_window_class_name, GodWndProc, h_instance);
+
+ const auto hwnd = CreateWindowEx(0,
+ god_window_class_name,
+ L"", 0,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ nullptr, nullptr, h_instance, nullptr
+ );
+
+ if (hwnd == nullptr)
+ throw std::runtime_error("Failed to create window.");
+
+ god_hwnd_ = hwnd;
+
window_manager_ = std::make_unique<ui::WindowManager>();
graph_manager_ = std::make_unique<graph::GraphManager>();
timer_manager_ = std::make_unique<TimerManager>();
@@ -37,12 +54,8 @@ namespace cru {
while (GetMessage(&msg, nullptr, 0, 0))
{
- if (!HandleThreadMessage(msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
-
- }
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
}
return static_cast<int>(msg.wParam);
@@ -52,45 +65,54 @@ namespace cru {
::PostQuitMessage(quit_code);
}
- bool Application::HandleThreadMessage(const MSG& message)
+ LRESULT Application::GodWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
- if (message.hwnd != nullptr)
- return false;
+ const auto app = Application::GetInstance();
- switch (message.message)
+ if (app)
+ {
+ const auto result = app->HandleGodWindowMessage(hWnd, Msg, wParam, lParam);
+ if (result.has_value())
+ return result.value();
+ else
+ return DefWindowProc(hWnd, Msg, wParam, lParam);
+ }
+ else
+ return DefWindowProc(hWnd, Msg, wParam, lParam);
+ }
+
+ std::optional<LRESULT> Application::HandleGodWindowMessage(HWND hwnd, int msg, WPARAM w_param, LPARAM l_param)
+ {
+ switch (msg)
{
case invoke_later_message_id:
{
- const auto p_action = reinterpret_cast<InvokeLaterAction*>(message.wParam);
+ const auto p_action = reinterpret_cast<InvokeLaterAction*>(w_param);
(*p_action)();
delete p_action;
- return true;
+ return 0;
}
case WM_TIMER:
{
- const auto action = timer_manager_->GetAction(static_cast<UINT_PTR>(message.wParam));
+ const auto action = GetTimerManager()->GetAction(static_cast<UINT_PTR>(w_param));
if (action.has_value())
{
action.value()();
- return true;
+ return 0;
}
break;
}
default:
- return false;
+ return std::nullopt;
}
- return false;
+ return std::nullopt;
}
void InvokeLater(InvokeLaterAction&& action) {
//copy the action to a safe place
auto p_action_copy = new InvokeLaterAction(std::move(action));
- PostMessage(
- nullptr,
- invoke_later_message_id,
- reinterpret_cast<WPARAM>(p_action_copy),
- 0
- );
+ if (PostMessageW(Application::GetInstance()->GetGodWindowHandle(), invoke_later_message_id, reinterpret_cast<WPARAM>(p_action_copy), 0) == 0)
+ throw std::runtime_error(fmt::format("Last error: {}.", ::GetLastError()));
}
}