aboutsummaryrefslogtreecommitdiff
path: root/src/win/native
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2019-04-19 23:20:09 +0800
committercrupest <crupest@outlook.com>2019-04-19 23:20:09 +0800
commitea87825d58ab5b58dd360c3f080518c07a865db0 (patch)
tree4b497ef3687d682368e0fde4b86293565583a63a /src/win/native
parent7351020a582d70a1495249fba87d342c8a1fb634 (diff)
downloadcru-ea87825d58ab5b58dd360c3f080518c07a865db0.tar.gz
cru-ea87825d58ab5b58dd360c3f080518c07a865db0.tar.bz2
cru-ea87825d58ab5b58dd360c3f080518c07a865db0.zip
...
Diffstat (limited to 'src/win/native')
-rw-r--r--src/win/native/win_application.cpp33
-rw-r--r--src/win/native/win_native_window.cpp1
-rw-r--r--src/win/native/window_manager.cpp5
-rw-r--r--src/win/native/window_manager.hpp2
-rw-r--r--src/win/native/window_painter.cpp13
-rw-r--r--src/win/native/window_painter.hpp6
6 files changed, 44 insertions, 16 deletions
diff --git a/src/win/native/win_application.cpp b/src/win/native/win_application.cpp
index 72e12fa0..6c39453f 100644
--- a/src/win/native/win_application.cpp
+++ b/src/win/native/win_application.cpp
@@ -1,6 +1,7 @@
#include "cru/win/native/win_application.hpp"
#include "cru/win/exception.hpp"
+#include "cru/win/graph/graph_manager.hpp"
#include "cru/win/native/god_window.hpp"
#include "cru/win/native/win_native_window.hpp"
#include "god_window_message.hpp"
@@ -17,19 +18,22 @@ UiApplication* UiApplication::GetInstance() {
} // namespace cru::platform::native
namespace cru::win::native {
-WinApplication* WinApplication::instance_ = nullptr;
+WinApplication* WinApplication::instance = nullptr;
+
+namespace {
+bool application_constructing = false;
+}
WinApplication* WinApplication::GetInstance() {
- if (instance_ == nullptr)
- instance_ = new WinApplication(::GetModuleHandleW(nullptr));
- return instance_;
+ if (instance == nullptr && !application_constructing) {
+ application_constructing = true;
+ instance = new WinApplication(::GetModuleHandleW(nullptr));
+ }
+ return instance;
}
WinApplication::WinApplication(HINSTANCE h_instance) : h_instance_(h_instance) {
- if (instance_)
- throw std::runtime_error("A application instance already exists.");
-
- instance_ = this;
+ assert(instance == nullptr);
if (!::IsWindows8OrGreater())
throw std::runtime_error("Must run on Windows 8 or later.");
@@ -39,7 +43,8 @@ WinApplication::WinApplication(HINSTANCE h_instance) : h_instance_(h_instance) {
window_manager_ = std::make_shared<WindowManager>(this);
}
-WinApplication::~WinApplication() { instance_ = nullptr; }
+WinApplication::~WinApplication() {
+ instance = nullptr; }
int WinApplication::Run() {
MSG msg;
@@ -47,11 +52,21 @@ int WinApplication::Run() {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
+
+ for (const auto& handler : quit_handlers_) handler();
+
+ delete graph::GraphManager::GetInstance();
+ delete this;
+
return static_cast<int>(msg.wParam);
}
void WinApplication::Quit(const int quit_code) { ::PostQuitMessage(quit_code); }
+void WinApplication::AddOnQuitHandler(const std::function<void()>& handler) {
+ quit_handlers_.push_back(handler);
+}
+
void WinApplication::InvokeLater(const std::function<void()>& action) {
// copy the action to a safe place
auto p_action_copy = new std::function<void()>(action);
diff --git a/src/win/native/win_native_window.cpp b/src/win/native/win_native_window.cpp
index 0afad4e6..1d3b15ba 100644
--- a/src/win/native/win_native_window.cpp
+++ b/src/win/native/win_native_window.cpp
@@ -254,6 +254,7 @@ RECT WinNativeWindow::GetClientRectPixel() {
void WinNativeWindow::OnDestroyInternal() {
application_->GetWindowManager()->UnregisterWindow(hwnd_);
hwnd_ = nullptr;
+ destroy_event_.Raise();
if (delete_this_on_destroy_)
application_->InvokeLater([this] { delete this; });
}
diff --git a/src/win/native/window_manager.cpp b/src/win/native/window_manager.cpp
index a2fcdb54..5fea5a27 100644
--- a/src/win/native/window_manager.cpp
+++ b/src/win/native/window_manager.cpp
@@ -26,6 +26,11 @@ WindowManager::WindowManager(WinApplication* application) {
L"CruUIWindowClass", GeneralWndProc, application->GetInstanceHandle());
}
+WindowManager::~WindowManager() {
+ for (const auto [key, window] : window_map_)
+ delete window;
+}
+
void WindowManager::RegisterWindow(HWND hwnd, WinNativeWindow* window) {
assert(window_map_.count(hwnd) == 0); // The hwnd is already in the map.
window_map_.emplace(hwnd, window);
diff --git a/src/win/native/window_manager.hpp b/src/win/native/window_manager.hpp
index fa5bbe9d..8fab9cfc 100644
--- a/src/win/native/window_manager.hpp
+++ b/src/win/native/window_manager.hpp
@@ -19,7 +19,7 @@ class WindowManager : public Object {
WindowManager(WindowManager&& other) = delete;
WindowManager& operator=(const WindowManager& other) = delete;
WindowManager& operator=(WindowManager&& other) = delete;
- ~WindowManager() override = default;
+ ~WindowManager() override;
// Get the general window class for creating ordinary window.
std::shared_ptr<WindowClass> GetGeneralWindowClass() const {
diff --git a/src/win/native/window_painter.cpp b/src/win/native/window_painter.cpp
index 46364cdd..4e98a7fd 100644
--- a/src/win/native/window_painter.cpp
+++ b/src/win/native/window_painter.cpp
@@ -1,5 +1,6 @@
#include "window_painter.hpp"
+#include "cru/win/exception.hpp"
#include "cru/win/graph/graph_manager.hpp"
#include "cru/win/native/window_render_target.hpp"
@@ -7,7 +8,7 @@
namespace cru::win::native {
WindowPainter::WindowPainter(WinNativeWindow* window)
- : WinPainter(window->GetWindowRenderTarget()
+ : D2DPainter(window->GetWindowRenderTarget()
->GetGraphManager()
->GetD2D1DeviceContext()),
window_(window) {
@@ -18,7 +19,13 @@ WindowPainter::WindowPainter(WinNativeWindow* window)
->BeginDraw();
}
+WindowPainter::~WindowPainter() { EndDraw(); }
+
void WindowPainter::DoEndDraw() {
- WinPainter::DoEndDraw();
- window_->GetWindowRenderTarget()->Present(); }
+ ThrowIfFailed(window_->GetWindowRenderTarget()
+ ->GetGraphManager()
+ ->GetD2D1DeviceContext()
+ ->EndDraw());
+ window_->GetWindowRenderTarget()->Present();
+}
} // namespace cru::win::native
diff --git a/src/win/native/window_painter.hpp b/src/win/native/window_painter.hpp
index 0e6ab2cb..78c0717c 100644
--- a/src/win/native/window_painter.hpp
+++ b/src/win/native/window_painter.hpp
@@ -1,16 +1,16 @@
#pragma once
-#include "cru/win/graph/win_painter.hpp"
+#include "cru/win/graph/d2d_painter.hpp"
#include "cru/win/native/win_native_window.hpp"
namespace cru::win::native {
-class WindowPainter : public graph::WinPainter {
+class WindowPainter : public graph::D2DPainter {
public:
explicit WindowPainter(WinNativeWindow* window);
WindowPainter(const WindowPainter& other) = delete;
WindowPainter& operator=(const WindowPainter& other) = delete;
WindowPainter(WindowPainter&& other) = delete;
WindowPainter& operator=(WindowPainter&& other) = delete;
- ~WindowPainter() override = default;
+ ~WindowPainter() override;
protected:
void DoEndDraw() override;