Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Import *.tlb - как потом использовать полученный *.h ? (C++ Builder 2009) (http://forum.oszone.net/showthread.php?t=142612)

Sanchos 13-06-2009 21:36 1142563

Import *.tlb - как потом использовать полученный *.h ? (C++ Builder 2009)
 
Нужно подключить 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 1149632

дальше создаёшь объект (не забудь 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);
}



Время: 06:29.

Время: 06:29.
© OSzone.net 2001-