На главную... Продукты | Технологии | Классификаторы | Проекты | Скачать | Цены| Форум | Статьи | Обучение | Контакты

Падение в корку при использовании связки QT+mingw+ActiveX+mapapi

Поиск  Пользователи  Правила  Войти
Форум » Настольные приложения » GIS ToolKit, GIS ToolKit Active, ГИС Конструктор для Windows
Страницы: 1
RSS
Падение в корку при использовании связки QT+mingw+ActiveX+mapapi, вопросики накопились
 
делаю тестовый проект используя:

компоненты ActiveX GIS ToolKit Active 13.0.2
библиотеки Qt 5.14.2
mingw 7.3.0 x64
ОС Windows10x64

библиотеки загружаются динамически и ActiveX подключается следующим образом:

#define CLSID_MapView "{f200d06e-b99e-470e-8378-e0583b1d12ff}"
#define gis64accesPath "C:\\Program Files\\Panorama\\GISToolActive13\\GisDll\\X64\\gis64acces.dll"
#define gis64vecexPath "C:\\Program Files\\Panorama\\GISToolActive13\\GisDll\\X64\\gis64vecex.dll"
  gis64acces = new QLibrary(gis64accesPath);
   gis64acces->load();
   mapGetDrawScale = (_mapGetDrawScale) gis64acces->resolve("mapGetDrawScale");
gis64vecex = new QLibrary(gis64vecexPath);
   gis64vecex->load();
   ImportFromAnySxfEx = (_ImportFromAnySxfEx) gis64vecex->resolve("ImportFromAnySxfEx");
ui->axWidget->setControl( CLSID_MapView);
   QObject::connect(this, SIGNAL(signal_MapOpen(QString, bool)), ui->axWidget,
                    SLOT(MapOpen(QString, bool)));
   QObject::connect(ui->axWidget,SIGNAL(OnMapMouseMove(int, double, double, double)), this,
                    SLOT(MapViewMouseMove(int, double, double, double)));
   QObject::connect(ui->axWidget,SIGNAL(OnMapOpen()), this,
                    SLOT(MapViewMapOpen()));

прототипы функций описаны следующим образом:

   typedef double (*_mapGetDrawScale)(HMAP);    _mapGetDrawScale mapGetDrawScale;
typedef long int (*_ImportFromAnySxfEx)(HMAP hmap, const char * sxfname,
                                           const char * rscname, char * mapname,
                                           long int size, HMESSAGE handle,
                                           HSELECT select, long int frscfromsxf);
   _ImportFromAnySxfEx ImportFromAnySxfEx;
typedef double (*_mapGetHeightValueOfMtr)(HMAP hMap, long int number,
                                             double x, double y);
   _mapGetHeightValueOfMtr mapGetHeightValueOfMtr;
typedef long int (*_mapGetRstPlanePointColor)(HMAP hMap, long int number,
                                                 COLORREF *color, double x, double y);
   _mapGetRstPlanePointColor mapGetRstPlanePointColor;
typedef long int (*_mapPlaneToGeoWGS84)(HMAP hmap, double *Bx, double *Ly);
   _mapPlaneToGeoWGS84 mapPlaneToGeoWGS84;
typedef void (*_mapRadianToDegree)(double *radian, GEODEGREE *degree);
   _mapRadianToDegree mapRadianToDegree;
typedef long int (*_mapPlaneToGeo42)(HMAP hmap, double *Bx, double *Ly);
   _mapPlaneToGeo42 mapPlaneToGeo42;

mapGetDrawScale отрабатывает без проблем
при попытке использовать mapPlaneToGeoWGS84, mapPlaneToGeo42 валится без сообщений
при использовании mapRadianToDegree получаю AccessValation

хэндл на карту получаю вот так:
hMap = (HMAP)ui->axWidget->property("MapHandle").toLongLong();

параметры выходных координат устанавливаю вот так:
   ui->axWidget->setProperty("PlaceOut", PP_PICTURE);
в документации на ActiveX сказано:

Применяемая система
координат

Значения

PP_MAP        = $0000;        //  Координаты точек в системе карты в дискретах

PP_PICTURE = $0001;        //  Координаты точек в системе изображения в пикселях

PP_PLANE        = $0002;        //  Координаты точек в плоской прямоугольной  системе на местности в  метрах

PP_GEO        = $0003;        //  Координаты точек в геодезических координатах в радианах

PP_GEOWGS84        = $0004;        // Координаты  точек в геодезических координатах в радианах WGS84

однако в maptype.h

