Войти

Показать полную графическую версию : Import *.tlb - как потом использовать полученный *.h ? (C++ Builder 2009)


Sanchos
13-06-2009, 21:36
Нужно подключить tlb файл от CorelDRAW, чтобы управлять корелом из С++ приложения...
Импортнул этот tlb и получил файлыЖ
VGCore_OCX.dcr
VGCore_TLB.cpp
VGCore_TLB.h

Вставил в проект, добавил #include "VGCore_TLB.h", а как дальше использовать, нехватает мозгов :(
Нужно как то подключится к IID_IVGApplication

В VGCore_TLB.cpp есть:

namespace Vgcore_tlb
{
....
const GUID IID_IVGApplication = {0xB058000B, 0x9AA4, 0x44FD,{ 0x95, 0x47, 0x4F,0x91, 0xEB, 0x75,0x7A, 0xC4} };
....
}

В VGCore_TLB.h:

namespace Vgcore_tlb
{
...
extern __declspec (package) const GUID IID_IVGApplication;
...
interface DECLSPEC_UUID("{B058000B-9AA4-44FD-9547-4F91EB757AC4}") IVGApplication;
typedef TComInterface<IVGApplication, &IID_IVGApplication> IVGApplicationPtr;
...
}

Есть у кого какие мысли по этому поводу?
Зарание благодарен.

pva
23-06-2009, 11:29
дальше создаёшь объект (не забудь CoInitialize) при помощи функции CoCreateInstance и используешь его. Вот вырезка из моей самописной библиотеки, адаптированная для твоего кода:

void Variant::check(HRESULT hr)
{
if (hr)
{
char *ddstr;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
0, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*) &ddstr, 0, 0);

std::string result(ddstr);
LocalFree(ddstr);

throw std::runtime_error(result);
}
}

Variant Variant::createObject(CLSID& clsid)
{
IDispatch* disp = 0;

for(;;)
{
unsigned hr = CoCreateInstance(clsid, 0,
CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER,
IID_IDispatch, &(void*)disp);

if (hr!=0x800401F0) // если вызван CoInitialize()
{
check(hr);
break;
}

CoInitialize(0);
}

return Variant(disp);
}

Потом используешь интерфейс IDispatch чтобы управлять кодом на макроязыке.
dispatchbot.h

#ifndef coobjectH
#define coobjectH
#include <variant.h>
#include <strings.h>
#include <memory>
#include <string>
#include <vector>
//------------------------------------------

class DispatchBot
{
IDispatch* fdisp;
mutable Variant fresult;
std::vector<Variant> fargs;
std::vector<std::wstring> fnames;
mutable std::vector<DISPID> fdispids;

void resetArgs();
void compile() const;
void invoke(int) const;

public:
DispatchBot();
~DispatchBot();

DispatchBot& addArg(const Variant&);
DispatchBot& addNamedArg(const std::wstring& w, const Variant&);
DispatchBot& member(Variant& obj, const std::wstring&);
DispatchBot& member(const std::wstring&);
void put(const Variant& v);
void execute();
Variant& oleArg(int n);
Variant& get();

DispatchBot& operator()(const Variant& v) {return addArg(v);}
DispatchBot& operator()(const std::wstring& w, const Variant& v) {return addNamedArg(w, v);}
DispatchBot& operator[](const std::wstring& w) {return member(w);}
Variant& operator*() {return get();}
Variant& operator()() {execute();return fresult;}
void operator=(const Variant& v) {put(v);}
};
//------------------------------------------
#endif

dispatchbot.cpp

#include <dispatchbot.h>
#include <sstream>
/*-----------------29.03.2006 23:00-----------------
* Класс для работы с IDispatch (ActiveX)

DispatchBot bot;
result = bot.member(object1, L"Method")(); // запуск метода
result = *bot.member(object1, L"Property"); // взятие свойства
bot.member(object1, L"Property") = value; // изменение свойства
bot.member(object1, L"Class1")[L"Class2"][L"Class3"]... // движение по вложенным агрегатам
bot.member(object1, L"Method_or_property")(value1)(value2)... // аргументы
bot.member(object1, L"Method_or_property")(L"Name1", value1)(L"Name1", value2)... // аргументы с именем

* можно действовать вперемешку.
* --------------------------------------------------*/

