Add windows implementations
12个文件已修改
7个文件已添加
4 文件已重命名
2个文件已删除
| | |
| | | set(QWINDOWKIT_INSTALL_NAME ${PROJECT_NAME}) |
| | | |
| | | # ---------------------------------- |
| | | # Main Project |
| | | # Find basic dependencies |
| | | # ---------------------------------- |
| | | find_package(qmsetup QUIET) |
| | | |
| | |
| | | set(qmsetup_DIR ${_package_path} CACHE PATH "" FORCE) |
| | | endif() |
| | | |
| | | qm_import(Filesystem) |
| | | qm_init_directories() |
| | | |
| | | # ---------------------------------- |
| | | # Add source modules |
| | | # ---------------------------------- |
| | | add_subdirectory(src) |
| | | |
| | | if(QWINDOWKIT_BUILD_EXAMPLES) |
| | |
| | | add_subdirectory(mainwindow) |
New file |
| | |
| | | project(QWKExample_MainWindow) |
| | | |
| | | set(CMAKE_AUTOMOC ON) |
| | | set(CMAKE_AUTOUIC ON) |
| | | set(CMAKE_AUTORCC ON) |
| | | |
| | | file(GLOB _src *.h *.cpp) |
| | | |
| | | add_executable(${PROJECT_NAME}) |
| | | |
| | | qm_configure_target(${PROJECT_NAME} |
| | | SOURCES ${_src} |
| | | QT_LINKS Core Gui Widgets |
| | | LINKS QWKWidgets |
| | | ) |
New file |
| | |
| | | #include <QApplication> |
| | | |
| | | #include "mainwindow.h" |
| | | |
| | | int main(int argc, char *argv[]) { |
| | | QApplication a(argc, argv); |
| | | MainWindow w; |
| | | w.show(); |
| | | return a.exec(); |
| | | } |
New file |
| | |
| | | #include "mainwindow.h" |
| | | |
| | | #include <QtCore/QDebug> |
| | | |
| | | #include <QWKWidgets/widgetwindowagent.h> |
| | | |
| | | MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { |
| | | auto agent = new QWK::WidgetWindowAgent(this); |
| | | if (!agent->setup(this)) { |
| | | qDebug() << "Frameless handle failed to initialize."; |
| | | } |
| | | } |
| | | |
| | | MainWindow::~MainWindow() { |
| | | } |
New file |
| | |
| | | #ifndef MAINWINDOW_H |
| | | #define MAINWINDOW_H |
| | | |
| | | #include <QtWidgets/QMainWindow> |
| | | |
| | | class MainWindow : public QMainWindow { |
| | | public: |
| | | explicit MainWindow(QWidget *parent = nullptr); |
| | | ~MainWindow(); |
| | | }; |
| | | |
| | | #endif // MAINWINDOW_H |
| | |
| | | qm_import(Filesystem Preprocess) |
| | | qm_init_directories() |
| | | qm_import(Preprocess) |
| | | |
| | | set(QWINDOWKIT_PROJECT_DESCRIPTION "Cross-platform window customization framework") |
| | | set(QWINDOWKIT_PROJECT_COPYRIGHT "Copyright 2023 Stdware Collections") |
| | |
| | | if(NOT FUNC_NO_SYNC_INCLUDE) |
| | | # Generate a standard include directory in build directory |
| | | qm_sync_include(. "${QWINDOWKIT_GENERATED_INCLUDE_DIR}/${_inc_name}" ${_install_options} |
| | | ${FUNC_SYNC_INCLUDE_OPTIONS} |
| | | ${FUNC_SYNC_INCLUDE_OPTIONS} FORCE |
| | | ) |
| | | target_include_directories(${_target} PUBLIC |
| | | "$<BUILD_INTERFACE:${QWINDOWKIT_GENERATED_INCLUDE_DIR}>" |
| | |
| | | corewindowagent_p.h |
| | | corewindowagent.cpp |
| | | windowitemdelegate.h |
| | | handler/abstractwindowcontext_p.h |
| | | handler/abstractwindowcontext.cpp |
| | | contexts/abstractwindowcontext_p.h |
| | | contexts/abstractwindowcontext.cpp |
| | | ) |
| | | |
| | | if(WIN32) |
| | | list(APPEND _src |
| | | qwindowkit_windows.h |
| | | handler/win32windowcontext_p.h |
| | | handler/win32windowcontext.cpp |
| | | qwindowkit_windows.cpp |
| | | contexts/win32windowcontext_p.h |
| | | contexts/win32windowcontext.cpp |
| | | ) |
| | | else() |
| | | list(APPEND _src |
| | | handler/qtwindowcontext_p.h |
| | | handler/qtwindowcontext.cpp |
| | | contexts/qtwindowcontext_p.h |
| | | contexts/qtwindowcontext.cpp |
| | | ) |
| | | if(APPLE) |
| | | # add files |
| | |
| | | LINKS |
| | | QT_LINKS Core Gui |
| | | QT_INCLUDE_PRIVATE Core Gui |
| | | INCLUDE_PRIVATE contexts |
| | | PREFIX QWK_CORE |
| | | ) |
| | | |
File was renamed from src/core/handler/abstractwindowcontext_p.h |
| | |
| | | ~AbstractWindowContext(); |
| | | |
| | | public: |
| | | virtual bool setup() = 0; |
| | | |
| | | inline QWindow *window() const; |
| | | void setupWindow(QWindow *window); |
| | | |
File was renamed from src/core/handler/qtwindowcontext.cpp |
| | |
| | | QtWindowContext::~QtWindowContext() { |
| | | } |
| | | |
| | | bool QtWindowContext::setup() { |
| | | return false; |
| | | } |
| | | |
| | | bool QtWindowContext::eventFilter(QObject *obj, QEvent *event) { |
| | | return AbstractWindowContext::eventFilter(obj, event); |
| | | } |
File was renamed from src/core/handler/qtwindowcontext_p.h |
| | |
| | | QtWindowContext(QWindow *window, WindowItemDelegate *delegate); |
| | | ~QtWindowContext(); |
| | | |
| | | public: |
| | | bool setup() override; |
| | | |
| | | protected: |
| | | bool eventFilter(QObject *obj, QEvent *event) override; |
| | | }; |
New file |
| | |
| | | #include "win32windowcontext_p.h" |
| | | |
| | | #include <QtCore/QHash> |
| | | |
| | | namespace QWK { |
| | | |
| | | using WndProcHash = QHash<HWND, Win32WindowContext *>; |
| | | Q_GLOBAL_STATIC(WndProcHash, g_wndProcHash); |
| | | |
| | | Win32WindowContext::Win32WindowContext(QWindow *window, WindowItemDelegate *delegate) |
| | | : AbstractWindowContext(window, delegate), windowId(0), qtWindowProc(nullptr) { |
| | | } |
| | | |
| | | Win32WindowContext::~Win32WindowContext() { |
| | | auto hWnd = reinterpret_cast<HWND>(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<HWND>(winId); |
| | | auto orgWndProc = reinterpret_cast<WNDPROC>(::GetWindowLongPtrW(hWnd, GWLP_WNDPROC)); |
| | | Q_ASSERT(orgWndProc); |
| | | if (!orgWndProc) { |
| | | QWK_WARNING << winLastErrorMessage(); |
| | | return false; |
| | | } |
| | | |
| | | if (::SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(windowProc)) == 0) { |
| | | QWK_WARNING << winLastErrorMessage(); |
| | | return false; |
| | | } |
| | | |
| | | windowId = winId; |
| | | qtWindowProc = orgWndProc; // Store original window proc |
| | | g_wndProcHash->insert(hWnd, this); // Save window handle mapping |
| | | return true; |
| | | } |
| | | |
| | | LRESULT Win32WindowContext::windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { |
| | | Q_ASSERT(hWnd); |
| | | if (!hWnd) { |
| | | return FALSE; |
| | | } |
| | | |
| | | const auto *ctx = g_wndProcHash->value(hWnd); |
| | | if (!ctx) { |
| | | return ::DefWindowProcW(hWnd, uMsg, wParam, lParam); |
| | | } |
| | | |
| | | auto winId = reinterpret_cast<WId>(hWnd); |
| | | |
| | | // Further procedure |
| | | Q_UNUSED(winId) |
| | | |
| | | return ::CallWindowProcW(ctx->qtWindowProc, hWnd, uMsg, wParam, lParam); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | #ifndef WIN32WINDOWCONTEXT_P_H |
| | | #define WIN32WINDOWCONTEXT_P_H |
| | | |
| | | #include <QWKCore/qwindowkit_windows.h> |
| | | #include <QWKCore/private/abstractwindowcontext_p.h> |
| | | |
| | | namespace QWK { |
| | | |
| | | class QWK_CORE_EXPORT Win32WindowContext : public AbstractWindowContext { |
| | | Q_OBJECT |
| | | public: |
| | | Win32WindowContext(QWindow *window, WindowItemDelegate *delegate); |
| | | ~Win32WindowContext(); |
| | | |
| | | public: |
| | | bool setup() override; |
| | | |
| | | protected: |
| | | WId windowId; |
| | | WNDPROC qtWindowProc; // Original Qt window proc function |
| | | |
| | | static LRESULT windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); |
| | | }; |
| | | |
| | | } |
| | | |
| | | #endif // WIN32WINDOWCONTEXT_P_H |
| | |
| | | #include "corewindowagent_p.h" |
| | | |
| | | #ifdef Q_OS_WINDOWS |
| | | # include "handler/win32windowcontext_p.h" |
| | | # include "win32windowcontext_p.h" |
| | | #else |
| | | # include "handler/qtwindowcontext_p.h" |
| | | # include "qtwindowcontext_p.h" |
| | | #endif |
| | | |
| | | Q_LOGGING_CATEGORY(qWindowKitLog, "qwindowkit") |
| | | |
| | | namespace QWK { |
| | | |
| | | CoreWindowAgentPrivate::CoreWindowAgentPrivate() { |
| | | CoreWindowAgentPrivate::CoreWindowAgentPrivate() : m_eventHandler(nullptr) { |
| | | } |
| | | |
| | | CoreWindowAgentPrivate::~CoreWindowAgentPrivate() { |
| | | delete m_eventHandler; |
| | | } |
| | | |
| | | void CoreWindowAgentPrivate::init() { |
| | | } |
| | | |
| | | void CoreWindowAgentPrivate::setup(QWindow *window, WindowItemDelegate *delegate) { |
| | | bool CoreWindowAgentPrivate::setup(QWindow *window, WindowItemDelegate *delegate) { |
| | | auto handler = |
| | | #ifdef Q_OS_WINDOWS |
| | | m_eventHandler = new Win32WindowContext(window, delegate); |
| | | new Win32WindowContext(window, delegate) |
| | | #else |
| | | m_eventHandler = new QtWindowContext(window, delegate); |
| | | new QtWindowContext(window, delegate) |
| | | #endif |
| | | ; |
| | | |
| | | if (!handler->setup()) { |
| | | delete handler; |
| | | return false; |
| | | } |
| | | m_eventHandler = handler; |
| | | return true; |
| | | } |
| | | |
| | | CoreWindowAgent::~CoreWindowAgent() { |
| | |
| | | |
| | | CoreWindowAgent *q_ptr; // no need to initialize |
| | | |
| | | void setup(QWindow *window, WindowItemDelegate *delegate); |
| | | bool setup(QWindow *window, WindowItemDelegate *delegate); |
| | | |
| | | AbstractWindowContext *m_eventHandler{}; |
| | | AbstractWindowContext *m_eventHandler; |
| | | }; |
| | | |
| | | } |
New file |
| | |
| | | #include "qwindowkit_windows.h" |
| | | |
| | | namespace QWK { |
| | | |
| | | QString winErrorMessage(DWORD code) { |
| | | LPWSTR buf = nullptr; |
| | | if (::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | |
| | | FORMAT_MESSAGE_IGNORE_INSERTS, |
| | | nullptr, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
| | | reinterpret_cast<LPWSTR>(&buf), 0, nullptr) == 0) { |
| | | return {}; |
| | | } |
| | | const QString &errorText = QString::fromWCharArray(buf).trimmed(); |
| | | ::LocalFree(buf); |
| | | return errorText; |
| | | } |
| | | |
| | | QString winLastErrorMessage() { |
| | | return winErrorMessage(::GetLastError()); |
| | | } |
| | | |
| | | } |
| | |
| | | #ifndef QWINDOWKIT_WINDOWS_H |
| | | #define QWINDOWKIT_WINDOWS_H |
| | | |
| | | #include <windows.h> |
| | | |
| | | #include <QString> |
| | | |
| | | #include <QWKCore/qwkcoreglobal.h> |
| | | |
| | | namespace QWK { |
| | | |
| | | QWK_CORE_EXPORT QString winErrorMessage(DWORD code); |
| | | |
| | | QWK_CORE_EXPORT QString winLastErrorMessage(); |
| | | |
| | | } |
| | | |
| | | #endif // QWINDOWKIT_WINDOWS_H |
| | |
| | | #ifndef QWKCOREGLOBAL_H |
| | | #define QWKCOREGLOBAL_H |
| | | |
| | | #include <QtGlobal> |
| | | #include <QLoggingCategory> |
| | | |
| | | #ifndef QWK_CORE_EXPORT |
| | | # ifdef QWK_CORE_STATIC |
| | |
| | | # endif |
| | | #endif |
| | | |
| | | QWK_CORE_EXPORT Q_DECLARE_LOGGING_CATEGORY(qWindowKitLog) |
| | | |
| | | #define QWK_INFO qCInfo(qWindowKitLog) |
| | | #define QWK_DEBUG qCDebug(qWindowKitLog) |
| | | #define QWK_WARNING qCWarning(qWindowKitLog) |
| | | #define QWK_CRITICAL qCCritical(qWindowKitLog) |
| | | |
| | | #endif // QWKCOREGLOBAL_H |
| | |
| | | QuickWindowAgent::~QuickWindowAgent() { |
| | | } |
| | | |
| | | void QuickWindowAgent::setup(QQuickWindow *window) { |
| | | bool QuickWindowAgent::setup(QQuickWindow *window) { |
| | | Q_ASSERT(window); |
| | | if (!window) { |
| | | return; |
| | | return false; |
| | | } |
| | | |
| | | Q_D(QuickWindowAgent); |
| | | if (d->host) { |
| | | return; |
| | | return false; |
| | | } |
| | | |
| | | if (!d->setup(window, new QuickItemDelegate())) { |
| | | return true; |
| | | } |
| | | d->host = window; |
| | | |
| | | d->setup(window, new QuickItemDelegate()); |
| | | return true; |
| | | } |
| | | |
| | | bool QuickWindowAgent::isHitTestVisible(QQuickItem *item) const { |
| | |
| | | ~QuickWindowAgent(); |
| | | |
| | | public: |
| | | void setup(QQuickWindow *window); |
| | | bool setup(QQuickWindow *window); |
| | | |
| | | bool isHitTestVisible(QQuickItem *item) const; |
| | | void setHitTestVisible(QQuickItem *item, bool visible); |
| | |
| | | WidgetWindowAgent::~WidgetWindowAgent() { |
| | | } |
| | | |
| | | void WidgetWindowAgent::setup(QWidget *w) { |
| | | bool WidgetWindowAgent::setup(QWidget *w) { |
| | | Q_ASSERT(w); |
| | | if (!w) { |
| | | return; |
| | | return false; |
| | | } |
| | | |
| | | Q_D(WidgetWindowAgent); |
| | | if (d->host) { |
| | | return; |
| | | return false; |
| | | } |
| | | d->host = w; |
| | | |
| | | std::ignore = w->winId(); // Make sure the window handle is created |
| | | d->setup(w->windowHandle(), new WidgetItemDelegate()); |
| | | if (!d->setup(w->windowHandle(), new WidgetItemDelegate())) { |
| | | return true; |
| | | } |
| | | d->host = w; |
| | | return true; |
| | | } |
| | | |
| | | bool WidgetWindowAgent::isHitTestVisible(QWidget *w) const { |
| | |
| | | ~WidgetWindowAgent(); |
| | | |
| | | public: |
| | | void setup(QWidget *w); |
| | | bool setup(QWidget *w); |
| | | |
| | | bool isHitTestVisible(QWidget *w) const; |
| | | void setHitTestVisible(QWidget *w, bool visible); |