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.cpp | 72 ++++++++++++++++++++++++----------- 1 files changed, 49 insertions(+), 23 deletions(-) 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 -- Gitblit v1.9.1