#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/input_method.hpp" #include "cru/win/native/window.hpp" #include "god_window_message.hpp" #include "timer.hpp" #include "window_manager.hpp" namespace cru::platform::native { std::unique_ptr CreateUiApplication() { return std::make_unique(); } } // namespace cru::platform::native namespace cru::platform::native::win { WinUiApplication* WinUiApplication::instance = nullptr; WinUiApplication::WinUiApplication() { instance = this; instance_handle_ = ::GetModuleHandleW(nullptr); if (!instance_handle_) throw Win32Error("Failed to get module(instance) handle."); 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(); input_method_manager_ = std::make_unique(this); } 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(std::function handler) { quit_handlers_.push_back(std::move(handler)); } void WinUiApplication::InvokeLater(std::function action) { // copy the action to a safe place auto p_action_copy = new std::function(std::move(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, std::function action) { return static_cast(timer_manager_->CreateTimer( static_cast(milliseconds.count()), false, std::move(action))); } unsigned long WinUiApplication::SetInterval( std::chrono::milliseconds milliseconds, std::function action) { return static_cast(timer_manager_->CreateTimer( static_cast(milliseconds.count()), true, std::move(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; } std::shared_ptr WinUiApplication::CreateWindow( INativeWindow* parent) { WinNativeWindow* p = nullptr; if (parent != nullptr) { p = CheckPlatform(parent, GetPlatformId()); } return (new WinNativeWindow(this, window_manager_->GetGeneralWindowClass(), WS_OVERLAPPEDWINDOW, p)) ->GetResolver(); } cru::platform::graph::IGraphFactory* WinUiApplication::GetGraphFactory() { return graph_factory_.get(); } ICursorManager* WinUiApplication::GetCursorManager() { return cursor_manager_.get(); } IInputMethodManager* WinUiApplication::GetInputMethodManager() { return input_method_manager_.get(); } } // namespace cru::platform::native::win