enum PPLACE            // ПРИМЕНЯЕМАЯ СИСТЕМА КООРДИНАТ
{
  PP_MAP      = 1,    // КООРДИНАТЫ ТОЧЕК В СИСТЕМЕ КАРТЫ В ДИСКРЕТАХ
  PP_PICTURE  = 2,    // КООРДИНАТЫ ТОЧЕК В СИСТЕМЕ ИЗОБРАЖЕНИЯ В ПИКСЕЛАХ
  PP_PLANE    = 3,    // КООРДИНАТЫ ТОЧЕК В ПЛОСКОЙ ПРЯМОУГОЛЬНОЙ СИСТЕМЕ
                      // НА МЕСТНОСТИ В МЕТРАХ
  PP_GEO      = 4,    // КООРДИНАТЫ ТОЧЕК В ГЕОДЕЗИЧЕСКИХ КООРДИНАТАХ
                      // В РАДИАНАХ
  PP_GEOWGS84 = 8,    // КООРДИНАТЫ ТОЧЕК В ГЕОДЕЗИЧЕСКИХ КООРДИНАТАХ
                      // В РАДИАНАХ В СИСТЕМЕ WGS-84

         

};

ActiveX компонент выдает координаты в метрах при установленном параметре  $0002 что в maptype соответствует PP_PICTURE

Вопрос: Почему валяться могучие функции и что предпринять в этом случае?
 
Ошибку нашел))
всем спасибо)

функции не резолвелись в библиотеки, надо делать вот так :  ImportFromAnySxfEx = (_ImportFromAnySxfEx) gis64vecex->resolve("ImportFromAnySxfEx");
Изменено: Григорий Боголепов - 02.10.2020 12:14:11
 
Продолжаем разговор)
пытаюсь вызвать диалог выбора объектов
делаю так:

#define CLSID_axMapSelectDialog     "{013681CF-981D-4AB8-9321-385BAABF1DC5}"

   axMapSelectDialog = new QAxObject();
   axMapSelectDialog->setControl( CLSID_axMapSelectDialog);
   QObject::connect(this, SIGNAL(signal_MapSelectDialogExecute(IDispatch*, bool)), axMapSelectDialog,
                    SLOT(Execute(IDispatch*, bool)));
   ui->axMapView->setProperty("Selecting", true);
   emit signal_MapSelectDialogExecute((IDispatch*)ui->axMapView->querySubObject("ViewSelect"),true);

результат: падение     void *_a[] = { nullptr, const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t1))), const_cast<void*>(reinterpret_cast<const void*>(std::addressof(_t2))) };    QMetaObject::activate(this, &staticMetaObject, 1, _a);
и абракадабра в консоле:

onecore\com\combase\dcomrem\security.cxx(3057)\combase.dll!00007FFFFD78632C: (caller: 00007FFFD75980AE) ReturnHr(1) tid(610) 80010117 Íå óäàåòñÿ ïîëó÷èòü äîñòóï ê êîíòåêñòó âûçîâà ïîñëå çàâåðøåíèÿ âûçîâà.

onecore\com\combase\dcomrem\security.cxx(3057)\combase.dll!00007FFFFD78632C: (caller: 00007FFFD75980AE) ReturnHr(2) tid(610) 80010117 Íå óäàåòñÿ ïîëó÷èòü äîñòóï ê êîíòåêñòó âûçîâà ïîñëå çàâåðøåíèÿ âûçîâà.

 
переписал, добавил инициализацию указателей на объект MapView

   ui->axMapView->setProperty("Selecting", true);
   axMapView = ui->axMapView->querySubObject("C_CONTAINER");
   axMapSelect = ui->axMapView->querySubObject("ViewSelect");
   axMapSelectDialog = new QAxObject();    axMapSelectDialog->setControl( CLSID_axMapSelectDialog);
   axMapSelectDialog->setProperty("cMapView",axMapView->asVariant());
   QObject::connect(this, SIGNAL(signal_MapSelectDialogExecute(IDispatch*, bool)), axMapSelectDialog,
                    SLOT(Execute(IDispatch*, bool)));
   emit signal_MapSelectDialogExecute((IDispatch*)axMapSelect,true);

