diff options
Diffstat (limited to 'tests')
118 files changed, 3831 insertions, 635 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2214137..05cc44c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,4 +1,5 @@ -# Generated from tests.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause if(QT_BUILD_STANDALONE_TESTS) # Add qt_find_package calls for extra dependencies that need to be found when building diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt index 8537f4f..2f384ae 100644 --- a/tests/auto/CMakeLists.txt +++ b/tests/auto/CMakeLists.txt @@ -1,9 +1,18 @@ -# Generated from auto.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause add_subdirectory(conversion) add_subdirectory(qaxobject) -# add_subdirectory(dumpcpp) (needs typelib target) # special case -#add_subdirectory(cmake) # special case +add_subdirectory(dumpcpp) +add_subdirectory(cmake) +add_subdirectory(qbstr) + +find_program(midl midl.exe) +if (midl) + add_subdirectory(qaxobjectcom) +endif() + if(NOT GCC) add_subdirectory(qaxscript) + add_subdirectory(qaxscriptmanager) endif() diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro deleted file mode 100644 index 0b43b0d..0000000 --- a/tests/auto/auto.pro +++ /dev/null @@ -1,10 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS += \ - conversion \ - qaxobject \ - qaxscript \ - dumpcpp \ - cmake - -*g++*: SUBDIRS -= \ - qaxscript \ diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index 4f15a69..3611659 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -1,12 +1,46 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause -cmake_minimum_required(VERSION 2.8) -project(qmake_cmake_files) +cmake_minimum_required(VERSION 3.16) + +project(qtactivetqt_cmake_tests) enable_testing() -find_package(Qt5Core REQUIRED) +set(required_packages Core) +set(optional_packages Widgets Gui) + +# Setup the test when called as a completely standalone project. +if(TARGET Qt6::Core) + # Tests are built as part of the qtactiveqt build tree. + # Setup paths so that the Qt packages are found. + qt_internal_set_up_build_dir_package_paths() +endif() + +find_package(Qt6 REQUIRED COMPONENTS ${required_packages}) +find_package(Qt6 OPTIONAL_COMPONENTS ${optional_packages}) + +# Setup common test variables which were previously set by ctest_testcase_common.prf. +set(CMAKE_MODULES_UNDER_TEST "${required_packages}" "${optional_packages}") + +foreach(qt_package ${CMAKE_MODULES_UNDER_TEST}) + set(package_name "${QT_CMAKE_EXPORT_NAMESPACE}${qt_package}") + if(${package_name}_FOUND) + set(CMAKE_${qt_package}_MODULE_MAJOR_VERSION "${${package_name}_VERSION_MAJOR}") + set(CMAKE_${qt_package}_MODULE_MINOR_VERSION "${${package_name}_VERSION_MINOR}") + set(CMAKE_${qt_package}_MODULE_PATCH_VERSION "${${package_name}_VERSION_PATCH}") + endif() +endforeach() -include("${_Qt5CTestMacros}") +include("${_Qt6CTestMacros}") -expect_pass(test_modules) +if(TARGET Qt6::Widgets AND TARGET Qt6::Gui) + _qt_internal_test_expect_pass(test_target_typelibs) + _qt_internal_test_expect_pass(test_target_typelibs_absolute) + _qt_internal_test_expect_fail(test_target_typelibs_empty_libs) + _qt_internal_test_expect_fail(test_target_typelibs_non_existing_libs) + _qt_internal_test_expect_pass(test_target_typelibs_out_dir) + _qt_internal_test_expect_pass(test_modules/container) + _qt_internal_test_expect_pass(test_modules/server) +endif() diff --git a/tests/auto/cmake/cmake.pro b/tests/auto/cmake/cmake.pro deleted file mode 100644 index bf2dbcb..0000000 --- a/tests/auto/cmake/cmake.pro +++ /dev/null @@ -1,5 +0,0 @@ - -# Cause make to do nothing. -TEMPLATE = subdirs - -CONFIG += ctest_testcase diff --git a/tests/auto/cmake/test_modules/CMakeLists.txt b/tests/auto/cmake/test_modules/CMakeLists.txt deleted file mode 100644 index 4336ad4..0000000 --- a/tests/auto/cmake/test_modules/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ - -cmake_minimum_required(VERSION 2.8) - -project(test_modules) - -add_subdirectory(server) -add_subdirectory(container) diff --git a/tests/auto/cmake/test_modules/container/CMakeLists.txt b/tests/auto/cmake/test_modules/container/CMakeLists.txt index 6d04576..999e241 100644 --- a/tests/auto/cmake/test_modules/container/CMakeLists.txt +++ b/tests/auto/cmake/test_modules/container/CMakeLists.txt @@ -1,24 +1,10 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.16) project(cmake_axcontainer) -find_package(Qt5Core REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Widgets REQUIRED) - -find_package(Qt5AxContainer REQUIRED) - -include_directories( - ${Qt5AxContainer_INCLUDE_DIRS} -) - -add_definitions(${Qt5AxContainer_DEFINITIONS}) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") - +find_package(Qt6 COMPONENTS Core Gui Widgets AxContainer CONFIG REQUIRED) add_executable(axcontainerapp axcontainer.cpp) - -target_link_libraries(axcontainerapp - ${Qt5AxContainer_LIBRARIES} -) +target_link_libraries(axcontainerapp Qt6::Core Qt6::Gui Qt6::Widgets Qt6::AxContainer) diff --git a/tests/auto/cmake/test_modules/container/axcontainer.cpp b/tests/auto/cmake/test_modules/container/axcontainer.cpp index e16bddb..73d8ebb 100644 --- a/tests/auto/cmake/test_modules/container/axcontainer.cpp +++ b/tests/auto/cmake/test_modules/container/axcontainer.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <qt_windows.h> #include <QtAxContainer/QAxWidget> diff --git a/tests/auto/cmake/test_modules/server/CMakeLists.txt b/tests/auto/cmake/test_modules/server/CMakeLists.txt index f553990..0a8d420 100644 --- a/tests/auto/cmake/test_modules/server/CMakeLists.txt +++ b/tests/auto/cmake/test_modules/server/CMakeLists.txt @@ -1,24 +1,10 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.16) project(cmake_axserver) -find_package(Qt5Core REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Widgets REQUIRED) - -find_package(Qt5AxServer REQUIRED) - -include_directories( - ${Qt5AxServer_INCLUDE_DIRS} -) - -add_definitions(${Qt5AxServer_DEFINITIONS}) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}") - +find_package(Qt6 COMPONENTS Core Gui Widgets AxServer CONFIG REQUIRED) add_executable(axserverapp WIN32 axserver.cpp) - -target_link_libraries(axserverapp - ${Qt5AxServer_LIBRARIES} -) +target_link_libraries(axserverapp Qt6::Core Qt6::Gui Qt6::Widgets Qt6::AxServer) diff --git a/tests/auto/cmake/test_modules/server/axserver.cpp b/tests/auto/cmake/test_modules/server/axserver.cpp index b31014c..6dabc17 100644 --- a/tests/auto/cmake/test_modules/server/axserver.cpp +++ b/tests/auto/cmake/test_modules/server/axserver.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <qt_windows.h> #include <QAxFactory> diff --git a/tests/auto/cmake/test_target_typelibs/CMakeLists.txt b/tests/auto/cmake/test_target_typelibs/CMakeLists.txt new file mode 100644 index 0000000..528aa08 --- /dev/null +++ b/tests/auto/cmake/test_target_typelibs/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(tst_typelibs) + +find_package(Qt6 COMPONENTS AxContainer Gui Widgets CONFIG REQUIRED) + +add_executable(tst_typelibs main.cpp) +target_link_libraries(tst_typelibs PRIVATE Qt6::AxContainer Qt6::Gui Qt6::Widgets) + +qt6_target_typelibs(tst_typelibs LIBRARIES "ieframe.dll") diff --git a/tests/auto/cmake/test_target_typelibs/main.cpp b/tests/auto/cmake/test_target_typelibs/main.cpp new file mode 100644 index 0000000..4b69f66 --- /dev/null +++ b/tests/auto/cmake/test_target_typelibs/main.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "ieframe.h" + +int main(int argc, char *argv[]) +{ + SHDocVw::WebBrowser* webBrowser = new SHDocVw::WebBrowser; + delete webBrowser; + return 0; +} diff --git a/tests/auto/cmake/test_target_typelibs_absolute/CMakeLists.txt b/tests/auto/cmake/test_target_typelibs_absolute/CMakeLists.txt new file mode 100644 index 0000000..942fa54 --- /dev/null +++ b/tests/auto/cmake/test_target_typelibs_absolute/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(tst_typelibs) + +find_package(Qt6 COMPONENTS AxContainer Gui Widgets CONFIG REQUIRED) + +add_executable(tst_typelibs main.cpp) +target_link_libraries(tst_typelibs PRIVATE Qt6::AxContainer Qt6::Gui Qt6::Widgets) + +qt6_target_typelibs(tst_typelibs LIBRARIES "$ENV{SystemRoot}/System32/ieframe.dll") diff --git a/tests/auto/cmake/test_target_typelibs_absolute/main.cpp b/tests/auto/cmake/test_target_typelibs_absolute/main.cpp new file mode 100644 index 0000000..4b69f66 --- /dev/null +++ b/tests/auto/cmake/test_target_typelibs_absolute/main.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "ieframe.h" + +int main(int argc, char *argv[]) +{ + SHDocVw::WebBrowser* webBrowser = new SHDocVw::WebBrowser; + delete webBrowser; + return 0; +} diff --git a/tests/auto/cmake/test_target_typelibs_empty_libs/CMakeLists.txt b/tests/auto/cmake/test_target_typelibs_empty_libs/CMakeLists.txt new file mode 100644 index 0000000..2971c1b --- /dev/null +++ b/tests/auto/cmake/test_target_typelibs_empty_libs/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(tst_typelibs) + +find_package(Qt6 COMPONENTS AxContainer Gui Widgets CONFIG REQUIRED) + +add_executable(tst_typelibs main.cpp) +target_link_libraries(tst_typelibs PRIVATE Qt6::AxContainer Qt6::Gui Qt6::Widgets) + +qt6_target_typelibs(tst_typelibs) diff --git a/tests/auto/cmake/test_target_typelibs_empty_libs/main.cpp b/tests/auto/cmake/test_target_typelibs_empty_libs/main.cpp new file mode 100644 index 0000000..4b69f66 --- /dev/null +++ b/tests/auto/cmake/test_target_typelibs_empty_libs/main.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "ieframe.h" + +int main(int argc, char *argv[]) +{ + SHDocVw::WebBrowser* webBrowser = new SHDocVw::WebBrowser; + delete webBrowser; + return 0; +} diff --git a/tests/auto/cmake/test_target_typelibs_non_existing_libs/CMakeLists.txt b/tests/auto/cmake/test_target_typelibs_non_existing_libs/CMakeLists.txt new file mode 100644 index 0000000..aaca1c9 --- /dev/null +++ b/tests/auto/cmake/test_target_typelibs_non_existing_libs/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(tst_typelibs) + +find_package(Qt6 COMPONENTS AxContainer Gui Widgets CONFIG REQUIRED) + +add_executable(tst_typelibs main.cpp) +target_link_libraries(tst_typelibs PRIVATE Qt6::AxContainer Qt6::Gui Qt6::Widgets) + +qt6_target_typelibs(tst_typelibs LIBRARIES "ieframe.dll" "qt100notexistinglib.dll") diff --git a/tests/auto/cmake/test_target_typelibs_non_existing_libs/main.cpp b/tests/auto/cmake/test_target_typelibs_non_existing_libs/main.cpp new file mode 100644 index 0000000..4b69f66 --- /dev/null +++ b/tests/auto/cmake/test_target_typelibs_non_existing_libs/main.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "ieframe.h" + +int main(int argc, char *argv[]) +{ + SHDocVw::WebBrowser* webBrowser = new SHDocVw::WebBrowser; + delete webBrowser; + return 0; +} diff --git a/tests/auto/cmake/test_target_typelibs_out_dir/CMakeLists.txt b/tests/auto/cmake/test_target_typelibs_out_dir/CMakeLists.txt new file mode 100644 index 0000000..d1c38ae --- /dev/null +++ b/tests/auto/cmake/test_target_typelibs_out_dir/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +cmake_minimum_required(VERSION 3.16) +project(tst_typelibs) + +find_package(Qt6 COMPONENTS AxContainer Gui Widgets CONFIG REQUIRED) + +add_executable(tst_typelibs main.cpp) +target_link_libraries(tst_typelibs PRIVATE Qt6::AxContainer Qt6::Gui Qt6::Widgets) +target_include_directories(tst_typelibs PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") + +qt6_target_typelibs(tst_typelibs LIBRARIES "ieframe.dll" + OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/typelibs" +) diff --git a/tests/auto/cmake/test_target_typelibs_out_dir/main.cpp b/tests/auto/cmake/test_target_typelibs_out_dir/main.cpp new file mode 100644 index 0000000..a2f659a --- /dev/null +++ b/tests/auto/cmake/test_target_typelibs_out_dir/main.cpp @@ -0,0 +1,11 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "typelibs/ieframe.h" + +int main(int argc, char *argv[]) +{ + SHDocVw::WebBrowser* webBrowser = new SHDocVw::WebBrowser; + delete webBrowser; + return 0; +} diff --git a/tests/auto/conversion/CMakeLists.txt b/tests/auto/conversion/CMakeLists.txt index 4aab821..1e25aeb 100644 --- a/tests/auto/conversion/CMakeLists.txt +++ b/tests/auto/conversion/CMakeLists.txt @@ -1,13 +1,24 @@ -# Generated from conversion.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## conversion Test: ##################################################################### -qt_add_test(conversion +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(conversion LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_test(conversion SOURCES tst_conversion.cpp - PUBLIC_LIBRARIES + INCLUDE_DIRECTORIES + ../../../src/activeqt/shared/ + LIBRARIES Qt::AxContainer Qt::Gui + Qt::AxBasePrivate + Qt::CorePrivate ) diff --git a/tests/auto/conversion/comutil_p.h b/tests/auto/conversion/comutil_p.h new file mode 100644 index 0000000..e722ed5 --- /dev/null +++ b/tests/auto/conversion/comutil_p.h @@ -0,0 +1,250 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef COMUTIL_P_H +#define COMUTIL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QtGlobal> +#include <QtAxBase/private/qbstr_p.h> +#include <comdef.h> +#include <type_traits> +#include <oleauto.h> +#include <wrl/client.h> + +using Microsoft::WRL::ComPtr; + +template<typename T> +ComPtr<T> makeComObject() +{ + ComPtr<T> ptr; + *ptr.GetAddressOf() = new T; + return ptr; +} + +template<typename T> +constexpr VARTYPE ValueType() +{ + using ValueType = std::remove_cv_t<std::remove_pointer_t<T>>; + + constexpr VARTYPE maybeByref = std::is_pointer_v<T> ? VT_BYREF : VT_EMPTY; + if constexpr (std::is_same_v<ValueType, bool>) + return VT_BOOL | maybeByref; + else if constexpr (std::is_same_v<ValueType, char>) + return VT_I1 | maybeByref; + else if constexpr (std::is_same_v<ValueType, unsigned char>) + return VT_UI1 | maybeByref; + else if constexpr (std::is_same_v<ValueType, short>) + return VT_I2 | maybeByref; + else if constexpr (std::is_same_v<ValueType, unsigned short>) + return VT_UI2 | maybeByref; + else if constexpr (std::is_same_v<ValueType, int>) + return VT_I4 | maybeByref; + else if constexpr (std::is_same_v<ValueType, unsigned int>) + return VT_UI4 | maybeByref; + else if constexpr (std::is_same_v<ValueType, long long>) + return VT_I8 | maybeByref; + else if constexpr (std::is_same_v<ValueType, unsigned long long>) + return VT_UI8 | maybeByref; + else if constexpr (std::is_same_v<ValueType, float>) + return VT_R4 | maybeByref; + else if constexpr (std::is_same_v<ValueType, double>) + return VT_R8 | maybeByref; + else if constexpr (std::is_same_v<const ValueType *, const wchar_t *>) + return VT_BSTR; + else if constexpr (std::is_base_of_v<IDispatch, ValueType>) + return VT_DISPATCH; + else if constexpr (std::is_base_of_v<IUnknown, ValueType>) + return VT_UNKNOWN; + else + return VT_EMPTY; +}; + +template<typename T> +constexpr auto ValueField() +{ + using Type = std::remove_const_t<T>; + if constexpr (std::is_same_v<Type, bool>) + return &VARIANT::boolVal; + else if constexpr (std::is_same_v<Type, bool *>) + return &VARIANT::pboolVal; + else if constexpr (std::is_same_v<Type, char>) + return &VARIANT::cVal; + else if constexpr (std::is_same_v<Type, char *>) + return &VARIANT::pcVal; + else if constexpr (std::is_same_v<Type, unsigned char>) + return &VARIANT::bVal; + else if constexpr (std::is_same_v<Type, unsigned char *>) + return &VARIANT::pbVal; + else if constexpr (std::is_same_v<Type, short>) + return &VARIANT::iVal; + else if constexpr (std::is_same_v<Type, short *>) + return &VARIANT::piVal; + else if constexpr (std::is_same_v<Type, unsigned short>) + return &VARIANT::uiVal; + else if constexpr (std::is_same_v<Type, unsigned short *>) + return &VARIANT::puiVal; + else if constexpr (std::is_same_v<Type, int>) + return &VARIANT::intVal; + else if constexpr (std::is_same_v<Type, int *>) + return &VARIANT::pintVal; + else if constexpr (std::is_same_v<Type, unsigned int>) + return &VARIANT::uintVal; + else if constexpr (std::is_same_v<Type, unsigned int *>) + return &VARIANT::puintVal; + else if constexpr (std::is_same_v<Type, long long>) + return &VARIANT::llVal; + else if constexpr (std::is_same_v<Type, long long *>) + return &VARIANT::pllVal; + else if constexpr (std::is_same_v<Type, unsigned long long>) + return &VARIANT::ullVal; + else if constexpr (std::is_same_v<Type, unsigned long long *>) + return &VARIANT::pullVal; + else if constexpr (std::is_same_v<Type, float>) + return &VARIANT::fltVal; + else if constexpr (std::is_same_v<Type, float *>) + return &VARIANT::pfltVal; + else if constexpr (std::is_same_v<Type, double>) + return &VARIANT::dblVal; + else if constexpr (std::is_same_v<Type, double *>) + return &VARIANT::pdblVal; + else if constexpr (std::is_same_v<T, const wchar_t *>) + return &VARIANT::bstrVal; + else if constexpr (std::is_base_of_v<IDispatch, std::remove_pointer_t<Type>>) + return &VARIANT::pdispVal; + else if constexpr (std::is_base_of_v<IUnknown, std::remove_pointer_t<Type>>) + return &VARIANT::punkVal; +} + +class ComVariant : public tagVARIANT +{ +public: + ComVariant() noexcept : VARIANT{} { ::VariantInit(this); } + + ~ComVariant() + { + const HRESULT hr = ::VariantClear(this); + Q_ASSERT(hr == S_OK); + Q_UNUSED(hr) + } + + ComVariant(const ComVariant &src) : ComVariant() { copy(&src); } + ComVariant(const VARIANT &src) noexcept : ComVariant() { copy(&src); } + ComVariant(const QBStr &src) noexcept : ComVariant() { copy(src.bstr()); } + + template<typename T> + ComVariant(const T &value) : ComVariant() + { + assign(value); + } + + ComVariant &operator=(const ComVariant &rhs) noexcept + { + if (this == &rhs) + return *this; + + clear(); + copy(&rhs); + + return *this; + } + + template<typename T> + ComVariant &operator=(const T &rhs) + { + assign(rhs); + return *this; + } + + void clear() + { + const HRESULT hr = ::VariantClear(this); + + Q_ASSERT(hr == S_OK); + Q_UNUSED(hr) + } + + void copy(const VARIANT *src) + { + vt = VT_EMPTY; + const HRESULT hr = ::VariantCopy(this, const_cast<VARIANT *>(src)); + + Q_ASSERT(hr == S_OK); + Q_UNUSED(hr) + } + + void copy(const BSTR &src) + { + vt = VT_EMPTY; + if (!src) + return; + + vt = VT_BSTR; + bstrVal = ::SysAllocStringByteLen(reinterpret_cast<const char *>(src), + ::SysStringByteLen(src)); + + Q_ASSERT(bstrVal); + } + + bool operator==(const ComVariant &rhs) const + { + auto *lhs = const_cast<tagVARIANT *>(static_cast<const tagVARIANT *>(this)); + auto *other = const_cast<tagVARIANT *>(static_cast<const tagVARIANT *>(&rhs)); + return compare(lhs, other, LOCALE_USER_DEFAULT, 0) == static_cast<HRESULT>(VARCMP_EQ); + } + +private: + template<typename T> + void assign(const T &value) + { + constexpr VARTYPE valueType = ValueType<T>(); + static_assert(valueType != VT_EMPTY, "Invalid type for ComVariant"); + + vt = valueType; + + constexpr auto VARIANT::*field = ValueField<T>(); + if constexpr (valueType == VT_BSTR) + this->*field = QBStr{ value }.release(); + else + this->*field = value; + + if constexpr (valueType == VT_UNKNOWN || valueType == VT_DISPATCH) + value->AddRef(); + } + + static HRESULT compare(VARIANT *lhs, VARIANT *rhs, LCID lcid, ULONG flags) + { + // Workaround missing support for VT_I1, VT_UI2, VT_UI4 and VT_UI8 in VarCmp + switch (lhs->vt) { + case VT_I1: + if (lhs->cVal == rhs->cVal) + return VARCMP_EQ; + return lhs->cVal > rhs->cVal ? VARCMP_GT : VARCMP_LT; + case VT_UI2: + if (lhs->uiVal == rhs->uiVal) + return VARCMP_EQ; + return lhs->uiVal > rhs->uiVal ? VARCMP_GT : VARCMP_LT; + case VT_UI4: + if (lhs->uintVal == rhs->uintVal) + return VARCMP_EQ; + return lhs->uintVal > rhs->uintVal ? VARCMP_GT : VARCMP_LT; + case VT_UI8: + if (lhs->ullVal == rhs->ullVal) + return VARCMP_EQ; + return lhs->ullVal > rhs->ullVal ? VARCMP_GT : VARCMP_LT; + } + return ::VarCmp(lhs, rhs, lcid, flags); + } +}; + +#endif diff --git a/tests/auto/conversion/conversion.pro b/tests/auto/conversion/conversion.pro deleted file mode 100644 index 47f0699..0000000 --- a/tests/auto/conversion/conversion.pro +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG += testcase -QT += axcontainer testlib -SOURCES += tst_conversion.cpp diff --git a/tests/auto/conversion/testutil_p.h b/tests/auto/conversion/testutil_p.h new file mode 100644 index 0000000..572e3d1 --- /dev/null +++ b/tests/auto/conversion/testutil_p.h @@ -0,0 +1,60 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef TESTUTIL_P_H +#define TESTUTIL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qtcore/qt_windows.h> +#include <qtcore/private/qcomobject_p.h> +#include <qtcore/qtglobal> +#include <wrl/client.h> +#include <atomic> + +using Microsoft::WRL::ComPtr; + +template <typename T> +ULONG refCount(const ComPtr<T> &p) +{ + p->AddRef(); + return p->Release(); +} + +struct IUnknownStub : QComObject<IUnknown> +{ +}; + +struct IDispatchStub : QComObject<IDispatch> +{ + HRESULT GetTypeInfoCount(UINT * /*pctinfo*/) override { return E_NOTIMPL; } + + HRESULT GetTypeInfo(UINT /*iTInfo*/, LCID /*lcid*/, ITypeInfo ** /*ppTInfo*/) override + { + return E_NOTIMPL; + } + + HRESULT GetIDsOfNames(const IID & /*riid*/, LPOLESTR * /*rgszNames*/, UINT /*cNames*/, + LCID /*lcid*/, DISPID * /*rgDispId*/) override + { + return E_NOTIMPL; + } + + HRESULT Invoke(DISPID /*dispIdMember*/, const IID & /*riid*/, LCID /*lcid*/, WORD /*wFlags*/, + DISPPARAMS * /*pDispParams*/, VARIANT * /*pVarResult*/, + EXCEPINFO * /*pExcepInfo*/, UINT * /*puArgErr*/) override + { + return E_NOTIMPL; + } +}; + +#endif diff --git a/tests/auto/conversion/tst_conversion.cpp b/tests/auto/conversion/tst_conversion.cpp index 52be69b..ba7bb5d 100644 --- a/tests/auto/conversion/tst_conversion.cpp +++ b/tests/auto/conversion/tst_conversion.cpp @@ -1,30 +1,11 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "comutil_p.h" +#include "testutil_p.h" + +#include <qaxtypes_p.h> +#include <ActiveQt/qaxobject.h> #include <QtTest/QtTest> #include <QtCore/QVariant> @@ -32,18 +13,13 @@ #include <QtCore/QMetaType> #include <qt_windows.h> +#include <wrl/client.h> -QT_BEGIN_NAMESPACE - -// Conversion functions from statically linked library (axtypes.h) -bool QVariantToVARIANT_container(const QVariant &var, VARIANT &arg, - const QByteArray &typeName = QByteArray(), - bool out = false); +using Microsoft::WRL::ComPtr; -QVariant VARIANTToQVariant_container(const VARIANT &arg, const QByteArray &typeName, - uint type = 0); +QT_BEGIN_NAMESPACE -QT_END_NAMESPACE +using namespace Qt::StringLiterals; class tst_Conversion : public QObject { @@ -52,6 +28,36 @@ class tst_Conversion : public QObject private slots: void conversion_data(); void conversion(); + + void VARIANTToQVariant_ReturnsBool_WhenCalledWithVariantBool(); + void QVariantToVARIANT_ReturnsVariantBool_WhenCalledWithBool(); + + void VARIANTToQVariant_ReturnsString_WhenCalledWithString_data(); + void VARIANTToQVariant_ReturnsString_WhenCalledWithString(); + + void QVariantToVARIANT_ReturnsString_WhenCalledWithString_data(); + void QVariantToVARIANT_ReturnsString_WhenCalledWithString(); + + void VARIANTToQVariant_ReturnsCopyOfValue_WhenCalledWithMaxPossibleValueOrPointer_data(); + void VARIANTToQVariant_ReturnsCopyOfValue_WhenCalledWithMaxPossibleValueOrPointer(); + + void QVariantToVARIANT_ReturnsCopyOfValue_WhenCalledWithMaxPossibleValue_data(); + void QVariantToVARIANT_ReturnsCopyOfValue_WhenCalledWithMaxPossibleValue(); + + void VARIANTToQVariant_DoesNotIncreaseRefCount_WhenGivenAnIUnknown(); + void QVariantToVARIANT_RecoversIUnknown_WhenQVariantHasIUnknown(); + + void VARIANTToQVariant_DoesNotIncreaseRefCount_WhenGivenAnIDispatch(); + void QVariantToVARIANT_RecoversIDispatch_WhenQVariantHasIDispatch(); + + void VARIANTToQVariant_IncreasesRefCount_WhenCalledWithQVariantTypeName(); + + void ObserveThat_VARIANTToQVariant_ReturnsEmptyQVariant_WhenWrappingIDispatchInQAxObjectPtr(); + void VARIANTToQVariant_CreatesQAxObject_WhenCalledWithMetaTypeId(); + +private: + template<typename T> + static void addScalarMaxValueRow(); }; enum Mode { @@ -170,6 +176,11 @@ void tst_Conversion::conversion_data() << qvar << uint(VT_DATE | VT_BYREF) << typeName << ByReference; QTest::newRow("datetime-out") << qvar << uint(VT_DATE | VT_BYREF) << typeName << OutParameter; + + // QTBUG-122762; do not create a 2-dimensional array from a string (sequence). + qvar = QVariant(QVariantList{QVariant(QString("test"_L1)), QVariant(42)}); + QTest::newRow("list") + << qvar << uint(VT_VARIANT | VT_ARRAY | VT_BYREF) << typeName << OutParameter; } void tst_Conversion::conversion() @@ -195,5 +206,271 @@ void tst_Conversion::conversion() delete variant.pullVal; } +void tst_Conversion::VARIANTToQVariant_ReturnsBool_WhenCalledWithVariantBool() +{ + { + const ComVariant v = true; + const QVariant result = VARIANTToQVariant(v, "canBeAnything"); + QVERIFY(result == true); + } + + { + const ComVariant v = false; + const QVariant result = VARIANTToQVariant(v, "canBeAnything"); + QVERIFY(result == false); + } +} + +void tst_Conversion::QVariantToVARIANT_ReturnsVariantBool_WhenCalledWithBool() +{ + { + const QVariant v = true; + ComVariant result; + QVERIFY(QVariantToVARIANT(v, result)); + QVERIFY(result.vt == VT_BOOL); + QVERIFY(result.boolVal == VARIANT_TRUE); + } + + { + const QVariant v = false; + ComVariant result; + QVERIFY(QVariantToVARIANT(v, result)); + QVERIFY(result.vt == VT_BOOL); + QVERIFY(result.boolVal == VARIANT_FALSE); + } +} + +void tst_Conversion::VARIANTToQVariant_ReturnsString_WhenCalledWithString_data() +{ + QTest::addColumn<QString>("text"); + QTest::newRow("empty") << QString{ "" }; + QTest::newRow("nonempty") << QString{ "Some Latin 1 text" }; +} + +void tst_Conversion::VARIANTToQVariant_ReturnsString_WhenCalledWithString() +{ + QFETCH(QString, text); + + const ComVariant comVariant = text.toStdWString().c_str(); + const QVariant actual = VARIANTToQVariant(comVariant, {}); + + QCOMPARE(actual, text); +} + +void tst_Conversion::QVariantToVARIANT_ReturnsString_WhenCalledWithString_data() +{ + QTest::addColumn<QString>("text"); + QTest::newRow("empty") << QString{ "" }; + QTest::newRow("nonempty") << QString{ "Some Latin 1 text" }; +} + +void tst_Conversion::QVariantToVARIANT_ReturnsString_WhenCalledWithString() +{ + QFETCH(QString, text); + + ComVariant comVariant; + QVERIFY(QVariantToVARIANT(text, comVariant)); + + const QString actual = QString::fromWCharArray(comVariant.bstrVal); + + QCOMPARE(actual, text); +} + +void tst_Conversion:: + VARIANTToQVariant_ReturnsCopyOfValue_WhenCalledWithMaxPossibleValueOrPointer_data() +{ + QTest::addColumn<ComVariant>("comVariant"); + QTest::addColumn<QVariant>("qvariant"); + + addScalarMaxValueRow<char>(); + addScalarMaxValueRow<unsigned char>(); + addScalarMaxValueRow<short>(); + addScalarMaxValueRow<unsigned short>(); + addScalarMaxValueRow<int>(); + addScalarMaxValueRow<unsigned int>(); + addScalarMaxValueRow<long long>(); + addScalarMaxValueRow<unsigned long long>(); + addScalarMaxValueRow<float>(); + addScalarMaxValueRow<double>(); + + addScalarMaxValueRow<char *>(); + addScalarMaxValueRow<unsigned char *>(); + addScalarMaxValueRow<short *>(); + addScalarMaxValueRow<unsigned short *>(); + addScalarMaxValueRow<int *>(); + addScalarMaxValueRow<unsigned int *>(); + addScalarMaxValueRow<long long *>(); + addScalarMaxValueRow<unsigned long long *>(); + addScalarMaxValueRow<float *>(); + addScalarMaxValueRow<double *>(); +} + +void tst_Conversion::VARIANTToQVariant_ReturnsCopyOfValue_WhenCalledWithMaxPossibleValueOrPointer() +{ + QFETCH(ComVariant, comVariant); + QFETCH(QVariant, qvariant); + + const QVariant actual = VARIANTToQVariant(comVariant, qvariant.typeName()); + + QCOMPARE(actual, qvariant); +} + +void tst_Conversion::QVariantToVARIANT_ReturnsCopyOfValue_WhenCalledWithMaxPossibleValue_data() +{ + QTest::addColumn<ComVariant>("comVariant"); + QTest::addColumn<QVariant>("qvariant"); + + addScalarMaxValueRow<int>(); + addScalarMaxValueRow<unsigned int>(); + addScalarMaxValueRow<long long>(); + addScalarMaxValueRow<unsigned long long>(); + addScalarMaxValueRow<float>(); + addScalarMaxValueRow<double>(); +} + +void tst_Conversion::QVariantToVARIANT_ReturnsCopyOfValue_WhenCalledWithMaxPossibleValue() +{ + QFETCH(ComVariant, comVariant); + QFETCH(QVariant, qvariant); + + ComVariant actual; + QVERIFY(QVariantToVARIANT(qvariant, actual)); + + QCOMPARE(actual, comVariant); +} + +void tst_Conversion::VARIANTToQVariant_DoesNotIncreaseRefCount_WhenGivenAnIUnknown() +{ + const auto stub = makeComObject<IUnknownStub>(); + + const ComVariant value = stub.Get(); + + const ULONG expectedRefCount = refCount(stub); + + const QVariant qVariant = VARIANTToQVariant(value, {}); + + QVERIFY(refCount(stub) == expectedRefCount); + + Q_UNUSED(qVariant); +} + +void tst_Conversion::QVariantToVARIANT_RecoversIUnknown_WhenQVariantHasIUnknown() +{ + const auto stub = makeComObject<IUnknownStub>(); + const ComVariant value = stub.Get(); + + const QVariant qvar = VARIANTToQVariant(value, {}); + + ComVariant comVariant; + + const ULONG expectedRefCount = refCount(stub) + 1; // Add one for the VARIANT + + QVERIFY(QVariantToVARIANT(qvar, comVariant)); + + QCOMPARE(refCount(stub), expectedRefCount); + + const ComPtr<IUnknown> recovered = comVariant.punkVal; + + QCOMPARE(recovered, stub); +} + +void tst_Conversion::VARIANTToQVariant_DoesNotIncreaseRefCount_WhenGivenAnIDispatch() +{ + const auto stub = makeComObject<IDispatchStub>(); + + const ComVariant value = stub.Get(); + + const ULONG expectedRefCount = refCount(stub); + + const QVariant qVariant = VARIANTToQVariant(value, "IDispatch*"); + + QCOMPARE(refCount(stub), expectedRefCount); + + Q_UNUSED(qVariant); +} + +struct IDispatchFixture +{ + const ComPtr<IDispatchStub> m_iDispatchStub = makeComObject<IDispatchStub>(); + const ComVariant m_comVariant = m_iDispatchStub.Get(); + const QVariant m_qVariant = VARIANTToQVariant(m_comVariant, "IDispatch*"); +}; + +void tst_Conversion::QVariantToVARIANT_RecoversIDispatch_WhenQVariantHasIDispatch() +{ + const IDispatchFixture testFixture; + const auto expectedRefCount = refCount(testFixture.m_iDispatchStub) + 1; + + ComVariant comVariant; + QVERIFY(QVariantToVARIANT(testFixture.m_qVariant, comVariant)); + + QCOMPARE(refCount(testFixture.m_iDispatchStub), expectedRefCount); + + const ComPtr<IUnknown> recovered = comVariant.pdispVal; + + QCOMPARE(recovered, testFixture.m_iDispatchStub); +} + +void tst_Conversion::VARIANTToQVariant_IncreasesRefCount_WhenCalledWithQVariantTypeName() +{ + const IDispatchFixture testFixture; + const auto expectedRefCount = refCount(testFixture.m_iDispatchStub) + 1; + + QVariant qVariant = VARIANTToQVariant(testFixture.m_comVariant, "QVariant"); + qVariant = {}; + + // Observe that IDispatch interface is leaked here, since + // the QVariant destructor does not decrement the refcount + QCOMPARE(refCount(testFixture.m_iDispatchStub), expectedRefCount); + + // Workaround to ensure cleanup + testFixture.m_iDispatchStub->Release(); +} + +void tst_Conversion::ObserveThat_VARIANTToQVariant_ReturnsEmptyQVariant_WhenWrappingIDispatchInQAxObjectPtr() +{ + const IDispatchFixture testFixture; + QCOMPARE(refCount(testFixture.m_iDispatchStub), 2u); + + qRegisterMetaType<QAxObject *>("QAxObject*"); + qRegisterMetaType<QAxObject>("QAxObject"); + + const QVariant qVariant = VARIANTToQVariant(testFixture.m_comVariant, "QAxObject*"); + QVERIFY(qVariant.isNull()); +} + +void tst_Conversion::VARIANTToQVariant_CreatesQAxObject_WhenCalledWithMetaTypeId() +{ + const IDispatchFixture testFixture; + QCOMPARE(refCount(testFixture.m_iDispatchStub), 2u); + + qRegisterMetaType<QAxObject *>("QAxObject*"); + qRegisterMetaType<QAxObject>("QAxObject"); + + const QVariant qVariant = VARIANTToQVariant(testFixture.m_comVariant, "QAxObject*", QMetaType::fromType<QAxObject*>().id()); + + QAxObject *recovered = qVariant.value<QAxObject *>(); + QVERIFY(recovered != nullptr); +} + +template<typename T> +void tst_Conversion::addScalarMaxValueRow() +{ + using ValueType = std::remove_pointer_t<T>; + static ValueType v = std::numeric_limits<ValueType>::max(); + + ComVariant comVariant; + if constexpr (std::is_pointer_v<T>) + comVariant = &v; + else + comVariant = v; + + const char *typeName = QMetaType::fromType<T>().name(); + QTest::newRow(typeName) << comVariant << QVariant{ v }; +} + QTEST_MAIN(tst_Conversion) + +QT_END_NAMESPACE + #include "tst_conversion.moc" diff --git a/tests/auto/dumpcpp/CMakeLists.txt b/tests/auto/dumpcpp/CMakeLists.txt index 91da6c3..a5ff2dc 100644 --- a/tests/auto/dumpcpp/CMakeLists.txt +++ b/tests/auto/dumpcpp/CMakeLists.txt @@ -1,20 +1,24 @@ -# Generated from dumpcpp.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_dumpcpp Test: ##################################################################### -qt_add_test(tst_dumpcpp +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_dumpcpp LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_test(tst_dumpcpp SOURCES tst_dumpcpp.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::AxContainer Qt::Gui Qt::Widgets ) -#### Keys ignored in scope 1:.:.:dumpcpp.pro:<TRUE>: -# TYPELIBS = "$$(SystemRoot)\\system32\\ieframe.dll" - -## Scopes: -##################################################################### +qt6_target_typelibs(tst_dumpcpp LIBRARIES "ieframe.dll") +qt6_target_typelibs(tst_dumpcpp LIBRARIES "msxml6.dll") diff --git a/tests/auto/dumpcpp/dumpcpp.pro b/tests/auto/dumpcpp/dumpcpp.pro deleted file mode 100644 index aae7bd8..0000000 --- a/tests/auto/dumpcpp/dumpcpp.pro +++ /dev/null @@ -1,11 +0,0 @@ -CONFIG += testcase -QT += widgets axcontainer testlib -SOURCES += tst_dumpcpp.cpp -TARGET = tst_dumpcpp - -# Assume Web Browser type library is available in all windows installations -TYPELIBS = $$(SystemRoot)\\system32\\ieframe.dll - -!exists($$TYPELIBS) { - message("Web Browser type library for test not found!") -} diff --git a/tests/auto/dumpcpp/tst_dumpcpp.cpp b/tests/auto/dumpcpp/tst_dumpcpp.cpp index 039c090..66cd158 100644 --- a/tests/auto/dumpcpp/tst_dumpcpp.cpp +++ b/tests/auto/dumpcpp/tst_dumpcpp.cpp @@ -1,47 +1,55 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtTest/QtTest> #include "ieframe.h" // generated header +#include "msxml6.h" // generated header #include <QApplication> + +struct XmlFixture +{ + MSXML2::DOMDocument60 doc; + MSXML2::IXMLDOMNodeList *root; + + const QString xml{ + R"( + <root prop="The root property"> + The value + </root> + )" }; +}; + class tst_dumpcpp : public QObject { Q_OBJECT private slots: + void init(); void toggleAddressBar(); + void propertyGetter_ReturnsValue_WhenValueIsInt(); + void propertyGetter_ReturnsValue_WhenValueIsString(); + void invokeGetter_ReturnsValue_WhenValueInheritsIDispatch(); + void propertyGetter_ReturnsValue_WhenValueInheritsIDispatch(); + + void propertySetter_SetsValue_WhenValueIsVariantInt(); + void propertySetter_SetsValue_WhenValueIsString(); + void invoke_SetsValue_WhenValueDerivesFromIDispatch(); + +private: + XmlFixture m_xml; }; +void tst_dumpcpp::init() +{ + m_xml.doc.loadXML(m_xml.xml); + m_xml.root = m_xml.doc.childNodes(); +} + // A simple test to verify that an object can be instantiated and interacted with void tst_dumpcpp::toggleAddressBar() { - SHDocVw::WebBrowser* webBrowser = new SHDocVw::WebBrowser; + SHDocVw::WebBrowser *webBrowser = new SHDocVw::WebBrowser; QVERIFY(webBrowser); bool addressBar = webBrowser->AddressBar(); addressBar = !addressBar; @@ -50,5 +58,60 @@ void tst_dumpcpp::toggleAddressBar() delete webBrowser; } +void tst_dumpcpp::propertyGetter_ReturnsValue_WhenValueIsInt() +{ + int length = m_xml.root->length(); + QVERIFY(length == 1); +} + +void tst_dumpcpp::invokeGetter_ReturnsValue_WhenValueInheritsIDispatch() +{ + // item(...) takes an argument and is called as a function invocation + MSXML2::IXMLDOMNode *firstChild = m_xml.root->item(0); + QVERIFY(firstChild); +} + +void tst_dumpcpp::propertyGetter_ReturnsValue_WhenValueInheritsIDispatch() +{ + // attributes() takes an argument and is called as property getter + MSXML2::IXMLDOMNamedNodeMap *attributes = m_xml.root->item(0)->attributes(); + QVERIFY(attributes); +} + +void tst_dumpcpp::propertyGetter_ReturnsValue_WhenValueIsString() +{ + MSXML2::IXMLDOMNamedNodeMap *attributes = m_xml.root->item(0)->attributes(); + + // nodeValue is a property getter + QVariant p = attributes->getNamedItem("prop")->nodeValue(); + QCOMPARE(p, "The root property"); +} + +void tst_dumpcpp::propertySetter_SetsValue_WhenValueIsVariantInt() +{ + MSXML2::IXMLDOMNamedNodeMap *attributes = m_xml.root->item(0)->attributes(); + MSXML2::IXMLDOMNode *attribNode = attributes->item(0); + attribNode->setNodeValue(QVariant { 42 } ); + + QVariant p = attributes->getNamedItem("prop")->nodeValue(); + QCOMPARE(p, 42); +} + +void tst_dumpcpp::propertySetter_SetsValue_WhenValueIsString() +{ + m_xml.root->item(0)->setText("The new value"); + QCOMPARE(m_xml.root->item(0)->text(), "The new value"); +} + +void tst_dumpcpp::invoke_SetsValue_WhenValueDerivesFromIDispatch() +{ + MSXML2::IXMLDOMNode *node = m_xml.doc.createNode(MSXML2::NODE_ELEMENT, "sometag", ""); + node->setText("The new text"); + + m_xml.root->item(0)->appendChild(node); + + QCOMPARE(m_xml.root->item(0)->childNodes()->item(1)->text(), "The new text"); +} + QTEST_MAIN(tst_dumpcpp) #include "tst_dumpcpp.moc" diff --git a/tests/auto/qaxobject/CMakeLists.txt b/tests/auto/qaxobject/CMakeLists.txt index 7c07415..87fe2e1 100644 --- a/tests/auto/qaxobject/CMakeLists.txt +++ b/tests/auto/qaxobject/CMakeLists.txt @@ -1,13 +1,20 @@ -# Generated from qaxobject.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### -## qaxobject Test: +## QAxObject Test: ##################################################################### -qt_add_test(qaxobject +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qaxobject LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_test(tst_qaxobject SOURCES tst_qaxobject.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::AxContainer Qt::Gui ) diff --git a/tests/auto/qaxobject/qaxobject.pro b/tests/auto/qaxobject/qaxobject.pro deleted file mode 100644 index e6f51a1..0000000 --- a/tests/auto/qaxobject/qaxobject.pro +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG += testcase -QT += axcontainer testlib -SOURCES += tst_qaxobject.cpp diff --git a/tests/auto/qaxobject/tst_qaxobject.cpp b/tests/auto/qaxobject/tst_qaxobject.cpp index 3955a6c..dfae5f0 100644 --- a/tests/auto/qaxobject/tst_qaxobject.cpp +++ b/tests/auto/qaxobject/tst_qaxobject.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtTest/QtTest> diff --git a/tests/auto/qaxobjectcom/CMakeLists.txt b/tests/auto/qaxobjectcom/CMakeLists.txt new file mode 100644 index 0000000..09ce6a1 --- /dev/null +++ b/tests/auto/qaxobjectcom/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +# Configure the manifest file to point to the com_server dll +# because the dll name is different in debug and release +set(TestServerDll "TestServer${CMAKE_DEBUG_POSTFIX}.dll") +configure_file( + tst_qaxobjectcom.exe.manifest.in + tst_qaxobjectcom.exe.manifest +) + +qt_internal_add_test(tst_qaxobjectcom + SOURCES + tst_qaxobjectcom.cpp + ${CMAKE_CURRENT_BINARY_DIR}/tst_qaxobjectcom.exe.manifest + LIBRARIES + Qt::AxContainer + Qt::CorePrivate + Qt::AxBasePrivate +) + +# Embed the manifest file into the binary for registry free COM +target_link_options(tst_qaxobjectcom PRIVATE "/MANIFEST") + +# Build the com_server automatically +add_subdirectory(testserver) +add_dependencies(tst_qaxobjectcom testserver) + +# Generate qaxobject COM wrapper for our COM test server +qt6_target_typelibs(tst_qaxobjectcom + LIBRARIES + ${CMAKE_CURRENT_BINARY_DIR}/testserver/testserverlib.tlb +) diff --git a/tests/auto/qaxobjectcom/testserver/CMakeLists.txt b/tests/auto/qaxobjectcom/testserver/CMakeLists.txt new file mode 100644 index 0000000..f05ebc0 --- /dev/null +++ b/tests/auto/qaxobjectcom/testserver/CMakeLists.txt @@ -0,0 +1,47 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +# Configure file allow execute_process to detect changes to idl file. +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/testserverlib.idl + ${CMAKE_CURRENT_BINARY_DIR}/testserverlib.idl + COPYONLY +) + +# Run midl at configure time because qt6_target_typelibs checks +# for presence of tlb file at configure time +execute_process( + COMMAND + midl /h testserverlib.h /tlb testserverlib.tlb testserverlib.idl + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND_ERROR_IS_FATAL ANY +) + +qt_add_library(testserver +SHARED + testserver.h + testserver.cpp + testserver.def + testserverlib.idl + testserver.rc +) + +# Trigger rebuild of resources if tlb file changed +set_property( + SOURCE + testserver.rc + PROPERTY + OBJECT_DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/testserverlib.tlb +) + +target_include_directories(testserver + PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} +) + +target_link_libraries(testserver + PRIVATE + Qt::CorePrivate + Qt::AxBasePrivate +) diff --git a/tests/auto/qaxobjectcom/testserver/testserver.cpp b/tests/auto/qaxobjectcom/testserver/testserver.cpp new file mode 100644 index 0000000..1145565 --- /dev/null +++ b/tests/auto/qaxobjectcom/testserver/testserver.cpp @@ -0,0 +1,132 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include <QString> +#include <QUuid> +#include <QtCore/qassert.h> +#include <QtCore/qdebug.h> +#include "testserverlib.h" +#include "testserver.h" + +extern "C" IMAGE_DOS_HEADER __ImageBase; // Trickery to get path to current dll +static long s_serverLock = 0; + +static const std::array<wchar_t, MAX_PATH> GetModuleFilename() +{ + std::array<wchar_t, MAX_PATH> filename; + const DWORD length = GetModuleFileName(reinterpret_cast<HMODULE>(&__ImageBase), filename.data(), + static_cast<DWORD>(filename.size())); + + if (0 == length || filename.size() == length) + return {}; + + return filename; +} + +// Create a dispatcher that implements IDispatch for the input owner +static ComPtr<IUnknown> CreateDispatcher(const QUuid &guid, IUnknown *owner) +{ + ComPtr<ITypeLib> typeLib; + if (LoadTypeLib(GetModuleFilename().data(), &typeLib) != S_OK) + { + qCritical("Failed to load type library"); + return {}; + } + + ComPtr<ITypeInfo> typeInfo; + if (typeLib->GetTypeInfoOfGuid(guid, &typeInfo) + != S_OK) { + qCritical("Failed to get type info"); + return {}; + } + + ComPtr<IUnknown> dispatcher; + if (CreateStdDispatch(owner, owner, typeInfo.Get(), &dispatcher) != S_OK) { + qCritical("Failed to create standard dispatch"); + return {}; + } + + return dispatcher; +} + +TestServer::TestServer() +{ + m_unkDisp = CreateDispatcher(__uuidof(IComServer), this); + ++s_serverLock; +} + +HRESULT __stdcall TestServer::QueryInterface(IID const &id, void **result) +{ + Q_ASSERT(result); + if (id == __uuidof(IDispatch)) { + ComPtr<IDispatch> disp; + m_unkDisp.As(&disp); + *result = disp.Detach(); + return S_OK; + } + return QComObject::QueryInterface(id, result); +} + +HRESULT TestServer::SetObserver(IUnknown* observer) +{ + const ComPtr<IUnknown> rcv{ observer }; + return rcv.As(&m_receiver); +} + +HRESULT TestServer::VariantIn(VARIANT v) +{ + return m_receiver->VariantIn(v); +} + +struct Factory : IClassFactory +{ + ULONG __stdcall AddRef() override { return 2; } + ULONG __stdcall Release() override { return 1; } + HRESULT __stdcall QueryInterface(IID const &id, void **result) override + { + Q_ASSERT(result); + + if (id == __uuidof(IClassFactory) || id == __uuidof(IUnknown)) { + *result = static_cast<IClassFactory *>(this); + return S_OK; + } + + *result = nullptr; + return E_NOINTERFACE; + } + + HRESULT __stdcall CreateInstance(IUnknown *outer, IID const &iid, void **result) override + { + Q_ASSERT(result); + Q_ASSERT(!outer); + + const ComPtr<TestServer> server{ new (std::nothrow) TestServer }; + return server->QueryInterface(iid, result); + } + + HRESULT __stdcall LockServer(BOOL lock) override + { + if (lock) + ++s_serverLock; + else + --s_serverLock; + + return S_OK; + } +}; + +HRESULT __stdcall DllGetClassObject(CLSID const &clsid, IID const &iid, void **result) +{ + if (__uuidof(TestServer) == clsid) { + static Factory farm; + + return farm.QueryInterface(iid, result); + } + + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT __stdcall DllCanUnloadNow() +{ + return s_serverLock ? S_FALSE : S_OK; +} diff --git a/tests/auto/qaxobjectcom/testserver/testserver.def b/tests/auto/qaxobjectcom/testserver/testserver.def new file mode 100644 index 0000000..56e1a71 --- /dev/null +++ b/tests/auto/qaxobjectcom/testserver/testserver.def @@ -0,0 +1,3 @@ +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE diff --git a/tests/auto/qaxobjectcom/testserver/testserver.h b/tests/auto/qaxobjectcom/testserver/testserver.h new file mode 100644 index 0000000..53663ef --- /dev/null +++ b/tests/auto/qaxobjectcom/testserver/testserver.h @@ -0,0 +1,43 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#ifndef TEST_SERVER_H +#define TEST_SERVER_H + +#include <qt_windows.h> +#include "testserverlib.h" +#include <wrl/client.h> +#include <QtCore/private/qcomobject_p.h> +#include "../../conversion/comutil_p.h" + +using Microsoft::WRL::ComPtr; + +class __declspec(uuid("af732aba-95cf-4ee7-bd59-8f946b7f82e3")) +TestServer : public QComObject<IComServer> +{ +public: + TestServer(); + + HRESULT __stdcall QueryInterface(IID const &id, void **result) override; + HRESULT __stdcall SetObserver(IUnknown *observer) override; + HRESULT __stdcall VariantIn(VARIANT v) override; + +private: + ComPtr<IUnknown> m_unkDisp; + ComPtr<IComServer> m_receiver; +}; + +struct Receiver : public QComObject<IComServer> +{ + HRESULT SetObserver(IUnknown *observer) override { return E_NOTIMPL; } + + HRESULT VariantIn(VARIANT arg) override + { + lastArg = ComVariant{ arg }; + return S_OK; + } + + ComVariant lastArg{}; +}; + +#endif diff --git a/tests/auto/qaxobjectcom/testserver/testserver.rc b/tests/auto/qaxobjectcom/testserver/testserver.rc new file mode 100644 index 0000000..51dfeed --- /dev/null +++ b/tests/auto/qaxobjectcom/testserver/testserver.rc @@ -0,0 +1 @@ +1 TYPELIB "testserverlib.tlb" diff --git a/tests/auto/qaxobjectcom/testserver/testserverlib.idl b/tests/auto/qaxobjectcom/testserver/testserverlib.idl new file mode 100644 index 0000000..00d64ab --- /dev/null +++ b/tests/auto/qaxobjectcom/testserver/testserverlib.idl @@ -0,0 +1,33 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import "oaidl.idl"; +import "ocidl.idl"; + +[ + object, + dual, + uuid(f4811a11-3092-415e-a473-38c627544246), + oleautomation, + pointer_default(unique) +] +interface IComServer : IUnknown +{ + HRESULT SetObserver([in] IUnknown *observer); + HRESULT VariantIn([in] VARIANT arg); +}; + +[ + uuid(104d435f-7504-4786-aae7-b22745450c4c), + version(1.0), +] +library ComServerLib +{ + [ + uuid(af732aba-95cf-4ee7-bd59-8f946b7f82e3), + ] + coclass TestServer + { + interface IComServer; + }; +}; diff --git a/tests/auto/qaxobjectcom/tst_qaxobjectcom.cpp b/tests/auto/qaxobjectcom/tst_qaxobjectcom.cpp new file mode 100644 index 0000000..fec1d8d --- /dev/null +++ b/tests/auto/qaxobjectcom/tst_qaxobjectcom.cpp @@ -0,0 +1,87 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include <QtTest/QtTest> +#include "testserverlib.h" +#include <testserver/testserverlib.h> +#include "testserver/testserver.h" +#include "../conversion/comutil_p.h" +#include <QtAxBase/private/qbstr_p.h> + +class tst_qaxobjectcom : public QObject +{ + Q_OBJECT +private slots: + void comObject_receivesVARIANT_whenCalledWithQVariant_data() + { + QTest::addColumn<QVariant>("value"); + QTest::addColumn<ComVariant>("expected"); + + QTest::addRow("bool") << QVariant{ true } << ComVariant{ VARIANT_TRUE }; + QTest::addRow("short") << QVariant{ static_cast<short>(3) } << ComVariant{ static_cast<int>(3) }; // TODO: Fixme + QTest::addRow("unsigned short") << QVariant{ static_cast<ushort>(3) } << ComVariant{ static_cast<int>(3) }; // TODO: Fixme + QTest::addRow("int") << QVariant{ 3 } << ComVariant{ 3 }; + QTest::addRow("unsigned int") << QVariant{ 3u } << ComVariant{ 3u }; + QTest::addRow("long long") << QVariant{ 3ll } << ComVariant{ 3ll }; + QTest::addRow("unsigned long long") << QVariant{ 3ull } << ComVariant{ 3ull }; + QTest::addRow("float") << QVariant{ 3.3f } << ComVariant{ 3.3f }; + QTest::addRow("double") << QVariant{ 3.3 } << ComVariant{ 3.3 }; + } + + void comObject_receivesVARIANT_whenCalledWithQVariant() + { + QFETCH(const QVariant, value); + QFETCH(const ComVariant, expected); + + // Arrange + ComServerLib::TestServer server; + const ComPtr<Receiver> observer = makeComObject<Receiver>(); + server.SetObserver(observer.Get()); + + // Act + server.VariantIn(value); + + // Assert + QCOMPARE_EQ(observer->lastArg, expected); + } + + void comObject_receivesVARIANT_whenCalledWithVariantStringList() + { + const QVariant value{ QList{ QVariant{ "A" }, QVariant{ "BC" } } }; + + // Arrange + ComServerLib::TestServer server; + const ComPtr<Receiver> observer = makeComObject<Receiver>(); + server.SetObserver(observer.Get()); + + // Act + server.VariantIn(value); + + // Assert + QVERIFY(V_ISARRAY(&observer->lastArg)); + + LPSAFEARRAY safeArray = V_ARRAY(&observer->lastArg); + + VARTYPE itemType; + if (SUCCEEDED(SafeArrayGetVartype(safeArray, &itemType))) + + QCOMPARE_EQ(itemType, VT_VARIANT); + + LPVOID data; + QCOMPARE_EQ(SafeArrayAccessData(safeArray, &data), S_OK); + + const auto *pItems = static_cast<const VARIANT*>(data); + ComVariant item1{ pItems[0] }; + ComVariant item2{ pItems[1] }; + + QCOMPARE_EQ(item1, ComVariant{ QBStr{ L"A" } }); + QCOMPARE_EQ(item2, ComVariant{ QBStr{ L"BC" } }); + + // end accessing data + QCOMPARE_EQ(SafeArrayUnaccessData(safeArray), S_OK); + + } +}; + +QTEST_MAIN(tst_qaxobjectcom) +#include "tst_qaxobjectcom.moc" diff --git a/tests/auto/qaxobjectcom/tst_qaxobjectcom.exe.manifest.in b/tests/auto/qaxobjectcom/tst_qaxobjectcom.exe.manifest.in new file mode 100644 index 0000000..7d6ef11 --- /dev/null +++ b/tests/auto/qaxobjectcom/tst_qaxobjectcom.exe.manifest.in @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1"> + <assemblyIdentity version="1.0.0.0" name="tst_qaxobjectcom.app"/> + <file name="testserver/${TestServerDll}"> + <comClass + description="Com Server" + clsid="{af732aba-95cf-4ee7-bd59-8f946b7f82e3}" + progid="Qt.TestServer" + threadingModel = "Both" + /> + </file> +</assembly> diff --git a/tests/auto/qaxscript/CMakeLists.txt b/tests/auto/qaxscript/CMakeLists.txt index 4312217..351ab2f 100644 --- a/tests/auto/qaxscript/CMakeLists.txt +++ b/tests/auto/qaxscript/CMakeLists.txt @@ -1,12 +1,19 @@ -# Generated from qaxscript.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### -## qaxscript Test: +## tst_QAxScript Test: ##################################################################### -qt_add_test(qaxscript +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qaxscript LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_test(tst_qaxscript SOURCES tst_qaxscript.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::AxContainer ) diff --git a/tests/auto/qaxscript/qaxscript.pro b/tests/auto/qaxscript/qaxscript.pro deleted file mode 100644 index 704b2cd..0000000 --- a/tests/auto/qaxscript/qaxscript.pro +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG += testcase -QT = core axcontainer testlib -SOURCES += tst_qaxscript.cpp diff --git a/tests/auto/qaxscript/tst_qaxscript.cpp b/tests/auto/qaxscript/tst_qaxscript.cpp index 3b3ab88..1eb4258 100644 --- a/tests/auto/qaxscript/tst_qaxscript.cpp +++ b/tests/auto/qaxscript/tst_qaxscript.cpp @@ -1,57 +1,162 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtTest/QtTest> #include <QAxScriptManager> #include <QAxScript> +using namespace Qt::StringLiterals; + class tst_QAxScript : public QObject { Q_OBJECT private slots: + void call(); void scriptReturnValue(); + void scriptOutParameters(); + void error_data(); + void error(); }; +void tst_QAxScript::call() +{ + QAxScriptManager scriptManager; + const auto scriptCode_js = uR"JS( + function test1() { + return 'JScript'; + } + )JS"_s; + const auto scriptCode_vb = uR"VB( + Function test2() + test2 = "VBScript" + End Function + )VB"_s; + QAxScript *jsscript = scriptManager.load(scriptCode_js, u"JS"_s, u"JScript"_s); + QVERIFY2(jsscript, "Unable to load script (CoInitializeEx() called?)"); + QVERIFY(jsscript->scriptEngine()->hasIntrospection()); + QAxScript *vbscript = scriptManager.load(scriptCode_vb, u"VB"_s, u"VBScript"_s); + QVERIFY2(vbscript, "Unable to load script (CoInitializeEx() called?)"); + QVERIFY(vbscript->scriptEngine()->hasIntrospection()); + + QCOMPARE(jsscript->call("test1()"), "JScript"); + QTest::ignoreMessage(QtWarningMsg, "QAxBase::dynamicCallHelper: test1(): No such method in [unknown]"); + QTest::ignoreMessage(QtWarningMsg, "\tCandidates are:"); + QCOMPARE(vbscript->call("test1()"), QVariant()); + QCOMPARE(vbscript->call("test2()"), "VBScript"); + QTest::ignoreMessage(QtWarningMsg, "QAxBase::dynamicCallHelper: test2(): No such method in [unknown]"); + QTest::ignoreMessage(QtWarningMsg, "\tCandidates are:"); + QCOMPARE(jsscript->call("test2()"), QVariant()); +} + void tst_QAxScript::scriptReturnValue() { QAxScriptManager scriptManager; - const char scriptCode[] = - "function foo() {\n" - " return 'test';\n" - "}\n"; // QTBUG-42289, fails when DISPATCH_PROPERTYGET is used. - QAxScript *script = scriptManager.load(QLatin1String(scriptCode), - QStringLiteral("Test"), - QStringLiteral("JScript")); + const auto scriptCode = uR"JS( + function foo() { + return 'test'; + } + )JS"_s; // QTBUG-42289, fails when DISPATCH_PROPERTYGET is used. + QAxScript *script = scriptManager.load(scriptCode, u"Test"_s, u"JScript"_s); QVERIFY2(script, "Unable to load script (CoInitializeEx() called?)"); const QVariant result = script->call("foo()"); - QCOMPARE(result, QVariant(QStringLiteral("test"))); + QCOMPARE(result, QVariant(u"test"_s)); +} + +void tst_QAxScript::scriptOutParameters() +{ + QAxScriptManager scriptManager; + const auto scriptCode = uR"VB( + Function GetProductName(ByRef manufacturer, ByRef name, ByRef version) + manufacturer = "The Qt Company" + name = "ActiveQt" + version = 650 + On Error Resume Next + GetProductName = 42 + End Function + )VB"_s; + + QAxScript *script = scriptManager.load(scriptCode, u"Test"_s, u"VBScript"_s); + QVERIFY2(script, "Unable to load script (CoInitializeEx() called?)"); + + QVariant returnValue; + QList<QVariant> results = {{}, {}, {}}; + + returnValue = script->scriptEngine()->dynamicCall("GetProductName(QVariant&,QVariant&,QVariant&)", results); + QCOMPARE(returnValue, 42); + QCOMPARE(results.size(), 3); + QCOMPARE(results.at(0), "The Qt Company"); + QCOMPARE(results.at(1), "ActiveQt"); + QCOMPARE(results.at(2), 650); + + results = {{}, {}, {}}; + returnValue = script->call("GetProductName(QVariant&,QVariant&,QVariant&)", results); + QCOMPARE(returnValue, 42); + QCOMPARE(results.size(), 3); + QCOMPARE(results.at(0), "The Qt Company"); + QCOMPARE(results.at(1), "ActiveQt"); + QCOMPARE(results.at(2), 650); +} + +void tst_QAxScript::error_data() +{ + QTest::addColumn<QString>("scriptCode"); + QTest::addColumn<QString>("language"); + QTest::addColumn<int>("expectedErrorCode"); + QTest::addColumn<QString>("expectedDescription"); + QTest::addColumn<int>("expectedSourcePosition"); + QTest::addColumn<QString>("expectedSourceText"); + + QTest::addRow("JS syntax error") + << "function foo {}" + << "JScript" + << 0 << "Expected '('" << 0 << "function foo {}"; + + QTest::addRow("VB syntax error") + << "Funktion test" + << "VBScript" + << 0 << "Type mismatch: 'Funktion'" << 0 << ""; +} + +void tst_QAxScript::error() +{ + QFETCH(QString, scriptCode); + QFETCH(QString, language); + QFETCH(int, expectedErrorCode); + QFETCH(QString, expectedDescription); + QFETCH(int, expectedSourcePosition); + QFETCH(QString, expectedSourceText); + + QAxScriptManager scriptManager; + QAxScript script(u"Test"_s, &scriptManager); + + QAxScript *actualScript = nullptr; + int actualCode; + QString actualDescription; + int actualSourcePosition; + QString actualSourceText; + + connect(&scriptManager, &QAxScriptManager::error, + this, [&](QAxScript *script){ + actualScript = script; + }); + + connect(&script, &QAxScript::error, + this, [&](int code, const QString &description, int sourcePosition, const QString &sourceText){ + actualCode = code; + actualDescription = description; + actualSourcePosition = sourcePosition; + actualSourceText = sourceText.trimmed(); + }); + + script.load(scriptCode, language); + + QCOMPARE(actualScript, &script); + QCOMPARE(actualCode, expectedErrorCode); + QCOMPARE(actualDescription, expectedDescription); + QCOMPARE(actualSourcePosition, expectedSourcePosition); + QCOMPARE(actualSourceText, expectedSourceText); } QTEST_MAIN(tst_QAxScript) diff --git a/tests/auto/qaxscriptmanager/CMakeLists.txt b/tests/auto/qaxscriptmanager/CMakeLists.txt new file mode 100644 index 0000000..37b83ab --- /dev/null +++ b/tests/auto/qaxscriptmanager/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## QAxScriptManager Test: +##################################################################### + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qaxscriptmanager LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_test(tst_qaxscriptmanager + SOURCES + tst_qaxscriptmanager.cpp + LIBRARIES + Qt::AxContainer +) diff --git a/tests/auto/qaxscriptmanager/tst_qaxscriptmanager.cpp b/tests/auto/qaxscriptmanager/tst_qaxscriptmanager.cpp new file mode 100644 index 0000000..9ecb7c2 --- /dev/null +++ b/tests/auto/qaxscriptmanager/tst_qaxscriptmanager.cpp @@ -0,0 +1,188 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + + +#include <QtTest/QtTest> +#include <QAxScriptManager> +#include <QAxScript> + +using namespace Qt::StringLiterals; + +class tst_QAxScriptManager : public QObject +{ + Q_OBJECT + +public: + struct Script { + QString language; + QString name; + QString code; + }; + +private slots: + void functions_data(); + void functions(); + + void scriptNames_data(); + void scriptNames(); + + void script_data(); + void script(); + + void call_data(); + void call(); +}; + +void tst_QAxScriptManager::functions_data() +{ + const auto scriptCode_js = Script{u"JScript"_s, u"test1"_s, uR"JS( + function js1() { + return 'JScript 1'; + } + function js2(value) { + return 'JScript 2'; + } + )JS"_s}; + const auto scriptCode_vb = Script{u"VBScript"_s, u"test2"_s, uR"VB( + Function vb1() + vb1 = "VBScript 1" + End Function + + Function vb2(value) + vb2 = "VBScript 2" + End Function + )VB"_s}; + + QTest::addColumn<QList<Script>>("scripts"); + QTest::addColumn<QStringList>("functions"); + QTest::addColumn<QStringList>("signatures"); + + QTest::addRow("js") << QList{scriptCode_js} + << QStringList{"js1", "js2"} + << QStringList{"js1()", "js2(QVariant)"}; + QTest::addRow("vb") << QList{scriptCode_vb} + << QStringList{"vb1", "vb2"} + << QStringList{"vb1()", "vb2(QVariant)"}; + QTest::addRow("both") << QList{scriptCode_js, scriptCode_vb} + << QStringList{"js1", "js2", "vb1", "vb2"} + << QStringList{"js1()", "js2(QVariant)", "vb1()", "vb2(QVariant)"}; +} + +void tst_QAxScriptManager::functions() +{ + // QStringList functions(QAxScript::FunctionFlags = QAxScript::FunctionNames) const; + + QFETCH(QList<Script>, scripts); + QFETCH(QStringList, functions); + QFETCH(QStringList, signatures); + + QAxScriptManager scriptManager; + for (const auto &script : scripts) { + QVERIFY2(scriptManager.load(script.code, script.name, script.language), + "Unable to load script (CoInitializeEx() called?)"); + } + functions.sort(); + QStringList actualFunctions = scriptManager.functions(); + actualFunctions.sort(); + QCOMPARE(actualFunctions, functions); + + QStringList actualSignatures = scriptManager.functions(QAxScript::FunctionSignatures); + actualSignatures.sort(); + QCOMPARE(actualSignatures, signatures); +} + +void tst_QAxScriptManager::scriptNames_data() +{ + functions_data(); +} + +void tst_QAxScriptManager::scriptNames() +{ + // QStringList scriptNames() const; + QFETCH(QList<Script>, scripts); + QFETCH(QStringList, functions); + + QAxScriptManager scriptManager; + QStringList expectedNames; + for (const auto &script : scripts) { + expectedNames << script.name; + QVERIFY2(scriptManager.load(script.code, script.name, script.language), + "Unable to load script (CoInitializeEx() called?)"); + } + expectedNames.sort(); + QStringList actualNames = scriptManager.scriptNames(); + actualNames.sort(); + QCOMPARE(actualNames, expectedNames); +} + +void tst_QAxScriptManager::script_data() +{ + functions_data(); +} + +void tst_QAxScriptManager::script() +{ + QFETCH(QList<Script>, scripts); + QFETCH(QStringList, functions); + + QAxScriptManager scriptManager; + QStringList expectedNames; + for (const auto &script : scripts) { + expectedNames << script.name; + QVERIFY2(scriptManager.load(script.code, script.name, script.language), + "Unable to load script (CoInitializeEx() called?)"); + } + + for (const auto &script : scripts) { + QAxScript *axscript = scriptManager.script(script.name); + QVERIFY(axscript); + QVERIFY(axscript->scriptEngine()); + QVERIFY(axscript->scriptEngine()->isValid()); + const auto scriptFunctions = axscript->functions(); + for (const auto &scriptFunction : scriptFunctions) { + auto index = functions.indexOf(scriptFunction); + QCOMPARE_NE(index, -1); + functions.remove(index); + } + + QCOMPARE(axscript->scriptEngine()->scriptLanguage(), script.language); + } + + // verify that all functions were found across the different QAxScript objects + QVERIFY(functions.isEmpty()); +} + +void tst_QAxScriptManager::call_data() +{ + functions_data(); +} + +void tst_QAxScriptManager::call() +{ + QFETCH(QList<Script>, scripts); + QFETCH(QStringList, functions); + QFETCH(QStringList, signatures); + + QAxScriptManager scriptManager; + for (const auto &script : scripts) { + QAxScript *axScript = scriptManager.load(script.code, script.name, script.language); + + QVERIFY2(axScript, "Unable to load script (CoInitializeEx() called?)"); + QVERIFY(axScript->scriptEngine()); + QVERIFY(axScript->scriptEngine()->hasIntrospection()); + } + + // QAxScriptManager::call finds the script based on function name... + for (const auto &function : std::as_const(functions)) { + QVariant result = scriptManager.call(function); + QCOMPARE(result.metaType(), QMetaType::fromType<QString>()); + } + // ...or fully qualified function signature + for (const auto &function : std::as_const(signatures)) { + QVariant result = scriptManager.call(function); + QCOMPARE(result.metaType(), QMetaType::fromType<QString>()); + } +} + +QTEST_MAIN(tst_QAxScriptManager) +#include "tst_qaxscriptmanager.moc" diff --git a/tests/auto/qbstr/CMakeLists.txt b/tests/auto/qbstr/CMakeLists.txt new file mode 100644 index 0000000..65a49a6 --- /dev/null +++ b/tests/auto/qbstr/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qbstr LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +qt_internal_add_test(tst_qbstr + SOURCES + tst_qbstr.cpp + LIBRARIES + Qt::AxBasePrivate +) diff --git a/tests/auto/qbstr/tst_qbstr.cpp b/tests/auto/qbstr/tst_qbstr.cpp new file mode 100644 index 0000000..3a757f6 --- /dev/null +++ b/tests/auto/qbstr/tst_qbstr.cpp @@ -0,0 +1,138 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include <QtTest/QtTest> +#include <QtAxBase/private/qbstr_p.h> + +QT_USE_NAMESPACE + +using namespace Qt::StringLiterals; + +typedef int (*SETOANOCACHE)(void); + +void DisableBSTRCache() +{ + const HINSTANCE hLib = LoadLibraryA("OLEAUT32.DLL"); + if (hLib != nullptr) { + const SETOANOCACHE SetOaNoCache = + reinterpret_cast<SETOANOCACHE>(GetProcAddress(hLib, "SetOaNoCache")); + if (SetOaNoCache != nullptr) + SetOaNoCache(); + FreeLibrary(hLib); + } +} + +class tst_qbstr : public QObject +{ + Q_OBJECT +private slots: + void initTestCase() { DisableBSTRCache(); } + void constructor_nullInitializes() + { + const QBStr str; + QVERIFY(!str.bstr()); + } + + void constructor_initializes_withLiteral() + { + const QBStr str{ L"hello world" }; + QCOMPARE_EQ(str.bstr(), "hello world"_L1); + } + + void constructor_initializes_withQString() + { + const QString expected{ "hello world"_L1 }; + QBStr str{ expected }; + QCOMPARE_EQ(QStringView{ str.bstr() }, expected); + } + + void copyConstructor_initializes_withNullString() + { + const QBStr null; + const QBStr dest = null; + QCOMPARE_EQ(dest.bstr(), nullptr); + } + + void copyConstructor_initializes_withValidString() + { + const QBStr expected{ L"hello world" }; + const QBStr dest = expected; + QCOMPARE_EQ(QStringView{ dest.bstr() }, expected.bstr()); + } + + void moveConstructor_initializes_withNullString() + { + const QBStr str{ QBStr{} }; + QCOMPARE_EQ(str.bstr(), nullptr); + } + + void moveConstructor_initializes_withValidString() + { + QBStr source { L"hello world" }; + const QBStr str{ std::move(source) }; + QCOMPARE_EQ(str.bstr(), "hello world"_L1); + } + + void assignment_assigns_withNullString() + { + const QBStr source{}; + const QBStr dest = source; + QCOMPARE_EQ(dest.bstr(), nullptr); + } + + void assignment_assigns_withValidString() + { + const QBStr source{ L"hello world" }; + const QBStr dest = source; + QCOMPARE_EQ(dest.bstr(), "hello world"_L1); + } + + void moveAssignment_assigns_withNullString() + { + QBStr source{}; + const QBStr dest = std::move(source); + QCOMPARE_EQ(dest.bstr(), nullptr); + } + + void moveAssignment_assigns_withValidString() + { + QBStr source{ L"hello world" }; + const QBStr dest = std::move(source); + QCOMPARE_EQ(dest.bstr(), "hello world"_L1); + } + + void release_returnsStringAndClearsValue() + { + QBStr str{ L"hello world" }; + BSTR val = str.release(); + QCOMPARE_EQ(str.bstr(), nullptr); + QCOMPARE_EQ(val, "hello world"_L1); + SysFreeString(val); + } + + void str_returnsQString_withNullString() + { + const QBStr bstr{}; + const QString str = bstr.str(); + QVERIFY(str.isEmpty()); + } + + void str_returnsQString_withValidString() + { + const QBStr bstr{L"hello world"}; + const QString str = bstr.str(); + QCOMPARE_EQ(str, "hello world"); + } + + void operatorBool_returnsFalse_withNullString() { + QVERIFY(!QBStr{}); + } + + void operatorBool_returnsTrue_withValidString() + { + QVERIFY(QBStr{ "hello world" }); + } +}; + +QTEST_MAIN(tst_qbstr) +#include "tst_qbstr.moc" diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt index 048232d..f911543 100644 --- a/tests/manual/CMakeLists.txt +++ b/tests/manual/CMakeLists.txt @@ -1,5 +1,11 @@ -# Generated from manual.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause add_subdirectory(axviewer) add_subdirectory(dumpcpp) +add_subdirectory(hierarchy) +add_subdirectory(mediaplayer) +add_subdirectory(menus) +add_subdirectory(multiple) +add_subdirectory(opengl) add_subdirectory(testcontrol) diff --git a/tests/manual/axviewer/.prev_CMakeLists.txt b/tests/manual/axviewer/.prev_CMakeLists.txt deleted file mode 100644 index 8864fee..0000000 --- a/tests/manual/axviewer/.prev_CMakeLists.txt +++ /dev/null @@ -1,69 +0,0 @@ -# Generated from axviewer.pro. - -##################################################################### -## axviewer Binary: -##################################################################### - -qt_add_executable(axviewer - SOURCES - ../shared/metaobjectdump.cpp ../shared/metaobjectdump.h - ../shared/textdialog.cpp ../shared/textdialog.h - main.cpp - INCLUDE_DIRECTORIES - ../shared - PUBLIC_LIBRARIES - Qt::AxContainer - Qt::Gui - Qt::Widgets -) - -#### Keys ignored in scope 1:.:.:axviewer.pro:<TRUE>: -# DIAGLIB = "../../../../qtbase/tests/manual/diaglib" -# TEMPLATE = "app" - -## Scopes: -##################################################################### - -qt_extend_target(axviewer CONDITION EXISTS _ss_DIAGLIB - SOURCES - ../../../../qtbase/tests/manual/diaglib/eventfilter.cpp ../../../../qtbase/tests/manual/diaglib/eventfilter.h - ../../../../qtbase/tests/manual/diaglib/nativewindowdump.h - ../../../../qtbase/tests/manual/diaglib/qwindowdump.cpp ../../../../qtbase/tests/manual/diaglib/qwindowdump.h - ../../../../qtbase/tests/manual/diaglib/textdump.cpp ../../../../qtbase/tests/manual/diaglib/textdump.h - DEFINES - QT_DIAG_LIB - INCLUDE_DIRECTORIES - ../../../../qtbase/tests/manual/diaglib - PUBLIC_LIBRARIES - Qt::CorePrivate - Qt::GuiPrivate -) - -qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (WIN32) - SOURCES - ../../../../qtbase/tests/manual/diaglib/nativewindowdump_win.cpp - PUBLIC_LIBRARIES - user32 -) - -qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (NOT (WIN32)) - SOURCES - ../../../../qtbase/tests/manual/diaglib/nativewindowdump.cpp -) - -qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (QT_FEATURE_widgets) - SOURCES - ../../../../qtbase/tests/manual/diaglib/debugproxystyle.cpp ../../../../qtbase/tests/manual/diaglib/debugproxystyle.h - ../../../../qtbase/tests/manual/diaglib/logwidget.cpp ../../../../qtbase/tests/manual/diaglib/logwidget.h - ../../../../qtbase/tests/manual/diaglib/qwidgetdump.cpp ../../../../qtbase/tests/manual/diaglib/qwidgetdump.h - PUBLIC_LIBRARIES - Qt::WidgetsPrivate -) - -qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (QT_FEATURE_opengl) - SOURCES - ../../../../qtbase/tests/manual/diaglib/glinfo.cpp ../../../../qtbase/tests/manual/diaglib/glinfo.h - PUBLIC_LIBRARIES - Qt::OpenGL - Qt::OpenGLWidgets -) diff --git a/tests/manual/axviewer/CMakeLists.txt b/tests/manual/axviewer/CMakeLists.txt index f34e32c..22f8f3a 100644 --- a/tests/manual/axviewer/CMakeLists.txt +++ b/tests/manual/axviewer/CMakeLists.txt @@ -1,70 +1,70 @@ -# Generated from axviewer.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + ##################################################################### ## axviewer Binary: ##################################################################### -# qt_add_executable(axviewer # special case -qt_add_manual_test(axviewer # special case +qt_internal_add_manual_test(tst_axviewer_manual SOURCES ../shared/metaobjectdump.cpp ../shared/metaobjectdump.h ../shared/textdialog.cpp ../shared/textdialog.h main.cpp INCLUDE_DIRECTORIES ../shared - PUBLIC_LIBRARIES + LIBRARIES Qt::AxContainer Qt::Gui Qt::Widgets ) -#### Keys ignored in scope 1:.:.:axviewer.pro:<TRUE>: -# DIAGLIB = "../../../../qtbase/tests/manual/diaglib" -# TEMPLATE = "app" - ## Scopes: ##################################################################### -qt_extend_target(axviewer CONDITION EXISTS _ss_DIAGLIB +set(diaglib_path "${CMAKE_CURRENT_SOURCE_DIR}/../../../../qtbase/tests/manual/diaglib") +qt_internal_extend_target(tst_axviewer_manual CONDITION EXISTS "${diaglib_path}" SOURCES - ../../../../qtbase/tests/manual/diaglib/eventfilter.cpp ../../../../qtbase/tests/manual/diaglib/eventfilter.h - ../../../../qtbase/tests/manual/diaglib/nativewindowdump.h - ../../../../qtbase/tests/manual/diaglib/qwindowdump.cpp ../../../../qtbase/tests/manual/diaglib/qwindowdump.h - ../../../../qtbase/tests/manual/diaglib/textdump.cpp ../../../../qtbase/tests/manual/diaglib/textdump.h + "${diaglib_path}/eventfilter.cpp" "${diaglib_path}/eventfilter.h" + "${diaglib_path}/nativewindowdump.h" + "${diaglib_path}/qwindowdump.cpp" "${diaglib_path}/qwindowdump.h" + "${diaglib_path}/textdump.cpp" "${diaglib_path}/textdump.h" DEFINES QT_DIAG_LIB INCLUDE_DIRECTORIES - ../../../../qtbase/tests/manual/diaglib - PUBLIC_LIBRARIES + "${diaglib_path}" + LIBRARIES Qt::CorePrivate Qt::GuiPrivate ) -qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (WIN32) +qt_internal_extend_target(tst_axviewer_manual CONDITION (EXISTS "${diaglib_path}") AND (WIN32) SOURCES - ../../../../qtbase/tests/manual/diaglib/nativewindowdump_win.cpp - PUBLIC_LIBRARIES + "${diaglib_path}/nativewindowdump_win.cpp" + LIBRARIES user32 ) -qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (NOT (WIN32)) +qt_internal_extend_target(tst_axviewer_manual CONDITION (EXISTS "${diaglib_path}") AND (NOT (WIN32)) SOURCES - ../../../../qtbase/tests/manual/diaglib/nativewindowdump.cpp + "${diaglib_path}/nativewindowdump.cpp" ) -qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (QT_FEATURE_widgets) +qt_internal_extend_target(tst_axviewer_manual CONDITION (EXISTS "${diaglib_path}") AND + TARGET Qt::Widgets SOURCES - ../../../../qtbase/tests/manual/diaglib/debugproxystyle.cpp ../../../../qtbase/tests/manual/diaglib/debugproxystyle.h - ../../../../qtbase/tests/manual/diaglib/logwidget.cpp ../../../../qtbase/tests/manual/diaglib/logwidget.h - ../../../../qtbase/tests/manual/diaglib/qwidgetdump.cpp ../../../../qtbase/tests/manual/diaglib/qwidgetdump.h - PUBLIC_LIBRARIES + "${diaglib_path}/debugproxystyle.cpp" "${diaglib_path}/debugproxystyle.h" + "${diaglib_path}/logwidget.cpp" "${diaglib_path}/logwidget.h" + "${diaglib_path}/qwidgetdump.cpp" "${diaglib_path}/qwidgetdump.h" + LIBRARIES Qt::WidgetsPrivate ) -qt_extend_target(axviewer CONDITION (EXISTS _ss_DIAGLIB) AND (QT_FEATURE_opengl) +qt_internal_extend_target(tst_axviewer_manual CONDITION (EXISTS "${diaglib_path}") AND + TARGET Qt::OpenGL AND TARGET Qt::OpenGLWidgets SOURCES - ../../../../qtbase/tests/manual/diaglib/glinfo.cpp ../../../../qtbase/tests/manual/diaglib/glinfo.h - PUBLIC_LIBRARIES + "${diaglib_path}/glinfo.cpp" "${diaglib_path}/glinfo.h" + LIBRARIES Qt::OpenGL Qt::OpenGLWidgets ) diff --git a/tests/manual/axviewer/axviewer.pro b/tests/manual/axviewer/axviewer.pro deleted file mode 100644 index a609e49..0000000 --- a/tests/manual/axviewer/axviewer.pro +++ /dev/null @@ -1,9 +0,0 @@ -TEMPLATE = app -QT = core gui widgets axcontainer -CONFIG += console c++11 - -SOURCES += main.cpp -include(../shared/shared.pri) - -DIAGLIB = ../../../../qtbase/tests/manual/diaglib -exists($$DIAGLIB):include($$DIAGLIB/diaglib.pri) diff --git a/tests/manual/axviewer/main.cpp b/tests/manual/axviewer/main.cpp index 29ad3dc..f7ee6ed 100644 --- a/tests/manual/axviewer/main.cpp +++ b/tests/manual/axviewer/main.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "metaobjectdump.h" #include "textdialog.h" @@ -148,8 +123,6 @@ void MainWindow::showMetaObject() int main(int argc, char* argv[]) { - if (isOptionSet(argc, argv, "-s")) - QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); if (!isOptionSet(argc, argv, "-n")) QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); @@ -161,9 +134,6 @@ int main(int argc, char* argv[]) parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); parser.addHelpOption(); parser.addVersionOption(); - QCommandLineOption noScalingDummy(QStringLiteral("s"), - QStringLiteral("Set Qt::AA_DisableHighDpiScaling.")); - parser.addOption(noScalingDummy); QCommandLineOption nativeSiblingsDummy(QStringLiteral("n"), QStringLiteral("Do not set Qt::AA_DontCreateNativeWidgetSiblings.")); parser.addOption(nativeSiblingsDummy); diff --git a/tests/manual/dumpcpp/CMakeLists.txt b/tests/manual/dumpcpp/CMakeLists.txt index bc681d9..e9ffc1a 100644 --- a/tests/manual/dumpcpp/CMakeLists.txt +++ b/tests/manual/dumpcpp/CMakeLists.txt @@ -1,26 +1,22 @@ -# Generated from dumpcpp.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## dumpcpp Binary: ##################################################################### -qt_add_executable(dumpcpp +qt_internal_add_manual_test(tst_dumpcpp_manual SOURCES ../shared/metaobjectdump.cpp ../shared/metaobjectdump.h ../shared/textdialog.cpp ../shared/textdialog.h main.cpp INCLUDE_DIRECTORIES ../shared - PUBLIC_LIBRARIES + LIBRARIES Qt::AxContainer Qt::Gui Qt::Test Qt::Widgets ) -#### Keys ignored in scope 1:.:.:dumpcpp.pro:<TRUE>: -# TEMPLATE = "app" -# TYPELIBS = "$$(SystemRoot)\\system32\\ieframe.dll" - -## Scopes: -##################################################################### +qt6_target_typelibs(tst_dumpcpp_manual LIBRARIES "ieframe.dll") diff --git a/tests/manual/dumpcpp/dumpcpp.pro b/tests/manual/dumpcpp/dumpcpp.pro deleted file mode 100644 index 6f116c0..0000000 --- a/tests/manual/dumpcpp/dumpcpp.pro +++ /dev/null @@ -1,13 +0,0 @@ -TEMPLATE=app -CONFIG += QMAKE_LFLAGS_CONSOLE -QT += widgets axcontainer testlib - -SOURCES += main.cpp -include(../shared/shared.pri) - -# Assume Web Browser type library is available in all windows installations -TYPELIBS = $$(SystemRoot)\\system32\\ieframe.dll - -!exists($$TYPELIBS) { - message("Web Browser type library for test not found!") -} diff --git a/tests/manual/dumpcpp/main.cpp b/tests/manual/dumpcpp/main.cpp index 2f3cef8..5bbc948 100644 --- a/tests/manual/dumpcpp/main.cpp +++ b/tests/manual/dumpcpp/main.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "ieframe.h" // generated header @@ -37,6 +12,7 @@ #include <QMenu> #include <QMenuBar> #include <QToolBar> +#include <QLibraryInfo> #include <QScreen> @@ -96,9 +72,6 @@ void MainWindow::showMetaObject() int main(int argc, char *argv[]) { - QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QApplication a(argc, argv); MainWindow w; diff --git a/tests/manual/hierarchy/CMakeLists.txt b/tests/manual/hierarchy/CMakeLists.txt new file mode 100644 index 0000000..3db0a0e --- /dev/null +++ b/tests/manual/hierarchy/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## hierarchy Library: +##################################################################### + +set(CMAKE_AUTOMOC ON) + +qt_internal_add_manual_test(tst_hierarchy + GUI + SOURCES + main.cpp + objects.cpp objects.h + hierarchy.def + hierarchy.rc + LIBRARIES + Qt::AxServer + Qt::Gui + Qt::Widgets +) + +qt_disable_warnings(tst_hierarchy) +qt6_target_idl(tst_hierarchy) diff --git a/tests/manual/hierarchy/doc/snippets/hierarchy-demo-snippet.qdoc b/tests/manual/hierarchy/doc/snippets/hierarchy-demo-snippet.qdoc new file mode 100644 index 0000000..9b14316 --- /dev/null +++ b/tests/manual/hierarchy/doc/snippets/hierarchy-demo-snippet.qdoc @@ -0,0 +1,44 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +//! [script] +<script language="javascript"> +function createSubWidget( form ) +{ + ParentWidget.createSubWidget( form.nameEdit.value ); +} + +function renameSubWidget( form ) +{ + var SubWidget = ParentWidget.subWidget( form.nameEdit.value ); + if ( !SubWidget ) { + alert( "No such widget " + form.nameEdit.value + "!" ); + return; + } + SubWidget.label = form.labelEdit.value; + form.nameEdit.value = SubWidget.label; +} + +function setFont( form ) +{ + ParentWidget.font = form.fontEdit.value; +} +</script> + +<p> +This widget can have many children! +</p> +<object ID="ParentWidget" CLASSID="CLSID:d574a747-8016-46db-a07c-b2b4854ee75c" +CODEBASE="http://www.qt-project.org/demos/hierarchy.cab"> +[Object not available! Did you forget to build and register the server?] +</object><br /> +<form> +<input type="edit" ID="nameEdit" value="<enter object name>" /> +<input type="button" value="Create" onClick="createSubWidget(this.form)" /> +<input type="edit" ID="labelEdit" /> +<input type="button" value="Rename" onClick="renameSubWidget(this.form)" /> +<br /> +<input type="edit" ID="fontEdit" value="MS Sans Serif" /> +<input type="button" value = "Set Font" onClick="setFont(this.form)" /> +</form> +//! [script] diff --git a/tests/manual/hierarchy/doc/src/hierarchy.qdoc b/tests/manual/hierarchy/doc/src/hierarchy.qdoc new file mode 100644 index 0000000..fbfaca9 --- /dev/null +++ b/tests/manual/hierarchy/doc/src/hierarchy.qdoc @@ -0,0 +1,65 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page qaxserver-demo-hierarchy.html + \title Qt Widget Hierarchy + + \input examples/hierarchy-demo.qdocinc +*/ + +/*! + \example activeqt/hierarchy + \title Hierarchy Example (ActiveQt) + \ingroup activeqt-examples + + \brief The Hierarchy example is shows how to write an in-process ActiveX + control. The control is a QWidget subclass with child widgets + that are accessible as sub-types. + + \snippet activeqt/hierarchy/objects.h 0 + The \c QParentWidget class provides slots to create a widget + with a name, and to return a pointer to a named widget. The class + declaration uses \c Q_CLASSINFO() to provide the COM identifiers for + this class. + + \snippet activeqt/hierarchy/objects.cpp 0 + The constructor of \c QParentWidget creates a vertical box layout. + New child widgets are automatically added to the layout. + + \snippet activeqt/hierarchy/objects.cpp 1 + The \c createSubWidget slot creates a new \c QSubWidget with + the name provided in the parameter, and sets the label to that + name. The widget is also shown explicitly. + + \snippet activeqt/hierarchy/objects.cpp 2 + The \c subWidget slot uses the \c QObject::findChild() function and + returns the first child of type \c QSubWidget that has the requested + name. + + \snippet activeqt/hierarchy/objects.h 1 + The \c QSubWidget class has a single string-property \c label, + and implements the paintEvent to draw the label. The class uses + again \c Q_CLASSINFO to provide the COM identifiers, and also sets + the \e ToSuperClass attribute to \e QSubWidget, to ensure that only + no slots of any superclasses (i.e. QWidget) are exposed. + + \snippet activeqt/hierarchy/objects.cpp 3 + \snippet activeqt/hierarchy/objects.cpp 4 + The implementation of the \c QSubWidget class is self-explanatory. + + \snippet activeqt/hierarchy/main.cpp 0 + The classes are then exported using a QAxFactory. \c QParentWidget is + exported as a full class (which can be created ), while \c QSubWidget is + only exported as a type, which can only be created indirectly through + APIs of \c QParentWidget. + + To build the example you must first build the QAxServer library. + Then run qmake and your make tool in \c activeqt/hierarchy. + + The \l{qaxserver-demo-hierarchy.html}{demonstration} requires + your WebBrowser to support ActiveX controls, and scripting to be + enabled. + + \snippet activeqt/hierarchy/doc/snippets/hierarchy-demo-snippet.qdoc script +*/ diff --git a/tests/manual/hierarchy/hierarchy.def b/tests/manual/hierarchy/hierarchy.def new file mode 100644 index 0000000..bc82a03 --- /dev/null +++ b/tests/manual/hierarchy/hierarchy.def @@ -0,0 +1,6 @@ +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + DumpIDL PRIVATE diff --git a/tests/manual/hierarchy/hierarchy.ico b/tests/manual/hierarchy/hierarchy.ico Binary files differnew file mode 100644 index 0000000..c80d36a --- /dev/null +++ b/tests/manual/hierarchy/hierarchy.ico diff --git a/tests/manual/hierarchy/hierarchy.inf b/tests/manual/hierarchy/hierarchy.inf new file mode 100644 index 0000000..cb7e90f --- /dev/null +++ b/tests/manual/hierarchy/hierarchy.inf @@ -0,0 +1,9 @@ +[version] + signature="$CHICAGO$" + AdvancedINF=2.0 + [Add.Code] + hierarchyax.dll=hierarchyax.dll + [hierarchyax.dll] + file-win32-x86=thiscab + clsid={d574a747-8016-46db-a07c-b2b4854ee75c} + RegisterServer=yes diff --git a/tests/manual/hierarchy/hierarchy.pro b/tests/manual/hierarchy/hierarchy.pro new file mode 100644 index 0000000..acc108a --- /dev/null +++ b/tests/manual/hierarchy/hierarchy.pro @@ -0,0 +1,16 @@ +include(../shared.pri) + +TEMPLATE = lib +TARGET = hierarchyax + +CONFIG += warn_off dll +QT += widgets axserver + +SOURCES = objects.cpp main.cpp +HEADERS = objects.h +RC_FILE = hierarchy.rc +DEF_FILE = hierarchy.def + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/activeqt/hierarchy +INSTALLS += target diff --git a/tests/manual/hierarchy/hierarchy.rc b/tests/manual/hierarchy/hierarchy.rc new file mode 100644 index 0000000..70eb503 --- /dev/null +++ b/tests/manual/hierarchy/hierarchy.rc @@ -0,0 +1,2 @@ +1 TYPELIB "hierarchy.rc" +1 ICON "hierarchy.ico" diff --git a/tests/manual/hierarchy/main.cpp b/tests/manual/hierarchy/main.cpp new file mode 100644 index 0000000..82e2db2 --- /dev/null +++ b/tests/manual/hierarchy/main.cpp @@ -0,0 +1,12 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +//! [0] +#include "objects.h" +#include <QAxFactory> + +QAXFACTORY_BEGIN("{9e626211-be62-4d18-9483-9419358fbb03}", "{75c276de-1df5-451f-a004-e4fa1a587df1}") + QAXCLASS(QParentWidget) + QAXTYPE(QSubWidget) +QAXFACTORY_END() +//! [0] diff --git a/tests/manual/hierarchy/objects.cpp b/tests/manual/hierarchy/objects.cpp new file mode 100644 index 0000000..8c0c3df --- /dev/null +++ b/tests/manual/hierarchy/objects.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "objects.h" +#include <QLayout> +#include <QPainter> + +/* Implementation of QParentWidget */ +//! [0] +QParentWidget::QParentWidget(QWidget *parent) +: QWidget(parent), + m_vbox(new QVBoxLayout(this)) +{ +} + +//! [0] //! [1] +void QParentWidget::createSubWidget(const QString &name) +{ + QSubWidget *sw = new QSubWidget(this, name); + m_vbox->addWidget(sw); + sw->setLabel(name); + sw->show(); +} + +//! [1] //! [2] +QSubWidget *QParentWidget::subWidget(const QString &name) +{ + return findChild<QSubWidget *>(name); +} + +//! [2] +QSize QParentWidget::sizeHint() const +{ + return QWidget::sizeHint().expandedTo(QSize(100, 100)); +} + +/* Implementation of QSubWidget */ +//! [3] +QSubWidget::QSubWidget(QWidget *parent, const QString &name) +: QWidget(parent) +{ + setObjectName(name); +} + +void QSubWidget::setLabel(const QString &text) +{ + m_label = text; + setObjectName(text); + update(); +} + +QString QSubWidget::label() const +{ + return m_label; +} + +QSize QSubWidget::sizeHint() const +{ + QFontMetrics fm(font()); + return QSize(fm.horizontalAdvance(m_label), fm.height()); +} + +void QSubWidget::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.setPen(palette().text().color()); + painter.drawText(rect(), Qt::AlignCenter, m_label); +//! [3] //! [4] +} +//! [4] diff --git a/tests/manual/hierarchy/objects.h b/tests/manual/hierarchy/objects.h new file mode 100644 index 0000000..f7bcf18 --- /dev/null +++ b/tests/manual/hierarchy/objects.h @@ -0,0 +1,62 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef OBJECTS_H +#define OBJECTS_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +class QVBoxLayout; +QT_END_NAMESPACE +class QSubWidget; + +//! [0] +class QParentWidget : public QWidget +{ + Q_OBJECT + Q_CLASSINFO("ClassID", "{d574a747-8016-46db-a07c-b2b4854ee75c}"); + Q_CLASSINFO("InterfaceID", "{4a30719d-d9c2-4659-9d16-67378209f822}"); + Q_CLASSINFO("EventsID", "{4a30719d-d9c2-4659-9d16-67378209f823}"); +public: + explicit QParentWidget(QWidget *parent = nullptr); + + QSize sizeHint() const override; + +public slots: + void createSubWidget(const QString &name); + + QSubWidget *subWidget(const QString &name); + +private: + QVBoxLayout *m_vbox; +}; +//! [0] + +//! [1] +class QSubWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QString label READ label WRITE setLabel) + + Q_CLASSINFO("ClassID", "{850652f4-8f71-4f69-b745-bce241ccdc30}"); + Q_CLASSINFO("InterfaceID", "{2d76cc2f-3488-417a-83d6-debff88b3c3f}"); + Q_CLASSINFO("ToSuperClass", "QSubWidget"); + +public: + QSubWidget(QWidget *parent = nullptr, const QString &name = QString()); + + void setLabel(const QString &text); + QString label() const; + + QSize sizeHint() const override; + +protected: + void paintEvent(QPaintEvent *e) override; + +private: + QString m_label; +}; +//! [1] + +#endif // OBJECTS_H diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro deleted file mode 100644 index 5749606..0000000 --- a/tests/manual/manual.pro +++ /dev/null @@ -1,2 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS += axviewer dumpcpp testcontrol diff --git a/tests/manual/mediaplayer/CMakeLists.txt b/tests/manual/mediaplayer/CMakeLists.txt new file mode 100644 index 0000000..6f443e7 --- /dev/null +++ b/tests/manual/mediaplayer/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## mediaplayer Binary: +##################################################################### + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) + +qt_internal_add_manual_test(tst_mediaplayer + SOURCES + mainwindow.ui + mediaaxwidget.h + main.cpp + INCLUDE_DIRECTORIES + ../shared + LIBRARIES + Qt::AxContainer + Qt::Core + Qt::Gui + Qt::Widgets +) + +set_target_properties(tst_mediaplayer PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) diff --git a/tests/manual/mediaplayer/doc/images/activeqt-mediaplayer-example.jpg b/tests/manual/mediaplayer/doc/images/activeqt-mediaplayer-example.jpg Binary files differnew file mode 100644 index 0000000..4839242 --- /dev/null +++ b/tests/manual/mediaplayer/doc/images/activeqt-mediaplayer-example.jpg diff --git a/tests/manual/mediaplayer/doc/src/mediaplayer.qdoc b/tests/manual/mediaplayer/doc/src/mediaplayer.qdoc new file mode 100644 index 0000000..e6cd19b --- /dev/null +++ b/tests/manual/mediaplayer/doc/src/mediaplayer.qdoc @@ -0,0 +1,64 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example activeqt/mediaplayer + \title Media Player Example (ActiveQt) + \ingroup activeqt-examples + + \brief The Media Player example uses the Microsoft Media Player + ActiveX control to implement a functional media player application. + + \image activeqt-mediaplayer-example.jpg + + \e {Media Player} demonstrates how a Qt application can communicate with + embedded ActiveX controls using signals, slots, and the \c dynamicCall() + function. + + \quotefromfile activeqt/mediaplayer/main.cpp + \skipto class MainWindow + \printuntil /^\}/ + + The \c MainWindow class declares a \c QMainWindow based user interface, + using the \c Ui::MainWindow class created by Qt Designer. A number + of slots are implemented to handle events from user interface elements, + including the \c mediaPlayer object, which is a QAxWidget hosting + the Microsoft Media Player ActiveX control. + + \quotefromfile activeqt/mediaplayer/main.cpp + \skipto MainWindow::MainWindow() + \printuntil /^\}/ + + The constructor initializes the user interface, restores a previously + saved window geometry, and uses the \c dynamicCall() function to invoke + the APIs implemented by the Microsoft Media Player ActiveX control, + to set initial configuration parameters. + + \quotefromfile activeqt/mediaplayer/main.cpp + \skipto MainWindow::on_mediaPlayer_PlayStateChange + \printuntil /^\}/ + + The \c on_mediaPlayer_PlayStateChange slot handles the signal emitted + by the \c mediaPlayer object when its state changes. + + \quotefromfile activeqt/mediaplayer/main.cpp + \skipto MainWindow::openMedia + \printuntil /^\}/ + + The \c openMedia() function allows a media file to be opened by using + the \c dynamicCall() function to set the URL property in the ActiveX + control, which causes the media file to be loaded and played. + + \quotefromfile activeqt/mediaplayer/main.cpp + \skipto int main + \printuntil /^\}/ + + The \c main() function starts the application using standard Qt APIs + and uses an optional command line argument as the name of a media + file to be loaded by the player. + + To build the example, you must first build the QAxContainer + library. Then run your make tool in + \c examples/activeqt/mediaplayer and run the resulting + \c mediaplayer.exe. +*/ diff --git a/tests/manual/mediaplayer/main.cpp b/tests/manual/mediaplayer/main.cpp new file mode 100644 index 0000000..955d666 --- /dev/null +++ b/tests/manual/mediaplayer/main.cpp @@ -0,0 +1,145 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include <QApplication> +#include <QMessageBox> +#include <QMainWindow> +#include <QScreen> +#include <QVariant> +#include <QSettings> +#include <QFileDialog> +#include <QCommandLineParser> + +#include "ui_mainwindow.h" + +static const char geometryKey[] = "Geometry"; + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(); + ~MainWindow(); + void openMedia(const QString &mediaUrl); + +public slots: + void on_mediaPlayer_PlayStateChange(int newState); + void on_actionOpen_triggered(); + void on_actionExit_triggered(); + void on_actionAbout_triggered(); + void on_actionAboutQt_triggered(); + +private: + void updateWindowTitle(const QString &state); + Ui::MainWindow m_ui; +}; + +MainWindow::MainWindow() +{ + m_ui.setupUi(this); + + QSettings settings(QSettings::IniFormat, QSettings::UserScope, + QCoreApplication::organizationName(), QCoreApplication::applicationName()); + + const QByteArray restoredGeometry = settings.value(QLatin1String(geometryKey)).toByteArray(); + if (restoredGeometry.isEmpty() || !restoreGeometry(restoredGeometry)) { + const QRect availableGeometry = screen()->availableGeometry(); + const QSize size = (availableGeometry.size() * 4) / 5; + resize(size); + move(availableGeometry.center() - QPoint(size.width(), size.height()) / 2); + } + + m_ui.mediaPlayer->dynamicCall("enableContextMenu", false); + m_ui.mediaPlayer->dynamicCall("stretchToFit", true); + updateWindowTitle(""); +} + +MainWindow::~MainWindow() +{ + QSettings settings(QSettings::IniFormat, QSettings::UserScope, + QCoreApplication::organizationName(), QCoreApplication::applicationName()); + settings.setValue(QLatin1String(geometryKey), saveGeometry()); +} + +void MainWindow::on_mediaPlayer_PlayStateChange(int newState) +{ + static const QHash<int, const char *> stateMapping { + {1, "Stopped"}, + {2, "Paused"}, + {3, "Playing"}, + {4, "Scanning Forwards"}, + {5, "Scanning Backwards"}, + {6, "Buffering"}, + {7, "Waiting"}, + {8, "Media Ended"}, + {9, "Transitioning"}, + {10, "Ready"}, + {11, "Reconnecting"}, + }; + const char *stateStr = stateMapping.value(newState, ""); + updateWindowTitle(tr(stateStr)); +} + +void MainWindow::on_actionOpen_triggered() +{ + QFileDialog fileDialog(this, tr("Open File")); + fileDialog.setAcceptMode(QFileDialog::AcceptOpen); + fileDialog.setFileMode(QFileDialog::ExistingFile); + fileDialog.setMimeTypeFilters({ "application/octet-stream", "video/x-msvideo", "video/mp4", "audio/mpeg", "audio/mp4" }); + if (fileDialog.exec() == QDialog::Accepted) + openMedia(fileDialog.selectedFiles().first()); +} + +void MainWindow::on_actionExit_triggered() +{ + QCoreApplication::quit(); +} + +void MainWindow::on_actionAbout_triggered() +{ + QMessageBox::about(this, tr("About Media Player"), + tr("This Example has been created using the ActiveQt integration into Qt Designer.\n" + "It demonstrates the use of QAxWidget to embed the Windows Media Player ActiveX\n" + "control into a Qt application.")); +} + +void MainWindow::on_actionAboutQt_triggered() +{ + QMessageBox::aboutQt(this, tr("About Qt")); +} + +void MainWindow::openMedia(const QString &mediaUrl) +{ + if (!mediaUrl.isEmpty()) + m_ui.mediaPlayer->dynamicCall("URL", mediaUrl); +} + +void MainWindow::updateWindowTitle(const QString &state) +{ + QString appName = QCoreApplication::applicationName(); + QString title = state.isEmpty() ? appName : + QString("%1 (%2)").arg(appName, state); + setWindowTitle(title); +} + +#include "main.moc" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCoreApplication::setApplicationName(QLatin1String("Active Qt Media Player")); + QCoreApplication::setOrganizationName(QLatin1String("QtProject")); + + MainWindow w; + QCommandLineParser parser; + parser.setApplicationDescription(QCoreApplication::applicationName()); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("file", "The media file to open."); + parser.process(app); + if (!parser.positionalArguments().isEmpty()) + w.openMedia(parser.positionalArguments().constFirst()); + w.show(); + return app.exec(); +} diff --git a/tests/manual/mediaplayer/mainwindow.ui b/tests/manual/mediaplayer/mainwindow.ui new file mode 100644 index 0000000..b83d392 --- /dev/null +++ b/tests/manual/mediaplayer/mainwindow.ui @@ -0,0 +1,147 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainWindow</class> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>794</width> + <height>599</height> + </rect> + </property> + <property name="acceptDrops"> + <bool>true</bool> + </property> + <property name="windowTitle"> + <string>Qt Media Player</string> + </property> + <widget class="QWidget" name="centralWidget"> + <layout class="QHBoxLayout" name="unnamed"> + <property name="spacing"> + <number>6</number> + </property> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <widget class="QFrame" name="Frame"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <layout class="QVBoxLayout" name="unnamed"> + <property name="spacing"> + <number>0</number> + </property> + <property name="leftMargin"> + <number>1</number> + </property> + <property name="topMargin"> + <number>1</number> + </property> + <property name="rightMargin"> + <number>1</number> + </property> + <property name="bottomMargin"> + <number>1</number> + </property> + <item> + <widget class="MediaAxWidget" name="mediaPlayer"> + <property name="control" stdset="0"> + <string>{6bf52a52-394a-11d3-b153-00c04f79faa6}</string> + </property> + <property name="sizePolicy" stdset="0"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>794</width> + <height>21</height> + </rect> + </property> + <widget class="QMenu" name="PopupMenu"> + <property name="title"> + <string>&File</string> + </property> + <addaction name="actionOpen"/> + <addaction name="actionExit"/> + </widget> + <widget class="QMenu" name="menuHelp"> + <property name="title"> + <string>&Help</string> + </property> + <addaction name="actionAbout"/> + <addaction name="actionAboutQt"/> + </widget> + <addaction name="PopupMenu"/> + <addaction name="menuHelp"/> + </widget> + <action name="actionOpen"> + <property name="text"> + <string>&Open</string> + </property> + </action> + <action name="actionExit"> + <property name="text"> + <string>E&xit</string> + </property> + </action> + <action name="actionAbout"> + <property name="text"> + <string>&About</string> + </property> + </action> + <action name="actionAboutQt"> + <property name="text"> + <string>About &Qt</string> + </property> + </action> + <actiongroup name="FileNewGroup"/> + </widget> + <layoutdefault spacing="6" margin="11"/> + <customwidgets> + <customwidget> + <class>QAxWidget</class> + <extends>QWidget</extends> + <header>qaxwidget.h</header> + </customwidget> + <customwidget> + <class>MediaAxWidget</class> + <extends>QAxWidget</extends> + <header>mediaaxwidget.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections/> +</ui> diff --git a/tests/manual/mediaplayer/mediaaxwidget.h b/tests/manual/mediaplayer/mediaaxwidget.h new file mode 100644 index 0000000..f12cdfc --- /dev/null +++ b/tests/manual/mediaplayer/mediaaxwidget.h @@ -0,0 +1,29 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef MEDIAAXWIDGET_H +#define MEDIAAXWIDGET_H + +#include <QtAxContainer/QAxWidget> +#include <qt_windows.h> + +// Overrides the translateKeyEvent() function to pass keystrokes +// to the Windows Media Player ActiveX control. +class MediaAxWidget : public QAxWidget +{ +public: + MediaAxWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {}) + : QAxWidget(parent, f) + { + } + +protected: + bool translateKeyEvent(int message, int keycode) const override + { + if (message >= WM_KEYFIRST && message <= WM_KEYLAST) + return true; + return QAxWidget::translateKeyEvent(message, keycode); + } +}; + +#endif // MEDIAAXWIDGET_H diff --git a/tests/manual/mediaplayer/mediaplayer.pro b/tests/manual/mediaplayer/mediaplayer.pro new file mode 100644 index 0000000..ad787a3 --- /dev/null +++ b/tests/manual/mediaplayer/mediaplayer.pro @@ -0,0 +1,11 @@ +TEMPLATE = app + +QT += widgets axcontainer + +HEADERS = mediaaxwidget.h +SOURCES = main.cpp +FORMS = mainwindow.ui + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/activeqt/mediaplayer +INSTALLS += target diff --git a/tests/manual/menus/CMakeLists.txt b/tests/manual/menus/CMakeLists.txt new file mode 100644 index 0000000..a8b3899 --- /dev/null +++ b/tests/manual/menus/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## menus Executable: +##################################################################### + +set(CMAKE_AUTOMOC ON) + +qt_internal_add_manual_test(tst_menus + GUI + SOURCES + main.cpp + menus.cpp menus.h + menus.def + menus.rc + LIBRARIES + Qt::AxServer + Qt::Core + Qt::Gui + Qt::Widgets +) + +qt_disable_warnings(tst_menus) +qt6_target_idl(tst_menus) diff --git a/tests/manual/menus/doc/snippets/doc_src_examples_activeqt_menus.qdoc b/tests/manual/menus/doc/snippets/doc_src_examples_activeqt_menus.qdoc new file mode 100644 index 0000000..0992d84 --- /dev/null +++ b/tests/manual/menus/doc/snippets/doc_src_examples_activeqt_menus.qdoc @@ -0,0 +1,9 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +//! [0] +<object ID="QMenus" CLASSID="CLSID:4dc3f340-a6f7-44e4-a79b-3e9217695fbd" +CODEBASE="http://www.qt-project.org/demos/menusax.cab"> +[Object not available! Did you forget to build and register the server?] +</object> +//! [0] diff --git a/tests/manual/menus/doc/src/menus.qdoc b/tests/manual/menus/doc/src/menus.qdoc new file mode 100644 index 0000000..2ed7ea1 --- /dev/null +++ b/tests/manual/menus/doc/src/menus.qdoc @@ -0,0 +1,37 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page qaxserver-demo-menus.html + \preliminary + + \title Menubar Merging + + This example is not fully functional at the moment. + + \raw HTML + <object ID="QMenus" CLASSID="CLSID:4dc3f340-a6f7-44e4-a79b-3e9217695fbd" + CODEBASE="http://www.qt-project.org/demos/menusax.cab"> + [Object not available! Did you forget to build and register the server?] + </object> + \endraw +*/ + +/*! + \example activeqt/menus + \title Menus Example (ActiveQt) + \ingroup activeqt-examples + + \brief The Menus example demonstrates the use of QMenuBar and QStatusBar + in a QMainWindow to implement an in-place active control. + + To build the example you must first build the QAxServer library. + Then run \c qmake and your make tool in \c + examples/activeqt/menus. + + The \l{qaxserver-demo-menus.html}{demonstration} requires your + WebBrowser to support ActiveX controls, and scripting to be + enabled. + + \snippet activeqt/menus/doc/snippets/doc_src_examples_activeqt_menus.qdoc 0 +*/ diff --git a/tests/manual/menus/fileopen.xpm b/tests/manual/menus/fileopen.xpm new file mode 100644 index 0000000..880417e --- /dev/null +++ b/tests/manual/menus/fileopen.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static const char *fileopen[] = { +" 16 13 5 1", +". c #040404", +"# c #808304", +"a c None", +"b c #f3f704", +"c c #f3f7f3", +"aaaaaaaaa...aaaa", +"aaaaaaaa.aaa.a.a", +"aaaaaaaaaaaaa..a", +"a...aaaaaaaa...a", +".bcb.......aaaaa", +".cbcbcbcbc.aaaaa", +".bcbcbcbcb.aaaaa", +".cbcb...........", +".bcb.#########.a", +".cb.#########.aa", +".b.#########.aaa", +"..#########.aaaa", +"...........aaaaa" +}; diff --git a/tests/manual/menus/filesave.xpm b/tests/manual/menus/filesave.xpm new file mode 100644 index 0000000..bd6870f --- /dev/null +++ b/tests/manual/menus/filesave.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static const char *filesave[] = { +" 14 14 4 1", +". c #040404", +"# c #808304", +"a c #bfc2bf", +"b c None", +"..............", +".#.aaaaaaaa.a.", +".#.aaaaaaaa...", +".#.aaaaaaaa.#.", +".#.aaaaaaaa.#.", +".#.aaaaaaaa.#.", +".#.aaaaaaaa.#.", +".##........##.", +".############.", +".##.........#.", +".##......aa.#.", +".##......aa.#.", +".##......aa.#.", +"b............." +}; diff --git a/tests/manual/menus/main.cpp b/tests/manual/menus/main.cpp new file mode 100644 index 0000000..0ae5c1a --- /dev/null +++ b/tests/manual/menus/main.cpp @@ -0,0 +1,26 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "menus.h" +#include <QApplication> +#include <QAxFactory> +#include <QScopedPointer> + +QAXFACTORY_BEGIN( + "{ce947ee3-0403-4fdc-895a-4fe779394b46}", // type library ID + "{8de435ce-8d2a-46ac-b3b3-cb800d0847c7}") // application ID + QAXCLASS(QMenus) +QAXFACTORY_END() + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + QScopedPointer<QWidget> window; + + if (!QAxFactory::isServer()) { + window.reset(new QMenus()); + window->show(); + } + + return a.exec(); +} diff --git a/tests/manual/menus/menus.cpp b/tests/manual/menus/menus.cpp new file mode 100644 index 0000000..876fb27 --- /dev/null +++ b/tests/manual/menus/menus.cpp @@ -0,0 +1,140 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "menus.h" +#include <QAction> +#include <QAxFactory> +#include <QMenuBar> +#include <QMessageBox> +#include <QTextEdit> +#include <QPixmap> + +#include "fileopen.xpm" +#include "filesave.xpm" + +QMenus::QMenus(QWidget *parent) + : QMainWindow(parent, {}) // QMainWindow's default flag is WType_TopLevel +{ + QAction *action; + + QMenu *file = new QMenu(this); + + action = new QAction(QPixmap((const char**)fileopen), tr("&Open"), this); + action->setShortcut(tr("CTRL+O")); + connect(action, &QAction::triggered, this, &QMenus::fileOpen); + file->addAction(action); + + action = new QAction(QPixmap((const char**)filesave), tr("&Save"), this); + action->setShortcut(tr("CTRL+S")); + connect(action, &QAction::triggered, this, &QMenus::fileSave); + file->addAction(action); + + QMenu *edit = new QMenu(this); + + action = new QAction(tr("&Normal"), this); + action->setShortcut(tr("CTRL+N")); + action->setToolTip(tr("Normal")); + action->setStatusTip(tr("Toggles Normal")); + action->setCheckable(true); + connect(action, &QAction::triggered, this, &QMenus::editNormal); + edit->addAction(action); + + action = new QAction(tr("&Bold"), this); + action->setShortcut(tr("CTRL+B")); + action->setCheckable(true); + connect(action, &QAction::triggered, this, &QMenus::editBold); + edit->addAction(action); + + action = new QAction(tr("&Underline"), this); + action->setShortcut(tr("CTRL+U")); + action->setCheckable(true); + connect(action, &QAction::triggered, this, &QMenus::editUnderline); + edit->addAction(action); + + QMenu *advanced = new QMenu(this); + action = new QAction(tr("&Font..."), this); + connect(action, &QAction::triggered, this, &QMenus::editAdvancedFont); + advanced->addAction(action); + + action = new QAction(tr("&Style..."), this); + connect(action, &QAction::triggered, this, &QMenus::editAdvancedStyle); + advanced->addAction(action); + + edit->addMenu(advanced)->setText(tr("&Advanced")); + + edit->addSeparator(); + + action = new QAction(tr("Una&vailable"), this); + action->setShortcut(tr("CTRL+V")); + action->setCheckable(true); + action->setEnabled(false); + connect(action, &QAction::triggered, this, &QMenus::editUnderline); + edit->addAction(action); + + QMenu *help = new QMenu(this); + + action = new QAction(tr("&About..."), this); + action->setShortcut(tr("F1")); + connect(action, &QAction::triggered, this, &QMenus::helpAbout); + help->addAction(action); + + action = new QAction(tr("&About Qt..."), this); + connect(action, &QAction::triggered, this, &QMenus::helpAboutQt); + help->addAction(action); + + if (!QAxFactory::isServer()) + menuBar()->addMenu(file)->setText(tr("&File")); + menuBar()->addMenu(edit)->setText(tr("&Edit")); + menuBar()->addMenu(help)->setText(tr("&Help")); + + m_editor = new QTextEdit(this); + setCentralWidget(m_editor); + + statusBar(); +} + +void QMenus::fileOpen() +{ + m_editor->append(tr("File Open selected.")); +} + +void QMenus::fileSave() +{ + m_editor->append(tr("File Save selected.")); +} + +void QMenus::editNormal() +{ + m_editor->append(tr("Edit Normal selected.")); +} + +void QMenus::editBold() +{ + m_editor->append(tr("Edit Bold selected.")); +} + +void QMenus::editUnderline() +{ + m_editor->append(tr("Edit Underline selected.")); +} + +void QMenus::editAdvancedFont() +{ + m_editor->append(tr("Edit Advanced Font selected.")); +} + +void QMenus::editAdvancedStyle() +{ + m_editor->append(tr("Edit Advanced Style selected.")); +} + +void QMenus::helpAbout() +{ + QMessageBox::about(this, tr("About QMenus"), + tr("This example implements an in-place ActiveX control with menus and status messages.")); +} + +void QMenus::helpAboutQt() +{ + QMessageBox::aboutQt(this); +} diff --git a/tests/manual/menus/menus.def b/tests/manual/menus/menus.def new file mode 100644 index 0000000..bc82a03 --- /dev/null +++ b/tests/manual/menus/menus.def @@ -0,0 +1,6 @@ +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + DumpIDL PRIVATE diff --git a/tests/manual/menus/menus.h b/tests/manual/menus/menus.h new file mode 100644 index 0000000..5523758 --- /dev/null +++ b/tests/manual/menus/menus.h @@ -0,0 +1,41 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef MENUS_H +#define MENUS_H + +#include <QMainWindow> + +QT_BEGIN_NAMESPACE +class QTextEdit; +QT_END_NAMESPACE + +class QMenus : public QMainWindow +{ + Q_OBJECT + Q_CLASSINFO("ClassID", "{4dc3f340-a6f7-44e4-a79b-3e9217695fbd}") + Q_CLASSINFO("InterfaceID", "{9ee49617-7d5c-441a-b833-4b068d40d751}") + Q_CLASSINFO("EventsID", "{13eca64b-ee2a-4f3c-aa04-5d9d975979a7}") + +public: + explicit QMenus(QWidget *parent = nullptr); + +public slots: + void fileOpen(); + void fileSave(); + + void editNormal(); + void editBold(); + void editUnderline(); + + void editAdvancedFont(); + void editAdvancedStyle(); + + void helpAbout(); + void helpAboutQt(); + +private: + QTextEdit *m_editor; +}; + +#endif // MENUS_H diff --git a/tests/manual/menus/menus.ico b/tests/manual/menus/menus.ico Binary files differnew file mode 100644 index 0000000..c80d36a --- /dev/null +++ b/tests/manual/menus/menus.ico diff --git a/tests/manual/menus/menus.inf b/tests/manual/menus/menus.inf new file mode 100644 index 0000000..f97efe8 --- /dev/null +++ b/tests/manual/menus/menus.inf @@ -0,0 +1,9 @@ +[version] + signature="$CHICAGO$" + AdvancedINF=2.0 + [Add.Code] + menusax.exe=menusax.exe + [menusax.exe] + file-win32-x86=thiscab + clsid={4dc3f340-a6f7-44e4-a79b-3e9217695fbd} + RegisterServer=yes diff --git a/tests/manual/menus/menus.pro b/tests/manual/menus/menus.pro new file mode 100644 index 0000000..f5a7890 --- /dev/null +++ b/tests/manual/menus/menus.pro @@ -0,0 +1,16 @@ +include(../shared.pri) + +TEMPLATE = app +TARGET = menusax + +CONFIG += warn_off +QT += widgets axserver + +SOURCES = main.cpp menus.cpp +HEADERS = menus.h +RC_FILE = menus.rc +DEF_FILE = menus.def + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/activeqt/menus +INSTALLS += target diff --git a/tests/manual/menus/menus.rc b/tests/manual/menus/menus.rc new file mode 100644 index 0000000..d466b35 --- /dev/null +++ b/tests/manual/menus/menus.rc @@ -0,0 +1,2 @@ +1 TYPELIB "menus.rc" +1 ICON "menus.ico" diff --git a/tests/manual/multiple/CMakeLists.txt b/tests/manual/multiple/CMakeLists.txt new file mode 100644 index 0000000..8e5d7c7 --- /dev/null +++ b/tests/manual/multiple/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## multiple Binary: +##################################################################### + +set(CMAKE_AUTOMOC ON) + +qt_internal_add_manual_test(tst_multiple + GUI + SOURCES + ax1.h + ax2.h + main.cpp + multipleax.def + multipleax.rc + LIBRARIES + Qt::AxServer + Qt::Gui + Qt::Widgets + +) +# qt_disable_warnings(tst_multiple) +qt6_target_idl(tst_multiple) diff --git a/tests/manual/multiple/ax1.h b/tests/manual/multiple/ax1.h new file mode 100644 index 0000000..be15878 --- /dev/null +++ b/tests/manual/multiple/ax1.h @@ -0,0 +1,50 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef AX1_H +#define AX1_H + +#include <QWidget> +#include <QPainter> + +//! [0] +class QAxWidget1 : public QWidget +{ + Q_OBJECT + Q_CLASSINFO("ClassID", "{1D9928BD-4453-4bdd-903D-E525ED17FDE5}") + Q_CLASSINFO("InterfaceID", "{99F6860E-2C5A-42ec-87F2-43396F4BE389}") + Q_CLASSINFO("EventsID", "{0A3E9F27-E4F1-45bb-9E47-63099BCCD0E3}") + + Q_PROPERTY(QColor fillColor READ fillColor WRITE setFillColor) +public: + explicit QAxWidget1(QWidget *parent = nullptr) + : QWidget(parent) + { + } + + QColor fillColor() const + { + return m_fillColor; + } + + void setFillColor(const QColor &fc) + { + m_fillColor = fc; + repaint(); + } + +protected: + void paintEvent(QPaintEvent *e) override + { + QPainter paint(this); + QRect r = rect(); + r.adjust(10, 10, -10, -10); + paint.fillRect(r, m_fillColor); + } + +private: + QColor m_fillColor = Qt::red; +}; +//! [0] + +#endif // AX1_H diff --git a/tests/manual/multiple/ax2.h b/tests/manual/multiple/ax2.h new file mode 100644 index 0000000..1dd2e00 --- /dev/null +++ b/tests/manual/multiple/ax2.h @@ -0,0 +1,54 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#ifndef AX2_H +#define AX2_H + +#include <QWidget> +#include <QPainter> + +//! [0] +class QAxWidget2 : public QWidget +{ + Q_OBJECT + Q_CLASSINFO("ClassID", "{58139D56-6BE9-4b17-937D-1B1EDEDD5B71}") + Q_CLASSINFO("InterfaceID", "{B66280AB-08CC-4dcc-924F-58E6D7975B7D}") + Q_CLASSINFO("EventsID", "{D72BACBA-03C4-4480-B4BB-DE4FE3AA14A0}") + Q_CLASSINFO("ToSuperClass", "QAxWidget2") + Q_CLASSINFO("StockEvents", "yes") + Q_CLASSINFO("Insertable", "yes") + + Q_PROPERTY(int lineWidth READ lineWidth WRITE setLineWidth) +public: + using QWidget::QWidget; + + int lineWidth() const + { + return m_lineWidth; + } + + void setLineWidth(int lw) + { + m_lineWidth = lw; + repaint(); + } + +protected: + void paintEvent(QPaintEvent *e) override + { + QPainter paint(this); + QPen pen = paint.pen(); + pen.setWidth(m_lineWidth); + paint.setPen(pen); + + QRect r = rect(); + r.adjust(10, 10, -10, -10); + paint.drawEllipse(r); + } + +private: + int m_lineWidth = 1; +}; +//! [0] + +#endif // AX2_H diff --git a/tests/manual/multiple/doc/src/multiple.qdoc b/tests/manual/multiple/doc/src/multiple.qdoc new file mode 100644 index 0000000..95e587c --- /dev/null +++ b/tests/manual/multiple/doc/src/multiple.qdoc @@ -0,0 +1,47 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page qaxserver-demo-multiple.html + \title Two Simple Qt Widgets + + \input multiple-demo.qdocinc +*/ + +/*! + \example activeqt/multiple + \title Multiple Example (ActiveQt) + \ingroup activeqt-examples + + \brief The Multiple example demonstrates the implementation of a + QAxFactory to provide multiple ActiveX controls in a single in + process ActiveX server using the \c QAXFACTORY_EXPORT() macro. + The ActiveX controls in this example are simple QWidget + subclasses that reimplement QWidget::paintEvent(). + + \snippet activeqt/multiple/ax1.h 0 + + The first control draws a filled rectangle. The fill color is exposed + as a property. \c Q_CLASSINFO() is used to specify the COM identifiers. + + \snippet activeqt/multiple/ax2.h 0 + + The second control draws a circle. The linewith is exposed as a property. + \c Q_CLASSINFO() is used to specify the COM identifiers, and to set the + attributes \e ToSuperClass and \e StockEvents to expose only the API of + the class itself, and to add COM stock events to the ActiveX control. + + \snippet activeqt/multiple/main.cpp 0 + + The classes are exported from the server using the QAxFactory macros. + + To build the example you must first build the QAxServer library. + Then run \c qmake and your make tool in \c + examples/activeqt/multiple. + + The \l{Two Simple Qt Widgets} demonstration requires your + WebBrowser to support ActiveX controls, and scripting to be + enabled. + + \input multiple-demo.qdocinc +*/ diff --git a/tests/manual/multiple/main.cpp b/tests/manual/multiple/main.cpp new file mode 100644 index 0000000..e262122 --- /dev/null +++ b/tests/manual/multiple/main.cpp @@ -0,0 +1,15 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +//! [0] +#include "ax1.h" +#include "ax2.h" +#include <QAxFactory> + +QT_USE_NAMESPACE + +QAXFACTORY_BEGIN("{98DE28B6-6CD3-4e08-B9FA-3D1DB43F1D2F}", "{05828915-AD1C-47ab-AB96-D6AD1E25F0E2}") + QAXCLASS(QAxWidget1) + QAXCLASS(QAxWidget2) +QAXFACTORY_END() +//! [0] diff --git a/tests/manual/multiple/multiple.inf b/tests/manual/multiple/multiple.inf new file mode 100644 index 0000000..7f6be76 --- /dev/null +++ b/tests/manual/multiple/multiple.inf @@ -0,0 +1,9 @@ +[version] + signature="$CHICAGO$" + AdvancedINF=2.0 + [Add.Code] + multipleax.dll=multipleax.dll + [multipleax.dll] + file-win32-x86=thiscab + clsid={1D9928BD-4453-4bdd-903D-E525ED17FDE5} + RegisterServer=yes diff --git a/tests/manual/multiple/multiple.pro b/tests/manual/multiple/multiple.pro new file mode 100644 index 0000000..f08d3a2 --- /dev/null +++ b/tests/manual/multiple/multiple.pro @@ -0,0 +1,16 @@ +include(../shared.pri) + +TEMPLATE = lib +TARGET = multipleax + +CONFIG += warn_off dll +QT += widgets axserver + +SOURCES = main.cpp +HEADERS = ax1.h ax2.h +RC_FILE = multipleax.rc +DEF_FILE = multipleax.def + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/activeqt/multiple +INSTALLS += target diff --git a/tests/manual/multiple/multipleax.def b/tests/manual/multiple/multipleax.def new file mode 100644 index 0000000..bc82a03 --- /dev/null +++ b/tests/manual/multiple/multipleax.def @@ -0,0 +1,6 @@ +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + DumpIDL PRIVATE diff --git a/tests/manual/multiple/multipleax.ico b/tests/manual/multiple/multipleax.ico Binary files differnew file mode 100644 index 0000000..c80d36a --- /dev/null +++ b/tests/manual/multiple/multipleax.ico diff --git a/tests/manual/multiple/multipleax.rc b/tests/manual/multiple/multipleax.rc new file mode 100644 index 0000000..a9bcc1a --- /dev/null +++ b/tests/manual/multiple/multipleax.rc @@ -0,0 +1,32 @@ +#include "winver.h" + +1 TYPELIB "multipleax.rc" +1 ICON "multipleax.ico" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL + FILEOS 0x00040000L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "The Qt Company Ltd." + VALUE "FileDescription", "Multiple Example (ActiveQt)" + VALUE "FileVersion", "1.0.0.0" + VALUE "LegalCopyright", "Copyright (C) 2015 The Qt Company Ltd." + VALUE "InternalName", "multipleax.dll" + VALUE "OriginalFilename", "multipleax.dll" + VALUE "ProductName", "Multiple Example (ActiveQt)" + VALUE "ProductVersion", "1.0.0.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END diff --git a/tests/manual/opengl/CMakeLists.txt b/tests/manual/opengl/CMakeLists.txt new file mode 100644 index 0000000..e8e4255 --- /dev/null +++ b/tests/manual/opengl/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +##################################################################### +## testcontrol Binary: +##################################################################### + +set(CMAKE_AUTOMOC ON) + +qt_internal_add_manual_test(tst_opengl + GUI + SOURCES + glbox.cpp glbox.h + globjwin.cpp globjwin.h + main.cpp + opengl.def + opengl.rc + LIBRARIES + Qt::AxServer + Qt::Gui + Qt::OpenGL + Qt::OpenGLWidgets + Qt::Widgets +) + +# qt_disable_warnings(tst_opengl) +qt6_target_idl(tst_opengl) diff --git a/tests/manual/opengl/doc/src/opengl.qdoc b/tests/manual/opengl/doc/src/opengl.qdoc new file mode 100644 index 0000000..b95e89d --- /dev/null +++ b/tests/manual/opengl/doc/src/opengl.qdoc @@ -0,0 +1,106 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page qaxserver-demo-opengl.html + + \title OpenGL in an HTML page + + \raw HTML + <SCRIPT LANGUAGE="JavaScript"> + function setRot( form ) + { + GLBox.setXRotation( form.XEdit.value ); + GLBox.setYRotation( form.YEdit.value ); + GLBox.setZRotation( form.ZEdit.value ); + } + </SCRIPT> + + <p /> + An OpenGL scene:<br /> + <object ID="GLBox" CLASSID="CLSID:5fd9c22e-ed45-43fa-ba13-1530bb6b03e0" + CODEBASE="http://www.qt-project.org/demos/openglax.cab"> + [Object not available! Did you forget to build and register the server?] + </object><br /> + + <form> + Rotate the scene:<br /> + X:<input type="edit" ID="XEdit" value="0" /><br /> + Y:<input type="edit" name="YEdit" value="0" /><br /> + Z:<input type="edit" name="ZEdit" value="0" /><br /> + <input type="button" value="Set" onClick="setRot(this.form)" /> + </form> + \endraw +*/ + +/*! + \example activeqt/opengl + \title OpenGL Example (ActiveQt) + \ingroup activeqt-examples + + \brief The OpenGL example demonstrates the use of the default factory + and QAxFactory::isServer(), and the implementation of an + additional COM interface using QAxBindable and QAxAggregated. + The server executable can run both as an ActiveX server and as a + stand-alone application. + + The ActiveX control in this example uses the QGlWidget class in + Qt to render an OpenGL scene in an ActiveX. The control exposes a few + methods to change the scene. + + The application uses QAxFactory through the \c QAXFACTORY_BEGIN(), + \c QAXCLASS() and \c QAXFACTORY_END() macros to expose the + \c GLBox widget as an ActiveX control. + \snippet activeqt/opengl/main.cpp 0 + The implementation of \c main initializes the QApplication object, + and uses \c QAxFactory::isServer() to determine whether or not it is + appropriate to create and show the application interface. + \snippet activeqt/opengl/main.cpp 1 + \snippet activeqt/opengl/main.cpp 2 + \snippet activeqt/opengl/main.cpp 3 + + The \c GLBox class inherits from both the \l QOpenGLWidget class to be able + to render OpenGL, and from \l QAxBindable. + \snippet activeqt/opengl/glbox.h 0 + The class reimplements the \l QAxBindable::createAggregate() function from QAxBindable + to return the pointer to a \l QAxAggregated object. + \snippet activeqt/opengl/glbox.h 1 + + The implementation file of the \c GLBox class includes the \c objsafe.h + system header, in which the \c IObjectSafety COM interface is defined. + \snippet activeqt/opengl/glbox.cpp 0 + A class \c ObjectSafetyImpl is declared using multiple inheritance + to subclass the QAxAggregated class, and to implement the IObjectSafety + interface. + \snippet activeqt/opengl/glbox.cpp 1 + The class declares a default constructor, and implements the queryInterface + function to support the IObjectSafety interface. + \snippet activeqt/opengl/glbox.cpp 2 + Since every COM interface inherits \c IUnknown the \c QAXAGG_IUNKNOWN macro + is used to provide the default implementation of the \c IUnknown interface. + The macro is defined to delegate all calls to \c QueryInterface, \c AddRef + and \c Release to the interface returned by the controllingUnknown() function. + \snippet activeqt/opengl/glbox.cpp 3 + The implementation of the \c IObjectSafety interface provides the caller + with information about supported and enabled safety options, and returns + \c S_OK for all calls to indicate that the ActiveX control is safe. + \snippet activeqt/opengl/glbox.cpp 4 + The implementation of the \c createAggregate() function just returns a new + \c ObjectSafetyImpl object. + \snippet activeqt/opengl/glbox.cpp 5 + + To build the example you must first build the QAxServer library. + Then run \c qmake and your make tool in \c + examples/activeqt/wrapper. + + The \l{qaxserver-demo-opengl.html}{demonstration} requires your + WebBrowser to support ActiveX controls, and scripting to be + enabled. + + In contrast to the other QAxServer examples Internet Explorer will not + open a dialog box to ask the user whether or not the scripting of the GLBox + control should be allowed (the exact browser behaviour depends on the security + settings in the Internet Options dialog). + + \input doc/src/examples/opengl-demo.qdocinc +*/ diff --git a/tests/manual/opengl/glbox.cpp b/tests/manual/opengl/glbox.cpp new file mode 100644 index 0000000..4222df2 --- /dev/null +++ b/tests/manual/opengl/glbox.cpp @@ -0,0 +1,218 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +/**************************************************************************** +** +** This is a simple QGLWidget displaying an openGL wireframe box +** +** The OpenGL code is mostly borrowed from Brian Pauls "spin" example +** in the Mesa distribution +** +****************************************************************************/ + +#include "glbox.h" +#include <QAxAggregated> +#include <QUuid> +//! [0] +#include <objsafe.h> +//! [0] + +/*! + Create a GLBox widget +*/ + +GLBox::GLBox(QWidget *parent, const char *name) + : QOpenGLWidget(parent) +{ + setObjectName(name); + + QSurfaceFormat format; + format.setVersion(1, 1); + format.setProfile(QSurfaceFormat::CompatibilityProfile); + setFormat(format); +} + + +/*! + Release allocated resources +*/ + +GLBox::~GLBox() +{ + makeCurrent(); + + if (m_object) + glDeleteLists(m_object, 1); +} + + +/*! + Paint the box. The actual openGL commands for drawing the box are + performed here. +*/ + +void GLBox::paintGL() +{ + glClear(GL_COLOR_BUFFER_BIT); + + glLoadIdentity(); + glTranslated(0, 0, -10); + glScaled(m_scale, m_scale, m_scale); + + glRotated(m_xRot, 1, 0, 0); + glRotated(m_yRot, 0, 1, 0); + glRotated(m_zRot, 0, 0, 1); + + glCallList(m_object); +} + + +/*! + Set up the OpenGL rendering state, and define display list +*/ + +void GLBox::initializeGL() +{ + initializeOpenGLFunctions(); + glClearColor(0, 0, 0, 1); // Let OpenGL clear to black + m_object = makeObject(); // Generate an OpenGL display list + glShadeModel(GL_FLAT); +} + + + +/*! + Set up the OpenGL view port, matrix mode, etc. +*/ + +void GLBox::resizeGL(int w, int h) +{ + glViewport(0, 0, (GLint)w, (GLint)h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1, 1, -1, 1, 5, 15); + glMatrixMode(GL_MODELVIEW); +} + + +/*! + Generate an OpenGL display list for the object to be shown, i.e. the box +*/ + +GLuint GLBox::makeObject() +{ + GLuint list; + + list = glGenLists(1); + + glNewList(list, GL_COMPILE); + + glColor3d(1, 1, 1); // Shorthand for glColor3f or glIndex + + glLineWidth(2); + + glBegin(GL_LINE_LOOP); + glVertex3d( 1, 0.5, -0.4); + glVertex3d( 1, -0.5, -0.4); + glVertex3d(-1, -0.5, -0.4); + glVertex3d(-1, 0.5, -0.4); + glEnd(); + + glBegin(GL_LINE_LOOP); + glVertex3d( 1, 0.5, 0.4); + glVertex3d( 1, -0.5, 0.4); + glVertex3d(-1, -0.5, 0.4); + glVertex3d(-1, 0.5, 0.4); + glEnd(); + + glBegin(GL_LINES); + glVertex3d( 1, 0.5, -0.4); glVertex3d( 1, 0.5, 0.4); + glVertex3d( 1, -0.5, -0.4); glVertex3d( 1, -0.5, 0.4); + glVertex3d(-1, -0.5, -0.4); glVertex3d(-1, -0.5, 0.4); + glVertex3d(-1, 0.5, -0.4); glVertex3d(-1, 0.5, 0.4); + glEnd(); + + glEndList(); + + return list; +} + + +/*! + Set the rotation angle of the object to \e degrees around the X axis. +*/ + +void GLBox::setXRotation(int degrees) +{ + m_xRot = GLdouble(degrees % 360); + update(); +} + + +/*! + Set the rotation angle of the object to \e degrees around the Y axis. +*/ + +void GLBox::setYRotation(int degrees) +{ + m_yRot = GLdouble(degrees % 360); + update(); +} + + +/*! + Set the rotation angle of the object to \e degrees around the Z axis. +*/ + +void GLBox::setZRotation(int degrees) +{ + m_zRot = GLdouble(degrees % 360); + update(); +} + +//! [1] +class ObjectSafetyImpl : public QAxAggregated, + public IObjectSafety +{ +public: +//! [1] //! [2] + explicit ObjectSafetyImpl() = default; + + long queryInterface(const QUuid &iid, void **iface) override + { + *iface = nullptr; + if (iid != IID_IObjectSafety) + return E_NOINTERFACE; + + *iface = static_cast<IObjectSafety*>(this); + AddRef(); + return S_OK; + } + +//! [2] //! [3] + QAXAGG_IUNKNOWN; + +//! [3] //! [4] + HRESULT WINAPI GetInterfaceSafetyOptions(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions) override + { + Q_UNUSED(riid); + *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACESAFE_FOR_UNTRUSTED_CALLER; + *pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACESAFE_FOR_UNTRUSTED_CALLER; + return S_OK; + } + + HRESULT WINAPI SetInterfaceSafetyOptions(REFIID riid, DWORD pdwSupportedOptions, DWORD pdwEnabledOptions) override + { + Q_UNUSED(riid); + Q_UNUSED(pdwSupportedOptions); + Q_UNUSED(pdwEnabledOptions); + return S_OK; + } +}; +//! [4] //! [5] + +QAxAggregated *GLBox::createAggregate() +{ + return new ObjectSafetyImpl(); +} +//! [5] diff --git a/tests/manual/opengl/glbox.h b/tests/manual/opengl/glbox.h new file mode 100644 index 0000000..d063d8b --- /dev/null +++ b/tests/manual/opengl/glbox.h @@ -0,0 +1,53 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +/**************************************************************************** +** +** This is a simple QGLWidget displaying an openGL wireframe box +** +****************************************************************************/ + +#ifndef GLBOX_H +#define GLBOX_H + +#include <QOpenGLWidget> +#include <QOpenGLFunctions_1_1> +//! [0] +#include <QAxBindable> + +class GLBox : public QOpenGLWidget, + public QOpenGLFunctions_1_1, + public QAxBindable +{ + Q_OBJECT + Q_CLASSINFO("ClassID", "{5fd9c22e-ed45-43fa-ba13-1530bb6b03e0}") + Q_CLASSINFO("InterfaceID", "{33b051af-bb25-47cf-a390-5cfd2987d26a}") + Q_CLASSINFO("EventsID", "{8c996c29-eafa-46ac-a6f9-901951e765b5}") + //! [0] //! [1] + +public: + explicit GLBox(QWidget *parent, const char *name = nullptr); + virtual ~GLBox(); + QAxAggregated *createAggregate() override; + +public slots: + void setXRotation(int degrees); +//! [1] + void setYRotation(int degrees); + void setZRotation(int degrees); + +protected: + void initializeGL() override; + void paintGL() override; + void resizeGL(int w, int h) override; + virtual GLuint makeObject(); + +private: + GLuint m_object = 0; + GLdouble m_xRot = 0; + GLdouble m_yRot = 0; + GLdouble m_zRot = 0; + GLdouble m_scale = 1.25; +}; + +#endif // GLBOX_H diff --git a/tests/manual/opengl/globjwin.cpp b/tests/manual/opengl/globjwin.cpp new file mode 100644 index 0000000..1e87032 --- /dev/null +++ b/tests/manual/opengl/globjwin.cpp @@ -0,0 +1,72 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#include "globjwin.h" +#include "glbox.h" +#include <QPushButton> +#include <QSlider> +#include <QLayout> +#include <QFrame> +#include <QMenuBar> +#include <QMenu> +#include <QApplication> + + +GLObjectWindow::GLObjectWindow(QWidget *parent) + : QWidget(parent) +{ + // Create a menu + QMenu *file = new QMenu(this); + file->addAction(tr("Exit"), qApp, &QApplication::quit); + + // Create a menu bar + QMenuBar *m = new QMenuBar(this); + m->addMenu(file)->setText(tr("&File")); + + // Create a nice frame to put around the OpenGL widget + QFrame *f = new QFrame(this); + f->setFrameStyle(QFrame::Sunken | QFrame::Panel); + f->setLineWidth(2); + + // Create our OpenGL widget + GLBox *c = new GLBox(f, "glbox"); + + // Create the three sliders; one for each rotation axis + QSlider *x = new QSlider(Qt::Vertical, this); + x->setMaximum(360); + x->setPageStep(60); + x->setTickPosition(QSlider::TicksLeft); + connect(x, &QSlider::valueChanged, c, &GLBox::setXRotation); + + QSlider *y = new QSlider(Qt::Vertical, this); + y->setMaximum(360); + y->setPageStep(60); + y->setTickPosition(QSlider::TicksLeft); + connect(y, &QSlider::valueChanged, c, &GLBox::setYRotation); + + QSlider *z = new QSlider(Qt::Vertical, this); + z->setMaximum(360); + z->setPageStep(60); + z->setTickPosition(QSlider::TicksLeft); + connect(z, &QSlider::valueChanged, c, &GLBox::setZRotation); + + // Now that we have all the widgets, put them into a nice layout + + // Top level layout, puts the sliders to the left of the frame/GL widget + QHBoxLayout *hlayout = new QHBoxLayout(this); + + // Put the sliders on top of each other + QVBoxLayout *vlayout = new QVBoxLayout(); + vlayout->addWidget(x); + vlayout->addWidget(y); + vlayout->addWidget(z); + + // Put the GL widget inside the frame + QHBoxLayout *flayout = new QHBoxLayout(f); + flayout->setContentsMargins(0, 0, 0, 0); + flayout->addWidget(c, 1); + + hlayout->setMenuBar(m); + hlayout->addLayout(vlayout); + hlayout->addWidget(f, 1); +} diff --git a/tests/manual/opengl/globjwin.h b/tests/manual/opengl/globjwin.h new file mode 100644 index 0000000..6b69db2 --- /dev/null +++ b/tests/manual/opengl/globjwin.h @@ -0,0 +1,24 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +/**************************************************************************** +** +** The GLObjectWindow contains a GLBox and three sliders connected to +** the GLBox's rotation slots. +** +****************************************************************************/ + +#ifndef GLOBJWIN_H +#define GLOBJWIN_H + +#include <qwidget.h> + +class GLObjectWindow : public QWidget +{ + Q_OBJECT + +public: + explicit GLObjectWindow(QWidget *parent = nullptr); +}; + +#endif diff --git a/tests/manual/opengl/main.cpp b/tests/manual/opengl/main.cpp new file mode 100644 index 0000000..2ea81da --- /dev/null +++ b/tests/manual/opengl/main.cpp @@ -0,0 +1,49 @@ +// Copyright (C) 2015 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only +// +// Qt OpenGL example: Box +// +// A small example showing how a GLWidget can be used just as any Qt widget +// +// File: main.cpp +// +// The main() function +// + +#include "globjwin.h" +#include "glbox.h" +#include <QApplication> +//! [0] +#include <QAxFactory> + +QAXFACTORY_BEGIN( + "{2c3c183a-eeda-41a4-896e-3d9c12c3577d}", // type library ID + "{83e16271-6480-45d5-aaf1-3f40b7661ae4}") // application ID + QAXCLASS(GLBox) +QAXFACTORY_END() + +//! [0] //! [1] +/* + The main program is here. +*/ + +int main(int argc, char *argv[]) +{ + QApplication a(argc,argv); + + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL) { + qWarning("This system does not support OpenGL. Exiting."); + return -1; + } + + if (!QAxFactory::isServer()) { + GLObjectWindow w; + w.resize(400, 350); + w.show(); + return a.exec(); +//! [1] //! [2] + } + return a.exec(); +//! [2] //! [3] +} +//! [3] diff --git a/tests/manual/opengl/opengl.def b/tests/manual/opengl/opengl.def new file mode 100644 index 0000000..bc82a03 --- /dev/null +++ b/tests/manual/opengl/opengl.def @@ -0,0 +1,6 @@ +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + DumpIDL PRIVATE diff --git a/tests/manual/opengl/opengl.ico b/tests/manual/opengl/opengl.ico Binary files differnew file mode 100644 index 0000000..c80d36a --- /dev/null +++ b/tests/manual/opengl/opengl.ico diff --git a/tests/manual/opengl/opengl.inf b/tests/manual/opengl/opengl.inf new file mode 100644 index 0000000..4a79e67 --- /dev/null +++ b/tests/manual/opengl/opengl.inf @@ -0,0 +1,9 @@ +[version] + signature="$CHICAGO$" + AdvancedINF=2.0 + [Add.Code] + openglax.exe=openglax.exe + [openglax.exe] + file-win32-x86=thiscab + clsid={5fd9c22e-ed45-43fa-ba13-1530bb6b03e0} + RegisterServer=yes diff --git a/tests/manual/opengl/opengl.pro b/tests/manual/opengl/opengl.pro new file mode 100644 index 0000000..1ece9b9 --- /dev/null +++ b/tests/manual/opengl/opengl.pro @@ -0,0 +1,18 @@ +TEMPLATE = app +TARGET = openglax + +CONFIG += warn_off +QT += widgets axserver opengl openglwidgets + +HEADERS = glbox.h \ + globjwin.h +SOURCES = glbox.cpp \ + globjwin.cpp \ + main.cpp + +RC_FILE = opengl.rc +DEF_FILE = opengl.def + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/activeqt/opengl +INSTALLS += target diff --git a/tests/manual/opengl/opengl.rc b/tests/manual/opengl/opengl.rc new file mode 100644 index 0000000..02c0898 --- /dev/null +++ b/tests/manual/opengl/opengl.rc @@ -0,0 +1,2 @@ +1 TYPELIB "opengl.rc" +1 ICON "opengl.ico" diff --git a/tests/manual/shared/metaobjectdump.cpp b/tests/manual/shared/metaobjectdump.cpp index 2eaec84..c383d3a 100644 --- a/tests/manual/shared/metaobjectdump.cpp +++ b/tests/manual/shared/metaobjectdump.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "metaobjectdump.h" diff --git a/tests/manual/shared/metaobjectdump.h b/tests/manual/shared/metaobjectdump.h index b3bde57..5051b99 100644 --- a/tests/manual/shared/metaobjectdump.h +++ b/tests/manual/shared/metaobjectdump.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef METAOBJECTDUMP_H #define METAOBJECTDUMP_H diff --git a/tests/manual/shared/shared.pri b/tests/manual/shared/shared.pri deleted file mode 100644 index ffd18b3..0000000 --- a/tests/manual/shared/shared.pri +++ /dev/null @@ -1,3 +0,0 @@ -SOURCES += $$PWD/metaobjectdump.cpp $$PWD/textdialog.cpp -HEADERS += $$PWD/metaobjectdump.h $$PWD/textdialog.h -INCLUDEPATH += $$PWD diff --git a/tests/manual/shared/textdialog.cpp b/tests/manual/shared/textdialog.cpp index f8ad7fc..4e1a5d1 100644 --- a/tests/manual/shared/textdialog.cpp +++ b/tests/manual/shared/textdialog.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include "textdialog.h" diff --git a/tests/manual/shared/textdialog.h b/tests/manual/shared/textdialog.h index 74bfaf5..930f608 100644 --- a/tests/manual/shared/textdialog.h +++ b/tests/manual/shared/textdialog.h @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtWidgets/QDialog> diff --git a/tests/manual/testcontrol/CMakeLists.txt b/tests/manual/testcontrol/CMakeLists.txt index 3115e4d..78e410c 100644 --- a/tests/manual/testcontrol/CMakeLists.txt +++ b/tests/manual/testcontrol/CMakeLists.txt @@ -1,20 +1,19 @@ -# Generated from testcontrol.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## testcontrol Binary: ##################################################################### -qt_add_executable(testcontrol +qt_internal_add_manual_test(tst_testcontrol_manual GUI SOURCES main.cpp - PUBLIC_LIBRARIES + testcontrol.rc + LIBRARIES Qt::AxServer Qt::Gui Qt::Widgets ) -qt_disable_warnings(testcontrol) - -#### Keys ignored in scope 1:.:.:testcontrol.pro:<TRUE>: -# RC_FILE = "testcontrol.rc" -# TEMPLATE = "app" +qt_disable_warnings(tst_testcontrol_manual) +qt6_target_idl(tst_testcontrol_manual) diff --git a/tests/manual/testcontrol/main.cpp b/tests/manual/testcontrol/main.cpp index bedd265..2a8a5f1 100644 --- a/tests/manual/testcontrol/main.cpp +++ b/tests/manual/testcontrol/main.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtAxServer/QAxFactory> #include <QtGui/QAction> diff --git a/tests/manual/testcontrol/testcontrol.pro b/tests/manual/testcontrol/testcontrol.pro deleted file mode 100644 index 30a0b48..0000000 --- a/tests/manual/testcontrol/testcontrol.pro +++ /dev/null @@ -1,6 +0,0 @@ -QT += widgets axserver -TARGET = testcontrol -TEMPLATE = app -SOURCES += main.cpp -CONFIG += warn_off -RC_FILE = testcontrol.rc diff --git a/tests/tests.pro b/tests/tests.pro deleted file mode 100644 index 157ef34..0000000 --- a/tests/tests.pro +++ /dev/null @@ -1,2 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS += auto |