#include "win32windowcontext_p.h" #include namespace QWK { using WndProcHash = QHash; // 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) { } Win32WindowContext::~Win32WindowContext() { // Remove window handle mapping auto hWnd = reinterpret_cast(windowId); g_wndProcHash->remove(hWnd); } bool Win32WindowContext::setup() { auto winId = m_windowHandle->winId(); Q_ASSERT(winId); if (!winId) { return false; } // Install window hook auto hWnd = reinterpret_cast(winId); auto qtWindowProc = reinterpret_cast(::GetWindowLongPtrW(hWnd, GWLP_WNDPROC)); Q_ASSERT(qtWindowProc); if (!qtWindowProc) { QWK_WARNING << winLastErrorMessage(); return false; } if (::SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast(QWK_WindowsWndProc)) == 0) { QWK_WARNING << winLastErrorMessage(); return false; } windowId = winId; // Store original window proc if (!g_qtWindowProc) { g_qtWindowProc = qtWindowProc; } // Save window handle mapping g_wndProcHash->insert(hWnd, this); return true; } bool Win32WindowContext::windowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result) { *result = FALSE; // TODO: Implement // ... return false; // Not handled } }