Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++ Qt
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/3: Рейтинг темы: голосов - 3, средняя оценка - 4.67
lell3
1 / 1 / 0
Регистрация: 29.08.2016
Сообщений: 43
1

ActiveX-control

02.08.2017, 10:34. Просмотров 629. Ответов 1

Добрый день, уважаемые форумчане.

Передо мной стоит задача разработать ActiveX-control на Qt, которая позволяла бы элементу графическом интерфейса на Delphi включить в себя виджет на Qt.

Использую следующий материал: Бланшет, Саммерфилд - Qt 4. Программирование GUI на C++[1], документацию по Qt5 http://doc.qt.io/qt-5/activeqt-activeqt-wrapper-example.html[2].

Создал простой виджет – электронные часы. При нажатии на кнопку старт/стоп запускает/останавливается таймер, по таймауту которого обновляется QtimeEdit и испускается тестовый сигнал someSignal. Так же при нажатии происходит запрос у клиента разрешение на изменение свойства и уведомление клиента об изменении свойства.

Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//Widget.h
#ifndef WIDGET_H
#define WIDGET_H
 
#include <QWidget>
#include <QAxBindable>
namespace Ui
{
    class Widget;
}
 
class Widget : public QWidget, public QAxBindable
{
    Q_OBJECT
    Q_PROPERTY(bool running READ isRunning)
 
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    bool isRunning() const { return running; }
    QAxAggregated *createAggregate();
 
private slots:
    void on_btnStart_clicked();
    void setTime();
    void on_btnStop_clicked();
signals:
    void someSignal();
 
private:
    Ui::Widget *ui;
    QTimer* timer;
    bool running;
};
#endif // WIDGET_H


Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//Widget.cpp
#include <QTimer>
#include "widget.h"
#include "ui_widget.h"
#include "objectsafetyimpl.h"
 
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{
    ui->setupUi(this);
    running =false;
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), SLOT(setTime()));
}
 
Widget::~Widget()
{
    delete timer;
    delete ui;
}
 
void Widget::on_btnStart_clicked()
{
    if (requestPropertyChange("running"))
    {
        timer->start(1000);
        running =true;
        propertyChanged("running");
    }
}
 
void Widget::on_btnStop_clicked()
{
    if (requestPropertyChange("running"))
    {
        timer->stop();
        running =false;
        propertyChanged("running");
    }
}
 
void Widget::setTime()
{
    emit someSignal();
    ui->timeEdit->setTime( QTime::currentTime());
}
 
QAxAggregated *Widget::createAggregate()
{
    return new ObjectSafetyImpl;
}


В классе Widget, унаследованном от QaxBindable переопределен виртуальный метод createAggregate(), который возвращает указатель на созданный экземпляр класса QaxAggregated. Код класса QaxAggregated взять из источника 1.

Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//objectsafetyimpl.h
#ifndef OBJECTSAFETYIMPL_H
#define OBJECTSAFETYIMPL_H
 
#include <QAxAggregated>
#include <objsafe.h>
 
class ObjectSafetyImpl : public QAxAggregated, public IObjectSafety
{
public:
    long queryInterface(const QUuid &iid, void **iface);
 
    QAXAGG_IUNKNOWN
 
    HRESULT WINAPI GetInterfaceSafetyOptions(REFIID riid,
            DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions);
    HRESULT WINAPI SetInterfaceSafetyOptions(REFIID riid,
            DWORD pdwSupportedOptions, DWORD pdwEnabledOptions);
};
 
#endif
 
//objectsafetyimpl.cpp
#include <QtWidgets>
#include "objectsafetyimpl.h"
 
long ObjectSafetyImpl::queryInterface(const QUuid &iid, void **iface)
{
    *iface = 0;
    if (iid == IID_IObjectSafety)
    {
        *iface = static_cast<IObjectSafety *>(this);
    }
    else
    {
        return E_NOINTERFACE;
    }
    AddRef();
    return S_OK;
}
 
HRESULT WINAPI ObjectSafetyImpl::GetInterfaceSafetyOptions(
        REFIID /* riid */, DWORD *pdwSupportedOptions,
        DWORD *pdwEnabledOptions)
{
    *pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA
                           | INTERFACESAFE_FOR_UNTRUSTED_CALLER;
    *pdwEnabledOptions = *pdwSupportedOptions;
    return S_OK;
}
 
HRESULT WINAPI ObjectSafetyImpl::SetInterfaceSafetyOptions(
        REFIID /* riid */, DWORD /* pdwSupportedOptions */,
        DWORD /* pdwEnabledOptions */)
{
    return S_OK;
}


Для получения идентификаторов GUID (Class, IIDClass, IIDInterface, IIDEvents, IIDTypeLib, IIDApp) использую guidgen.
После 5 итераций генерации GUID получаю 5 идентификаторов и их использую в макросе QAXFACTORY_DEFAULT

Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
//main.cpp
#include <QAxFactory>
#include "widget.h"
 
