From 1a1f26d9e4ab6a4fe51baa78e40c4cdf3f402bcf Mon Sep 17 00:00:00 2001
From: Sine Striker <trueful@163.com>
Date: 周四, 07 12月 2023 14:27:00 +0800
Subject: [PATCH] Add context factory

---
 src/core/corewindowagent.cpp                |   17 +++--
 src/core/corewindowagent_p.h                |    2 
 src/core/contexts/abstractwindowcontext.cpp |   20 ++++++
 src/core/contexts/win32windowcontext_p.h    |    4 
 examples/mainwindow/CMakeLists.txt          |    4 +
 src/core/contexts/abstractwindowcontext_p.h |    4 
 src/core/contexts/qtwindowcontext.cpp       |    7 +-
 examples/mainwindow/mainwindow.cpp          |   23 -------
 src/core/contexts/qtwindowcontext_p.h       |    4 
 src/core/contexts/win32windowcontext.cpp    |   40 +------------
 10 files changed, 47 insertions(+), 78 deletions(-)

diff --git a/examples/mainwindow/CMakeLists.txt b/examples/mainwindow/CMakeLists.txt
index 1554a8a..af9c769 100644
--- a/examples/mainwindow/CMakeLists.txt
+++ b/examples/mainwindow/CMakeLists.txt
@@ -12,4 +12,6 @@
     SOURCES ${_src}
     QT_LINKS Core Gui Widgets
     LINKS QWKWidgets WidgetFrame
-)
\ No newline at end of file
+)
+
+qm_add_win_manifest(${PROJECT_NAME})
\ No newline at end of file
diff --git a/examples/mainwindow/mainwindow.cpp b/examples/mainwindow/mainwindow.cpp
index adcf6cd..ce3d742 100644
--- a/examples/mainwindow/mainwindow.cpp
+++ b/examples/mainwindow/mainwindow.cpp
@@ -53,42 +53,19 @@
         return menuBar;
     }();
 
-    static const auto buttonStyleSheet = QLatin1String{ R"(
-QPushButton {
-    background-color:white;
-    color:black;
-}
-QPushButton:hover {
-    background-color:black;
-    color:white;
-}
-QPushButton:pressed {
-    background-color:red;
-    color:white;
-}
-)" };
-
     auto iconButton = new QPushButton("I");
-    iconButton->setFlat(true);
     iconButton->setAttribute(Qt::WA_Hover);
     iconButton->setMouseTracking(true);
-    iconButton->setStyleSheet(buttonStyleSheet);
     auto minButton = new QPushButton("鈥�");
-    minButton->setFlat(true);
     minButton->setAttribute(Qt::WA_Hover);
     minButton->setMouseTracking(true);
-    minButton->setStyleSheet(buttonStyleSheet);
     auto maxButton = new QPushButton("馃棖");
     maxButton->setCheckable(true);
-    maxButton->setFlat(true);
     maxButton->setAttribute(Qt::WA_Hover);
     maxButton->setMouseTracking(true);
-    maxButton->setStyleSheet(buttonStyleSheet);
     auto closeButton = new QPushButton("鉁�");
-    closeButton->setFlat(true);
     closeButton->setAttribute(Qt::WA_Hover);
     closeButton->setMouseTracking(true);
-    closeButton->setStyleSheet(buttonStyleSheet);
 
     auto windowBar = new QWK::WindowBar();
     windowBar->setIconButton(iconButton);
