Помогите: Работа со справочником СИ

Автор Dimastyj, 02.03.16, 22:54:52

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

Dimastyj

В справке "PartLibAPI.chm" есть примеры по работе с содержимым справочника.
Примеры представлены на Delphi и VisualStudio. Мне же нужно разобраться и адаптировать эти примеры под Embarcadero RAD Studio XE3.
На сколько я понимаю, для начала нужно PartlibClient.dll прогнать через утилиту tlibimp (или средствами среды разработки: Component -> Import Component... -> Import a Type Library -> ... -> Create Unit).
Я делал так в cmd: "tlibimp -C+ PARTLibClient.dll". После чего были сформированы библиотеки типов: PARTLibClient_TLB.h, PARTLibClient_TLB.cpp, BOSimple_TLB.h, BOSimple_TLB.cpp
Полученные библиотеки подключаем к проекту на RAD Studio.
В итоге имеем 2 прокта (на Visual Studio и Embarcadero) которые должны вывести кол-во изделий по маске "Болт", оба компилируются. В первом случае результат правильный - ненулевой, во втором выдает ноль.
Подскажите на этом простом примере что я делаю не так.



//--------------------------------------------------------
// Текст MVS
//--------------------------------------------------------

#include "stdafx.h"
#import "c:\Program Files (x86)\Common Files\ASCON Shared\BOSimple.dll" no_namespace
#import "c:\Program Files (x86)\ASCON\PartLib\Clients\PARTLibClient.dll"
#include <iostream>

long lCount=-1;
int _tmain(int argc, _TCHAR* argv[])
{
// Устанавливаем локализацию (для правильного отображения кириллицы в консоли)
setlocale(LC_ALL, "");
CoInitialize(NULL);
//Подключаемся к API справочника
PARTLibClient::IPARTLibProviderPtr pPLClient;
if(pPLClient.CreateInstance(__uuidof(PARTLibClient::BOSimpleProvider))==0)
{
         BSTR errorStr;
         //Подключаемся к серверу приложений
         if (pPLClient->Connect(&errorStr)==0)
{
                 //Получаем указатель на основной интерфейс для доступа к изделиям и папкам в справочнике
                 PARTLibClient::ICommonDataPtr cd = pPLClient->CreateCommonDataObj();  
                 //Ищем класс с именем Болт во свем хранилище
lCount=cd->FindByName(L"Болт", L"")->Count();
std::wcout <<L"lCount = "<< lCount <<std::endl;

         }
         else {
                 std::wcout<<L"Error! Unable to find COM object."<<std::endl<<errorStr<<std::endl;
         }
}
else
         std::wcout<<L"Error! Cannot create instance."<<std::endl;
system("pause");
return 0;
}
//--------------------------------------------------------



//--------------------------------------------------------
// Текст Embarcadero RAD Studio XE3
//--------------------------------------------------------

#pragma hdrstop
#pragma argsused

#include <tchar.h>
#include <stdio.h>

#include "BOSimple_TLB.h"
#include "PARTLibClient_TLB.h"
#include <iostream>

long lCount=-1;
int _tmain(int argc, _TCHAR* argv[])
{
// Устанавливаем локализацию (для правильного отображения кириллицы в консоли)
setlocale(LC_ALL, "");
CoInitialize(NULL);
//Подключаемся к API справочника
Partlibclient_tlb::IPARTLibProviderPtr pPLClient;
/*  конструкция if(pPLClient.CreateInstance(__uuidof(Partlibclient_tlb::BOSimpleProvider))==0) не отрабатывает, а та, что ниже, работает */
if(pPLClient.CreateInstance(Partlibclient_tlb::CLSID_BOSimpleProvider)==0)
{
  BSTR errorStr;
  long value;
  if(pPLClient->Connect(&errorStr,&value)==0)
  {
   //Получаем указатель на основной интерфейс для доступа к изделиям и папкам в справочнике
Partlibclient_tlb::ICommonDataPtr cd; // можно и так Partlibclient_tlb::ICommonData *cd;
pPLClient->CreateCommonDataObj(&cd); //(&cd);
  //Ищем класс с именем Болт во свем хранилище
Partlibclient_tlb::IClassCollectionPtr FindResult;
cd->FindByName(L"Болт", L"", &FindResult);
FindResult->Count(&lCount);
std::wcout <<L"lCount = "<< lCount <<std::endl;
  }
  else
  {
   std::wcout<<L"Error! Unable to find COM object."<<std::endl<<errorStr<<std::endl;
  }
}
else
  std::wcout<<L"Error! Cannot create instance."<<std::endl;
system("pause");
return 0;
}
//--------------------------------------------------------

