#include "cru/win/native/ui_application.hpp" #include "../debug_logger.hpp" #include "cru/common/logger.hpp" #include "cru/platform/check.hpp" #include "cru/win/graph/direct/factory.hpp" #include "cru/win/native/cursor.hpp" #include "cru/win/native/exception.hpp" #include "cru/win/native/god_window.hpp" #include "cru/win/native/window.hpp" #include "god_window_message.hpp" #include "timer.hpp" #include "window_manager.hpp" #include namespace cru::platform::native::win { WinUiApplication* WinUiApplication::instance = nullptr; WinUiApplication::WinUiApplication() { if (instance) { throw new std::runtime_error( "Already created an instance of WinUiApplication"); } instance = this; log::Logger::GetInstance()->AddSource( std::make_unique<::cru::platform::win::WinDebugLoggerSource>()); graph_factory_ = std::make_unique(); god_window_ = std::make_unique(this); timer_manager_ = std::make_unique(god_window_.get()); window_manager_ = std::make_unique(this); cursor_manager_ = std::make_unique(); } WinUiApplication::~WinUiApplication() { instance = nullptr; } int WinUiApplication::Run() { MSG msg; while (GetMessageW(&msg, nullptr, 0, 0)) { TranslateMessage(&msg); DispatchMessageW(&msg); } for (const auto& handler : quit_handlers_) handler(); return static_cast(msg.wParam); } void WinUiApplication::RequestQuit(const int quit_code) { ::PostQuitMessage(quit_code); } void WinUiApplication::AddOnQuitHandler(const std::function& handler) { quit_handlers_.push_back(handler); } void WinUiApplication::InvokeLater(const std::function& action) { // copy the action to a safe place auto p_action_copy = new std::function(action); if (::PostMessageW(GetGodWindow()->GetHandle(), invoke_later_message_id, reinterpret_cast(p_action_copy), 0) == 0) throw Win32Error(::GetLastError(), "InvokeLater failed to post message."); } unsigned long WinUiApplication::SetTimeout( std::chrono::milliseconds milliseconds, const std::function& action) { return static_cast(timer_manager_->CreateTimer( static_cast(milliseconds.count()), false, action)); } unsigned long WinUiApplication::SetInterval( std::chrono::milliseconds milliseconds, const std::function& action) { return static_cast(timer_manager_->CreateTimer( static_cast(milliseconds.count()), true, action)); } void WinUiApplication::CancelTimer(unsigned long id) { timer_manager_->KillTimer(static_cast(id)); } std::vector WinUiApplication::GetAllWindow() { const auto&& windows = window_manager_->GetAllWindows(); std::vector result; for (const auto w : windows) { result.push_back(static_cast(w)); } return result; } INativeWindow* WinUiApplication::CreateWindow(INativeWindow* parent) { WinNativeWindow* p = nullptr; if (parent != nullptr) { p = CheckPlatform(parent, GetPlatformId()); } return new WinNativeWindow(this, window_manager_->GetGeneralWindowClass(), WS_OVERLAPPEDWINDOW, p); } cru::platform::graph::IGraphFactory* WinUiApplication::GetGraphFactory() { return graph_factory_.get(); } ICursorManager* WinUiApplication::GetCursorManager() { return cursor_manager_.get(); } } // namespace cru::platform::native::win