DispatchBot::DispatchBot() :
fdisp()
{
}

DispatchBot::~DispatchBot()
{
if (fdisp) fdisp->Release();
}

Variant& DispatchBot::oleArg(int n)
{
return fargs.at(n);
}

DispatchBot& DispatchBot::addArg(const Variant& v)
{
std::vector<Variant>::iterator a = fargs.begin();
std::advance(a, fnames.size()-1);
fargs.insert(a, v);
return *this;
}

DispatchBot& DispatchBot::addNamedArg(const std::wstring& w, const Variant& v)
{
addArg(v);
fnames.push_back(w);
return *this;
}

void DispatchBot::compile() const
{
// аргументы хранятся в args в следующем порядке:
// сначала поименованные, затем по порядку.
// в векторе fnames сначала идёт имя класса-агрегата,
// свойства или метода, затем имена аргументов.
// Таким образом, имён на 1 больше, чем именованных аргументов.

if (fdispids.empty()) // not empty when compiled
{
fdispids.resize(fnames.size());

// аргумент для IDispatch::GetIDsOfNames()
std::vector<const wchar_t*> wt;
wt.reserve(fnames.size());
for (unsigned i=0; i<fnames.size(); i++) wt.push_back(fnames[i].c_str());

Variant::check(fdisp->GetIDsOfNames(IID_NULL, const_cast<wchar_t**>(&wt[0]),
wt.size(), LOCALE_SYSTEM_DEFAULT, &fdispids[0]));
}
}

void DispatchBot::invoke(int action) const
{
// запуск и сообщение об ошибке

DISPPARAMS params;
EXCEPINFO exceptn;
unsigned err_arg;

params.cArgs = fargs.size();
params.rgvarg = (VARIANT*)&fargs[0];
params.cNamedArgs = fdispids.size()-1;
params.rgdispidNamedArgs = &fdispids[1];

// были проблемы, если не сбрасывать результат.
fresult.reset();

if (fdisp->Invoke(fdispids[0], IID_NULL, LOCALE_USER_DEFAULT,
action, &params, (VARIANT*)&fresult, &exceptn, &err_arg))
{
std::stringstream errmsg;

const char* str_action;
switch (action)
{
case DISPATCH_METHOD: str_action = "exec"; break;
case DISPATCH_PROPERTYGET: str_action = "get"; break;
case DISPATCH_PROPERTYPUT: str_action = "put"; break;
default: str_action = "combined action";
}

errmsg << "DispatchBot::invoke " << str_action << " \"" << narrow(fnames[0])
<< "\" arg #" << err_arg << "\n"
<< narrow(exceptn.bstrSource) << ": "
<< narrow(exceptn.bstrDescription);

throw std::runtime_error(errmsg.str());
}
}

DispatchBot& DispatchBot::member(Variant& obj, const std::wstring& w)
{
fargs.clear();
fnames.clear();
fdispids.clear();

IDispatch* disp = obj.asDispatch();
if (!disp) throw std::invalid_argument("DispatchBot::member not an object");

disp->AddRef();
if (fdisp) fdisp->Release();
fdisp = disp;

fnames.push_back(w);
return *this;
}

DispatchBot& DispatchBot::member(const std::wstring& w)
{
if (!fnames.empty())
{
get();
}

return member(fresult, w);
}

Variant& DispatchBot::get()
{
compile();
invoke(DISPATCH_PROPERTYGET);
return fresult;
}

void DispatchBot::put(const Variant& v)
{
struct restore_t
{
std::vector<Variant>& v1;
std::vector<DISPID>& v2;

restore_t(std::vector<Variant>& a1, std::vector<DISPID>& a2) : v1(a1), v2(a2) {}

~restore_t()
{
v1.pop_back();
v2.pop_back();
}
};

compile();
// add named "put" argument
fdispids.push_back(DISPID_PROPERTYPUT);
addArg(v);

restore_t restore(fargs, fdispids);
invoke(DISPATCH_PROPERTYPUT);
}

void DispatchBot::execute()
{
compile();
invoke(DISPATCH_METHOD);
}




© OSzone.net 2001-2012