Slaviation

А с возвращаемым от CreateCommonDataObj значением все ок?

Dimastyj

Да, вроде бы с возвращаемым значением все ок, ненулевое.
Более того, болтов не находит, но соединение вроде как установлено, при поптке считать описание папки - есть результат такой же что и на VS если то же самое там сделать

cd->FindByName(L"Болт", L"", &FindResult);
FindResult->Count(&lCount);
std::wcout <<L"lCount = "<< lCount <<std::endl;


BSTR valueStr;
Partlibclient_tlb::IFolderPtr result;
cd->RootFolder(&result);
result->Description(&valueStr);
std::wcout<<L"RootFolder.Description = "<<valueStr<<std::endl;
result->DisplayName(&valueStr);
std::wcout<<L"RootFolder.DisplayName = "<<valueStr<<std::endl;

Dimastyj

Вот мои исходники на VS и XE3 с _TLB-шками.
странно, что при конструкции на XE3 как на VS

if(pPLClient.CreateInstance(__uuidof(Partlibclient_tlb::BOSimpleProvider))==0)

мы в эту ветку не попадаем вообще.
поэтому пишу так

if(pPLClient.CreateInstance(Partlibclient_tlb::CLSID_BOSimpleProvider)==0)

но в этом случае при запущенных "Справочниках" выдает ошибку, на VS работает и при запущенном приложении

Dimastyj

Товарищи, никто не подскажет по моему вопросу? пожалуйста

podshibyakinea

Что нужно? Библиотеку к справочнику СИ подключить?

podshibyakinea

unit main;

interface

uses Windows, sysutils, messages, comobj, LDefin2D, ksConstTLB, ksAuto, ksTLB,
  Forms;

procedure LIBRARYENTRY(command: WORD); Pascal;
function LIBRARYNAMEW: PWideChar; Pascal;

// ссылки на КОМПАС и 2D документ
var
  iKompas: KompasObject;
  iDocument2D: ksDocument2D;
  iDocumentParam: ksDocumentParam;
  iStamp: ksStamp;
  iViewParam: ksViewParam;
  iTextItemParam: ksTextItemParam;
  iTextItemFont: ksTextItemFont;
  n: integer;
  scale: Double;

implementation

uses BOSimple_TLB, PARTLibClient_TLB;

function LIBRARYNAMEW: PWideChar; pascal;
begin
  // название библиотеки
  Result := 'Библиотека выбора заготовки';
end;
//    начало!!
function GetDesignation : string;
const  LProvider = 'PartLibClient.BOSimpleProvider';
var
  CID, OID :WideString;
  BOPARTLib :IPARTLIbProvider;
  IBOB, tempIBOB :IBOObject;
  i :integer;
  errMess :WideString;
  LLocation,inlocation:WideString;
begin
  try
    try
//      LLocation := edt1.Text;
      BOPARTLib := CreateOleObject(LProvider) as IPARTLIbProvider;
      if BOPARTLib.Select( true, LLocation, 0) = false then exit;
//      edt1.Text := LLocation;
      BOPARTLib.GetObjectInfo(LLocation, CID, OID);
      IBOB := BOPARTLib.GetObject(CID, OID, 0);
      for i := 0 to IBOB.Objects.Count-1 do
        begin
          tempIBOB := IBOB.Objects.Item[i];
//          mmo1.Lines.Add(tempIBOB.ClassID + ' = ' + tempIBOB.Attribute['Value'].Value);
          // ищем обозначение
          if tempIBOB.ClassID = 'Designation' then
            Result := tempIBOB.Attribute['Value'].Value;
//          // ищем Шаблон спецификации КОМПАС
//          if tempIBOB.ClassID = 'KOMPAS_SPEC_PATTERN' then
//            spc_pattern := tempIBOB.Attribute['Value'].Value;
        end;
    except
      on E:Exception do
        iKompas.ksMessage(E.Message + #10'Не могу инициализировать ' + LProvider);
    end;
  finally
    BOPARTLib.Disconnect; // отключаемся от ССП
  end;
end;