QAXFACTORY_DEFAULT(Widget,                                      //Class
                   "{A0F471B4-9AB7-460C-AE1B-E51DEB31945A}",    //IIDClass
                   "{ EFE358E1-A4DB-4463-88F4-B5F3F25EBA26}",  //IIDInterface
                   "{80B0A938-B52C-4365-ADA1-2A60315B439B }",    //IIDEvents
                   "{F2AA4DE2-D41D-484B-B9CB-2A3FC413B126}",    //IIDTypeLib
                   "{4C568B33-C507-4AEE-BC7C-98C50CEF24A7}")    //IIDApp


Последнее, закидываю в директорию проекта файлы qaxserver.rc(файлы взяты из источника [1], в содержимом изменяю имя файла pro) и qaxserver.def.

Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//testActiveQt.pro
QT += axserver
TARGET = testActiveQt
TEMPLATE      = lib
CONFIG       += dll
 
 
SOURCES +=  main.cpp\
            widget.cpp \
            objectsafetyimpl.cpp
 
HEADERS  += widget.h \
            objectsafetyimpl.h
 
FORMS    += widget.ui
 
RC_FILE   = qaxserver.rc
DEF_FILE  = qaxserver.def


При попытки скомпилировать QtCreator выдает следующее [debug\testActiveQt.dll] Error 5 (ignored).
Как это исправить?

Забегая вперед попрошу помочь в тестировании этого кода. Как подключить этот ActiveX к другому проекту Qt?
Предположу что в другом приложении Qt нужно сделать следующее:
C++ (Qt)
1
2
    QaxWidget* wmp = new QAxWidget;
    wmp->setControl("{A0F471B4-9AB7-460C-AE1B-E51DEB31945A}",    //IIDClass
Предварительно включив в проект библиотеку и заголовочные файлы.

Однако работая с готовыми примерами Qt Creator выдает QAxBase::setControl: requested control {5e2461aa-a3e8-4f7a-8b04-307459a4c08c} could not be instantiated.

Компилятора под Delphi нет, поэтому, если предоставите проект под Delphi , который отобразит мой ActiveX-control буду премного благодарен.

Добавлено через 17 часов 51 минуту
Несмотря на "[debug\testActiveQt.dll] Error 5 (ignored)" dll собралась.
Далее полученные файлы libtestActiveQt.a, testActiveQt.dll помещаю в С:/Windows/System32 и в командной строке вбиваю команду С:/Windows/System32/regsvr32.exe С:/Windows/System32/testActiveQt.dll , которая регистрирует GUID в windows.
Появляется сообщение "Не удалось загрузить модуль "c:/.../testActiveQt.dll." Не найден указанный модуль."

Вбивая команду команду "С:/Windows/System32/regsvr32.exe С:/Windows/System32/libtestActiveQt.a" Появляется сообщение "Возможно модуль не совместим с версией Windows"

Добавлено через 2 минуты
Аналогично если работать с директорией SysWOW64
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.08.2017, 10:34
Ответы с готовыми решениями:

ActiveX + Qt + Excel
Добрый вечер (надеюсь =) ) Немедля перейду к проблеме, чтобы не отнимать Ваше время. Итак,...

Qt+ActiveX+word
Подскажите как с помощью ActiveX перейти в word на закладку и начиная с закладки считать данные из...

ActiveX Чего-то не хватает
Пытаюсь разобраться с ActiveQt #include &lt;QtGui&gt; #include &lt;ActiveQt\QAxBase.h&gt; #include...

Qt + COM (ActiveX) = Властелин упрвления сервером 1С предприятия
Доброго времени суток господа! Хочется общаться с 1С сервером через COM, т.е. подключиться,...

Qt ActiveX или взаимосвязь с посторонним приложением
Доброго времени суток. Пред история: Написав на C++ Builder Activex Object все вполне...

1
Operok
179 / 177 / 66
Регистрация: 15.02.2015
Сообщений: 511
Завершенные тесты: 2
02.08.2017, 10:50 2
Точно не знаю как реализована работа с COM в qt, но в вашей dll обязательно должны быть экспортированы функции: DllRegisterServer, DllUnregisterServer и DllGetClassObject. Регистрировать DLL желательно из того места, где она потом будет и лежать (в реестр записывается путь к ней), и не стоит кидать её в System32.
По идее для работы с зарегистрированным ActiveX объектом хедеры и dll (не надо класть её рядом с .exe) для клиента уже не нужны (работаем через интерфейс IDispatch).
1
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.08.2017, 10:50

ActiveX Перейти в начало Word-документа
Заполняю документ QAxObject *W = new QAxObject(&quot;Word.Application&quot;); // Создаю интерфейс к MSWord...

ActiveX Bridje или как превращать ActiveX Control в JavaBean.
Насколько я понял из документации, эта штука позволяет превращать JavaBean в ActiveX Control с...

ActiveX Control
Ребят,подскажите если не кодом то хоть где конкретно можно найти информацию. Необходимо:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru