From 91af9c894c8c23f42da32fc96cf2d8b5db401df6 Mon Sep 17 00:00:00 2001
From: Sine Striker <trueful@163.com>
Date: 周六, 02 12月 2023 14:07:00 +0800
Subject: [PATCH] Win32Context: Optimize

---
 src/core/contexts/win32windowcontext_p.h |    5 +-
 qmsetup                                  |    2 
 src/quick/CMakeLists.txt                 |    4 +-
 src/CMakeLists.txt                       |    1 
 src/core/contexts/win32windowcontext.cpp |   72 ++++++++++++++++++++++++-----------
 5 files changed, 55 insertions(+), 29 deletions(-)

diff --git a/qmsetup b/qmsetup
index f1c0099..d5d9a3e 160000
--- a/qmsetup
+++ b/qmsetup
@@ -1 +1 @@
-Subproject commit f1c00991ef5a360ec2148dd125a8bb7c4d8a16a1
+Subproject commit d5d9a3efa97633cd275a133d924ea998ea708f7a
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index eb6be77..52c5b95 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -69,6 +69,7 @@
 
     # Add include directories
     target_include_directories(${_target} PRIVATE ${QWINDOWKIT_BUILD_INCLUDE_DIR})
+    target_include_directories(${_target} PRIVATE .)
 
     # Library name
     if(${_target} MATCHES "^QWK(.+)")
diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp
index a5dd7f7..ab32ed0 100644
--- a/src/core/contexts/win32windowcontext.cpp
+++ b/src/core/contexts/win32windowcontext.cpp
@@ -4,14 +4,41 @@
 
 namespace QWK {
 
-    using WndProcHash = QHash<HWND, Win32WindowContext *>;
+    using WndProcHash = QHash<HWND, Win32WindowContext *>; // hWnd -> context
     Q_GLOBAL_STATIC(WndProcHash, g_wndProcHash);
 
+    static WNDPROC g_qtWindowProc = nullptr; // Original Qt window proc function
+
+    extern "C" LRESULT QT_WIN_CALLBACK QWK_WindowsWndProc(HWND hWnd, UINT message, WPARAM wParam,
+                                                          LPARAM lParam) {
+        Q_ASSERT(hWnd);
+        if (!hWnd) {
+            return FALSE;
+        }
+
+        // Search window context
+        auto ctx = g_wndProcHash->value(hWnd);
+        if (!ctx) {
+            return ::DefWindowProcW(hWnd, message, wParam, lParam);
+        }
+
+        // Try hooked procedure
+        LRESULT result;
+        bool handled = ctx->windowProc(hWnd, message, wParam, lParam, &result);
+        if (handled) {
+            return result;
+        }
+
+        // Fallback to Qt's procedure
+        return ::CallWindowProcW(g_qtWindowProc, hWnd, message, wParam, lParam);
+    }
+
     Win32WindowContext::Win32WindowContext(QWindow *window, WindowItemDelegate *delegate)
-        : AbstractWindowContext(window, delegate), windowId(0), qtWindowProc(nullptr) {
+        : AbstractWindowContext(window, delegate), windowId(0) {
     }
 
     Win32WindowContext::~Win32WindowContext() {
+        // Remove window handle mapping
         auto hWnd = reinterpret_cast<HWND>(windowId);
         g_wndProcHash->remove(hWnd);
     }
@@ -25,41 +52,40 @@
 
         // Install window hook
         auto hWnd = reinterpret_cast<HWND>(winId);
-        auto orgWndProc = reinterpret_cast<WNDPROC>(::GetWindowLongPtrW(hWnd, GWLP_WNDPROC));
-        Q_ASSERT(orgWndProc);
-        if (!orgWndProc) {
+        auto qtWindowProc = reinterpret_cast<WNDPROC>(::GetWindowLongPtrW(hWnd, GWLP_WNDPROC));
+        Q_ASSERT(qtWindowProc);
+        if (!qtWindowProc) {
             QWK_WARNING << winLastErrorMessage();
             return false;
         }
 
-        if (::SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(windowProc)) == 0) {
+        if (::SetWindowLongPtrW(hWnd, GWLP_WNDPROC,
+                                reinterpret_cast<LONG_PTR>(QWK_WindowsWndProc)) == 0) {
             QWK_WARNING << winLastErrorMessage();
             return false;
         }
 
         windowId = winId;
-        qtWindowProc = orgWndProc;         // Store original window proc
-        g_wndProcHash->insert(hWnd, this); // Save window handle mapping
+
+        // Store original window proc
+        if (!g_qtWindowProc) {
+            g_qtWindowProc = qtWindowProc;
+        }
+
+        // Save window handle mapping
+        g_wndProcHash->insert(hWnd, this);
+
         return true;
     }
 
-    LRESULT Win32WindowContext::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
-        Q_ASSERT(hWnd);
-        if (!hWnd) {
-            return FALSE;
-        }
+    bool Win32WindowContext::windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam,
+                                        LRESULT *result) {
+        *result = FALSE;
 
-        const auto *ctx = g_wndProcHash->value(hWnd);
-        if (!ctx) {
-            return ::DefWindowProcW(hWnd, uMsg, wParam, lParam);
-        }
+        // TODO: Implement
+        // ...
 
-        auto winId = reinterpret_cast<WId>(hWnd);
-
-        // Further procedure
-        Q_UNUSED(winId)
-
-        return ::CallWindowProcW(ctx->qtWindowProc, hWnd, uMsg, wParam, lParam);
+        return false; // Not handled
     }
 
 }
\ No newline at end of file
diff --git a/src/core/contexts/win32windowcontext_p.h b/src/core/contexts/win32windowcontext_p.h
index f1ab71e..85ecf59 100644
--- a/src/core/contexts/win32windowcontext_p.h
+++ b/src/core/contexts/win32windowcontext_p.h
@@ -15,11 +15,10 @@
     public:
         bool setup() override;
 
+        bool windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
+
     protected:
         WId windowId;
-        WNDPROC qtWindowProc; // Original Qt window proc function
-
-        static LRESULT windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
     };
 
 }
diff --git a/src/quick/CMakeLists.txt b/src/quick/CMakeLists.txt
index bfdcc12..f5feb3e 100644
--- a/src/quick/CMakeLists.txt
+++ b/src/quick/CMakeLists.txt
@@ -15,8 +15,8 @@
 qwk_add_library(${PROJECT_NAME} AUTOGEN
     SOURCES ${_src}
     LINKS QWKCore
-    QT_LINKS Core Quick
-    QT_INCLUDE_PRIVATE Core Quick
+    QT_LINKS Core Gui Quick
+    QT_INCLUDE_PRIVATE Core Gui Quick
     PREFIX QWK_QUICK
 )
 

--
Gitblit v1.9.1