From 5f75c4f4f6736ff8efa87beab715fd9a044f666c Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 12 Sep 2018 23:09:13 +0800 Subject: ... Never use PostMessage with hwnd as null!!!!!!!!!!!!!!!!!!!!!!!! --- CruUI/application.cpp | 66 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 22 deletions(-) (limited to 'CruUI/application.cpp') 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 + #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(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(); graph_manager_ = std::make_unique(); timer_manager_ = std::make_unique(); @@ -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(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 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(message.wParam); + const auto p_action = reinterpret_cast(w_param); (*p_action)(); delete p_action; - return true; + return 0; } case WM_TIMER: { - const auto action = timer_manager_->GetAction(static_cast(message.wParam)); + const auto action = GetTimerManager()->GetAction(static_cast(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(p_action_copy), - 0 - ); + if (PostMessageW(Application::GetInstance()->GetGodWindowHandle(), invoke_later_message_id, reinterpret_cast(p_action_copy), 0) == 0) + throw std::runtime_error(fmt::format("Last error: {}.", ::GetLastError())); } } -- cgit v1.2.3