diff options
author | crupest <crupest@outlook.com> | 2018-09-12 23:09:13 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2018-09-12 23:09:13 +0800 |
commit | 5f75c4f4f6736ff8efa87beab715fd9a044f666c (patch) | |
tree | a67dd8d9f6af0ff7b93776c1e3bcc2816a2250dd /CruUI/application.cpp | |
parent | e2dab3893a8be43de0e50587c85df9e11abf87fe (diff) | |
download | cru-5f75c4f4f6736ff8efa87beab715fd9a044f666c.tar.gz cru-5f75c4f4f6736ff8efa87beab715fd9a044f666c.tar.bz2 cru-5f75c4f4f6736ff8efa87beab715fd9a044f666c.zip |
...
Never use PostMessage with hwnd as null!!!!!!!!!!!!!!!!!!!!!!!!
Diffstat (limited to 'CruUI/application.cpp')
-rw-r--r-- | CruUI/application.cpp | 66 |
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())); } } |