результат тот же((
 
Такая комбинация программных средств для работы с диалогами в Windows не тестировалась. Только Visual Studio и Embarcadero.
 
Цитата
Oleg Belenkov написал:
Такая комбинация программных средств для работы с диалогами в Windows не тестировалась. Только Visual Studio и Embarcadero.
это не может не радовать
вопрос: каким образом в данной комбинации программных средств в Windows получить могучий диалог выбора условий поиска?
обработчики исключений через сигнал не срабатывают

   QObject::connect(axMapSelectDialog, SIGNAL(exception(int, QString, QString, QString)), this,                     SLOT(on_exception(int, QString, QString, QString)));


void MainWindow::on_exception(int code, QString source, QString disc, QString help)
{
   qDebug()<<code;
   qDebug()<<source;
   qDebug()<<disc;
   qDebug()<<help;
}
Изменено: Григорий Боголепов - 05.10.2020 11:42:31
 
Цитата
Oleg Belenkov написал:
Такая комбинация программных средств для работы с диалогами в Windows не тестировалась. Только Visual Studio и Embarcadero.

Не смотря на это нет никаких ограничений на использование GIS ToolKit Active в любых средах, поддерживающих технологию ActiveX.
Qt не исключение.
При правильном связывании компонентов между собой, при корректной передаче параметров и работе с интерфейсами всё должно работать.
Проблемы могут возникнуть, если среда разработки начинает "умничать" и оборачивать передаваемые параметры в свои типы, что может быть не совместимо с внутренней реализацией компонентов.
Для того, чтобы не напутать ничего с типами параметров и интерфейсами, рекомендуется импортировать библиотеку типов.

Цитата
Григорий Боголепов написал:
переписал, добавил инициализацию указателей на объект MapView

Qt не владею, но визуально по шагам реализация вроде бы правильная.
Подозреваю, что проблема тут как раз на уровне того, как берется интерфейс IMapSelect из MapView и передается в MapSelectDialog.

В Visual Studio с этим нет никаких проблем. Вот фрагмент примера из инсталляции:
Код
       private void btnSelect_Click(object sender, EventArgs e)
        {
            axGisToolKit.TxColorRef  aColor = new axGisToolKit.TxColorRef();
            aColor.Blue = 128; // тёмно-синий
            MapSelectDialog.SeekVisual = true;
            MapSelectDialog.ShowAllFromRSC = true;
            if (MapFindObject.Active) MapFindObject.Active = false;

            if (sender == btnSelDglObj)
               MapSelectDialog.Note = 1;
            else
            if (sender == btnSelDglSem)
                MapSelectDialog.Note = 4;
            else 
            if (sender == btnSelDglParm)
                MapSelectDialog.Note = 5;
            else
                MapSelectDialog.Note = 0;

            if (MapSelectDialog.Execute(MapFindObject.cMapSelect, true))
                if (MapSelectDialog.ModalResult == 12) // выделить
                    mvMap.SetObjSelected(MapFindObject.cMapSelect, aColor, true);
        }


Насколько мне известно, разработчики Qt для работы с ActiveX используют QAxObject.

Диалог можно вызывать и непосредственно из ГИС-ядра посредством обращения к MAPAPI-функции из библиотеки gis64selec.dll:
Код
 // Установить фильтр отображаемых объектов карты
 // hmap    - идентификатор открытой векторной карты
 // parm    - параметры задачи (см. maptype.h)
 // note    - адрес переменной,определяющей вид окна и содержащей
 //           индекс активной закладки при старте программы фильтра (допустимо note = 0).
 // restoremode - флаг восстановления контекста отображения карты :
 //           "-1" - стандартно восстановить контекст отображения;
 //           "0"  - использовать текущее состояние контекста отображения.
 // Если фильтр изменился, возвращает ненулевое значение
 // Help вызывается из mapselec.chm, топик "USTANOVKA"

 long int  WINAPI selSetViewStaffEx(HMAP hmap,TASKPARMEX* parm,
                                    long int* note,long int restoremode);


Таким образом можно обойтись без передачи интерфейсов в методы, но лучше с этим вопросом всё же разобраться, так как в GIS ToolKit Active это встречается довольно таки часто.
 
Цитата
Денис Вицко написал:
Диалог можно вызывать и непосредственно из ГИС-ядра посредством обращения к MAPAPI-функции из библиотеки gis64selec.dll:Код // Установить фильтр отображаемых объектов карты
// hmap    - идентификатор открытой векторной карты
// parm    - параметры задачи (см. maptype.h)
// note    - адрес переменной,определяющей вид окна и содержащей
//           индекс активной закладки при старте программы фильтра (допустимо note = 0).
// restoremode - флаг восстановления контекста отображения карты :
//           "-1" - стандартно восстановить контекст отображения;
//           "0"  - использовать текущее состояние контекста отображения.
// Если фильтр изменился, возвращает ненулевое значение
// Help вызывается из mapselec.chm, топик "USTANOVKA"

long int  WINAPI selSetViewStaffEx(HMAP hmap,TASKPARMEX* parm,
                                   long int* note,long int restoremode);
:)  ковыряю дальше, как получится-отпишу
 
В общем для потомков))
заработало вот так:

   QVariantList params;    params.append(ui->axMapView->querySubObject("ViewSelect")->asVariant());
   params.append(true);
   bool result = axMapSelectDialog->dynamicCall("Execute(IDispatch*, bool)", params).toBool();

ну и библиотеку gis64selec.dll по путям положить не забудьте

странно что механизм сигнал-слот вызывает падение а dynamicCall нет, обычно всё наоборот)))
Изменено: Григорий Боголепов - 05.10.2020 12:23:28
Страницы: 1
Читают тему (гостей: 1)



© КБ Панорама, 1991-2024

Регистрируясь или авторизуясь на форуме, Вы соглашаетесь с Политикой конфиденциальности