Sine Striker
2023-12-02 499afac952920595e6c3d4f94806427f894c7674
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "win32windowcontext_p.h"
 
#include <QtCore/QHash>
 
namespace QWK {
 
    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;
        if (ctx->windowProc(hWnd, message, wParam, lParam, &result)) {
            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<HWND>(windowId);
        g_wndProcHash->remove(hWnd);
    }
 
    bool Win32WindowContext::setup() {
        auto winId = m_windowHandle->winId();
 
        // Install window hook
        auto hWnd = reinterpret_cast<HWND>(winId);
        auto qtWindowProc = reinterpret_cast<WNDPROC>(::GetWindowLongPtrW(hWnd, GWLP_WNDPROC));
        ::SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(QWK_WindowsWndProc));
 
        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
        // ...
 
        Q_UNUSED(windowId)
 
        return false; // Not handled
    }
 
}