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

Ответить
Аватара пользователя
Sanchos

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

Сообщение Sanchos »

Нужно подключить 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 IVGApplicationPtr;
...
}

Есть у кого какие мысли по этому поводу?

Зарание благодарен.
Аватара пользователя
pva

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

Сообщение pva »

дальше создаёшь объект (не забудь 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 
#include 
#include 
#include 
#include 
//------------------------------------------
class DispatchBot
{
    IDispatch* fdisp;
    mutable Variant fresult;
    std::vector fargs;
    std::vector fnames;
    mutable std::vector 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 
#include 
/*-----------------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::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 wt;
        wt.reserve(fnames.size());
        for (unsigned i=0; iGetIDsOfNames(IID_NULL, const_cast(&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 
Ответить

Вернуться в «Программирование и базы данных»