diff --git a/src/core/contexts/abstractwindowcontext.cpp b/src/core/contexts/abstractwindowcontext.cpp
index 1c0e739..679a9ee 100644
--- a/src/core/contexts/abstractwindowcontext.cpp
+++ b/src/core/contexts/abstractwindowcontext.cpp
@@ -2,12 +2,28 @@
 
 namespace QWK {
 
-    AbstractWindowContext::AbstractWindowContext(QObject *host, WindowItemDelegate *delegate)
-        : m_host(host), m_delegate(delegate), m_windowHandle(delegate->hostWindow(host)) {
+    AbstractWindowContext::AbstractWindowContext()
+        : m_host(nullptr), m_delegate(nullptr), m_windowHandle(nullptr) {
     }
 
     AbstractWindowContext::~AbstractWindowContext() = default;
 
+    bool AbstractWindowContext::setup(QObject *host, WindowItemDelegate *delegate) {
+        if (!host || !delegate) {
+            return false;
+        }
+
+        auto windowHandle = delegate->hostWindow(host);
+        if (!windowHandle) {
+            return false;
+        }
+
+        m_host = host;
+        m_delegate.reset(delegate);
+        m_windowHandle = windowHandle;
+        return true;
+    }
+
     bool AbstractWindowContext::setHitTestVisible(const QObject *obj, bool visible) {
         Q_ASSERT(obj);
         if (!obj) {
diff --git a/src/core/contexts/abstractwindowcontext_p.h b/src/core/contexts/abstractwindowcontext_p.h
index b1202ea..a73f7c4 100644
--- a/src/core/contexts/abstractwindowcontext_p.h
+++ b/src/core/contexts/abstractwindowcontext_p.h
@@ -16,11 +16,11 @@
     class QWK_CORE_EXPORT AbstractWindowContext : public QObject {
         Q_OBJECT
     public:
-        AbstractWindowContext(QObject *host, WindowItemDelegate *delegate);
+        AbstractWindowContext();
         ~AbstractWindowContext() override;
 
     public:
-        virtual bool setup() = 0;
+        virtual bool setup(QObject *host, WindowItemDelegate *delegate);
 
         inline QObject *host() const;
         inline QWindow *window() const;
diff --git a/src/core/contexts/qtwindowcontext.cpp b/src/core/contexts/qtwindowcontext.cpp
index 732ecf1..4f4764e 100644
--- a/src/core/contexts/qtwindowcontext.cpp
+++ b/src/core/contexts/qtwindowcontext.cpp
@@ -40,15 +40,14 @@
 #endif
     }
 
-    QtWindowContext::QtWindowContext(QObject *host, WindowItemDelegate *delegate)
-        : AbstractWindowContext(host, delegate) {
+    QtWindowContext::QtWindowContext() : AbstractWindowContext() {
     }
 
     QtWindowContext::~QtWindowContext() {
     }
 
-    bool QtWindowContext::setup() {
-        if (!m_windowHandle) {
+    bool QtWindowContext::setup(QObject *host, WindowItemDelegate *delegate) {
+        if (!AbstractWindowContext::setup(host, delegate)) {
             return false;
         }
         return false;
diff --git a/src/core/contexts/qtwindowcontext_p.h b/src/core/contexts/qtwindowcontext_p.h
index 9a78813..242dcd2 100644
--- a/src/core/contexts/qtwindowcontext_p.h
+++ b/src/core/contexts/qtwindowcontext_p.h
@@ -8,11 +8,11 @@
     class QWK_CORE_EXPORT QtWindowContext : public AbstractWindowContext {
         Q_OBJECT
     public:
-        QtWindowContext(QObject *host, WindowItemDelegate *delegate);
+        QtWindowContext();
         ~QtWindowContext();
 
     public:
-        bool setup() override;
+        bool setup(QObject *host, WindowItemDelegate *delegate) override;
 
     protected:
         bool eventFilter(QObject *obj, QEvent *event) override;
diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp
index 4a99a18..538188d 100644
--- a/src/core/contexts/win32windowcontext.cpp
+++ b/src/core/contexts/win32windowcontext.cpp
@@ -188,22 +188,14 @@
     }
 
     static inline void triggerFrameChange(HWND hwnd) {
-        Q_ASSERT(hwnd);
-        if (!hwnd) {
-            return;
-        }
         ::SetWindowPos(hwnd, nullptr, 0, 0, 0, 0,
                        SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER |
                            SWP_FRAMECHANGED);
     }
 
     static inline quint32 getDpiForWindow(HWND hwnd) {
-        Q_ASSERT(hwnd);
-        if (!hwnd) {
-            return 0;
-        }
         const DynamicApis &apis = DynamicApis::instance();
-        if (apis.pGetDpiForWindow) { // Win10
+        if (apis.pGetDpiForWindow) {         // Win10
             return apis.pGetDpiForWindow(hwnd);
         } else if (apis.pGetDpiForMonitor) { // Win8.1
             HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
@@ -221,10 +213,6 @@
     }
 
     static inline quint32 getResizeBorderThickness(HWND hwnd) {
-        Q_ASSERT(hwnd);
-        if (!hwnd) {
-            return 0;
-        }
         const DynamicApis &apis = DynamicApis::instance();
         if (apis.pGetSystemMetricsForDpi) {
             const quint32 dpi = getDpiForWindow(hwnd);
@@ -236,10 +224,6 @@
     }
 
     static inline quint32 getTitleBarHeight(HWND hwnd) {
-        Q_ASSERT(hwnd);
-        if (!hwnd) {
-            return 0;
-        }
         const auto captionHeight = [hwnd]() -> int {
             const DynamicApis &apis = DynamicApis::instance();
             if (apis.pGetSystemMetricsForDpi) {
@@ -253,11 +237,6 @@
     }
 
     static inline void updateInternalWindowFrameMargins(HWND hwnd, QWindow *window) {
-        Q_ASSERT(hwnd);
-        Q_ASSERT(window);
-        if (!hwnd || !window) {
-            return;
-        }
         const auto margins = [hwnd]() -> QMargins {
             const int titleBarHeight = getTitleBarHeight(hwnd);
             if (isWin10OrGreater()) {
@@ -285,10 +264,6 @@
     }
 
     static inline MONITORINFOEXW getMonitorForWindow(HWND hwnd) {
-        Q_ASSERT(hwnd);
-        if (!hwnd) {
-            return {};
-        }
         // Use "MONITOR_DEFAULTTONEAREST" here so that we can still get the correct
         // monitor even if the window is minimized.
         HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
@@ -299,10 +274,6 @@
     };
 
     static inline void moveToDesktopCenter(HWND hwnd) {
-        Q_ASSERT(hwnd);
-        if (!hwnd) {
-            return;
-        }
         const auto monitorInfo = getMonitorForWindow(hwnd);
         RECT windowRect{};
         ::GetWindowRect(hwnd, &windowRect);
@@ -539,8 +510,7 @@
         return ::CallWindowProcW(g_qtWindowProc, hWnd, message, wParam, lParam);
     }
 
-    Win32WindowContext::Win32WindowContext(QObject *host, WindowItemDelegate *delegate)
-        : AbstractWindowContext(host, delegate) {
+    Win32WindowContext::Win32WindowContext() : AbstractWindowContext() {
     }
 
     Win32WindowContext::~Win32WindowContext() {
@@ -555,8 +525,8 @@
         }
     }
 
-    bool Win32WindowContext::setup() {
-        if (!m_windowHandle) {
+    bool Win32WindowContext::setup(QObject *host, WindowItemDelegate *delegate) {
+        if (!AbstractWindowContext::setup(host, delegate)) {
             return false;
         }
 
@@ -1294,8 +1264,6 @@
                                 break;
                             case CoreWindowAgent::Close:
                                 *result = HTCLOSE;
-                                break;
-                            case CoreWindowAgent::Unknown:
                                 break;
                             default:
                                 break; // unreachable
diff --git a/src/core/contexts/win32windowcontext_p.h b/src/core/contexts/win32windowcontext_p.h
index b8b8fea..0d7b14b 100644
--- a/src/core/contexts/win32windowcontext_p.h
+++ b/src/core/contexts/win32windowcontext_p.h
@@ -9,7 +9,7 @@
     class QWK_CORE_EXPORT Win32WindowContext : public AbstractWindowContext {
         Q_OBJECT
     public:
-        Win32WindowContext(QObject *host, WindowItemDelegate *delegate);
+        Win32WindowContext();
         ~Win32WindowContext() override;
 
         enum WindowPart {
@@ -22,7 +22,7 @@
         };
 
     public:
-        bool setup() override;
+        bool setup(QObject *host, WindowItemDelegate *delegate) override;
 
         bool windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
 
diff --git a/src/core/corewindowagent.cpp b/src/core/corewindowagent.cpp
index bea2239..d5dff5a 100644
--- a/src/core/corewindowagent.cpp
+++ b/src/core/corewindowagent.cpp
@@ -21,15 +21,20 @@
     void CoreWindowAgentPrivate::init() {
     }
 
-    bool CoreWindowAgentPrivate::setup(QObject *host, WindowItemDelegate *delegate) {
-        auto ctx =
+    AbstractWindowContext *CoreWindowAgentPrivate::createContext() const {
+        return
 #ifdef Q_OS_WINDOWS
-            std::make_unique<Win32WindowContext>(host, delegate)
+            new Win32WindowContext()
 #else
-            std::make_unique<QtWindowContext>(host, window, delegate)
+            new QtWindowContext()
 #endif
-            ;
-        if (!ctx->setup()) {
+                ;
+    }
+
+
+    bool CoreWindowAgentPrivate::setup(QObject *host, WindowItemDelegate *delegate) {
+        std::unique_ptr<AbstractWindowContext> ctx(createContext());
+        if (!ctx->setup(host, delegate)) {
             return false;
         }
         context = std::move(ctx);
diff --git a/src/core/corewindowagent_p.h b/src/core/corewindowagent_p.h
index faa61f8..7ff6825 100644
--- a/src/core/corewindowagent_p.h
+++ b/src/core/corewindowagent_p.h
@@ -16,6 +16,8 @@
 
         CoreWindowAgent *q_ptr; // no need to initialize
 
+        virtual AbstractWindowContext *createContext() const;
+
         bool setup(QObject *host, WindowItemDelegate *delegate);
 
         std::unique_ptr<AbstractWindowContext> context;

--
Gitblit v1.9.1