Поиск:

Ответ в темуСоздание новой темы Создание опроса
> получение ссылки на интерфейс обьекта 
V
    Опции темы
RastaDja
Дата 3.11.2010, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 1.11.2010

Репутация: 1
Всего: 5



Здраствуйте.
есть такая задача:

у нас есть COM интерфейс TreeLib.TreeMap, который реализует сохранение данных в карте
map<CComBSTR, CComVariant> m_varMap;

в качестве данных можэт быть любая Варыант переменная. предполагается, что в данные можно добавить и другой TreeLib.TreeMap обьект. Таким образом будет строится дерево.

Вопрос: Как получить ссылку на Парент обект, и как эту ссылку хранить. Спасибо


--------------------
The more closely you look at one thing, the less closely can you see something else.
PM MAIL   Вверх
xvr
Дата 3.11.2010, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



В COM'е нет встроенного понятия parent'а (есть агрегация, но это не то). Так что parent'а придется приделывать руками (как и любую другую проперть в AcitveX или метод в голом COM'е), и устанавливать так же вручную.
В принципе, если объект именно ActiveX (т.е. унаследован от IDispatch), ему можно принудительно прописать проперть Parent (если таковая у него найдется). Делать это при вставке объекта в m_varMap

PM MAIL   Вверх
RastaDja
Дата 3.11.2010, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 1.11.2010

Репутация: 1
Всего: 5



Код

class ATL_NO_VTABLE CTreeClassMap : 
    ...
{
public:
...

    IDispatch* _parent;
    map<CComBSTR, CComVariant> m_varMap;

    CTreeClassMap()
    {
    }

в качестве _parent использую IDispatch* но ничего не получается.
как вытенуть ссылку на и IDispatch* из map<CComBSTR, CComVariant> m_varMaр

или правельнее CTreeClassMap* _parent; но тогда как получить CTreeClassMap?

Добавлено через 2 минуты и 21 секунду
Код

IDispatch* pDisp = pVal.pdispVal;
        ITreeClassMap* pTree;
        
        if(SUCCEEDED(pDisp->QueryInterface(IID_ITreeClassMap,(void**)&pTree))){
            MessageBox(NULL,"NODE","DIS",MB_OK);
            IDispatch* pDis;
            if(SUCCEEDED(this->OuterQueryInterface(IID_IDispatch, (void**)&pDis))){
                MessageBox(NULL,"erQuer","DIS",MB_OK);
                pTree->put_Paren(pDis);
            
                m_varMap[key] = pTree;


такой код не работает smile 


--------------------
The more closely you look at one thing, the less closely can you see something else.
PM MAIL   Вверх
xvr
Дата 3.11.2010, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(RastaDja @  3.11.2010,  12:14 Найти цитируемый пост)
как вытенуть ссылку на и IDispatch* из map<CComBSTR, CComVariant> m_varMaр
Никак. Ее надо вытягивать из CTreeClassMap 

И вообще подход неверный - надо не вытягивать ссылку на родителя из уже вставленного в m_varMaр Варианта, а устанавливать ему (Варианту) ссылку на себя при вставке его в m_varMaр

Т.е. как то так (псевдокод):
Код

method CTreeClassMap::Add(CComBSTR key, CComVariant data)
{
 if (data.vt == VT_DISPATCH)
  {
    DISPID id=data.v_dispatch->GetDispID("Parent");
    if (id!=-1)
     {
       CComVariant p;
       p=(IDispatch*)this;
       data.v_dispatch->Invoke(id,PROP_PUT,p);
     }
  }
 m_varMaр[key]=data;
}

property CTreeClassMap::Parent(CComVariant p)
{
 p.v_dispatch->QueryInterface(IID_TreeClassMap, &_property);
}



Это сообщение отредактировал(а) xvr - 3.11.2010, 12:26
PM MAIL   Вверх
RastaDja
Дата 3.11.2010, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 1.11.2010

Репутация: 1
Всего: 5



Цитата

DISPID id=data.v_dispatch->GetDispID("Parent");

GetDispID("Paren"); у меня нет такой ф-ии
user posted imaget

Добавлено через 1 минуту и 42 секунды
извеняюс GetIDsOfMames


--------------------
The more closely you look at one thing, the less closely can you see something else.
PM MAIL   Вверх
RastaDja
Дата 3.11.2010, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 1.11.2010

Репутация: 1
Всего: 5



Код

STDMETHODIMP CTreeClassMap::Add(BSTR key, VARIANT pVal)
{
    // TODO: Add your implementation code here
    if (m_varMap.find(key) != m_varMap.end())
        return E_FAIL;
    
 if (pVal.vt == VT_DISPATCH)
  {
    OLECHAR FAR* szMember = (USHORT*)"Parent";
    DISPID id;
     pVal.pdispVal->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_SYSTEM_DEFAULT, &id); //.v_dispatch->GetDispID("Parent");
    if (id!=-1)
     {
       CComVariant p;
       IDispatch* pDisp;
       p.vt = VT_DISPATCH;
       p.pdispVal = (IDispatch*)this; //ошибка
      // pVal.pdispVal->Invoke(id,PROP_PUT,p);
    }
  }
 m_varMap[key]=pVal;


получаю ошибку
error C2594: 'type cast' : ambiguous conversions from 'class CTreeClassMap *const ' to 'struct IDispatch *'

у меня VS6

Добавлено через 12 минут и 11 секунд
Код

STDMETHODIMP CTreeClassMap::Add(BSTR key, VARIANT pVal)
{
    // TODO: Add your implementation code here
    if (m_varMap.find(key) != m_varMap.end())
        return E_FAIL;
    
 if (pVal.vt == VT_DISPATCH)
  {
    OLECHAR FAR* szMember = (USHORT*)"ParentFF";
    DISPID id;
     pVal.pdispVal->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_SYSTEM_DEFAULT, &id); //.v_dispatch->GetDispID("Parent");
    if (id!=-1)
     {
       CComVariant p;
       IDispatch* pDisp;
       p.vt = VT_DISPATCH;
       //p.pdispVal = (IDispatch*)this->OuterQueryInterface(IID_IDispatch, (void**)&(p.pdispVal));
       this->OuterQueryInterface(IID_IDispatch, (void**)&(p.pdispVal));
        DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};

       p.pdispVal->Invoke(
        id,
        IID_NULL,
        LOCALE_USER_DEFAULT,
        DISPATCH_METHOD,
        &dispparamsNoArgs, NULL, NULL, NULL);
      // pVal.pdispVal->Invoke(id,PROP_PUT,p);
    }
  }
 m_varMap[key]=pVal;


//    m_varMap[key] = pVal;
    return S_OK;
}


так ошибок не выдаёт  smile 
ща буду пробовать как работает


--------------------
The more closely you look at one thing, the less closely can you see something else.
PM MAIL   Вверх
xvr
Дата 3.11.2010, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



2й вариант немного перебор, достаточно сделать
Код

p.pdispVal = (IDispatch*)(ITreeClassMap*)this;


PS. Не забудьте добавить в свой класс реализацию проперти 'ParentFF'

PPS. Тут тоже ошибка:
Код

OLECHAR FAR* szMember = (USHORT*)"ParentFF";
должно быть
Код

OLECHAR FAR* szMember = L"ParentFF";


PM MAIL   Вверх
RastaDja
Дата 3.11.2010, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 1.11.2010

Репутация: 1
Всего: 5



Цитата

OLECHAR FAR* szMember = L"ParentFF";

я так делал, но тут ошибка преобразования

Добавлено через 4 минуты и 53 секунды
Код

STDMETHODIMP CTreeClassMap::get_ParentRR(VARIANT *pVal)
{
    // TODO: Add your implementation code here
    pVal->vt = VT_DISPATCH;
    pVal->pdispVal = _parent;
    return S_OK;
}

STDMETHODIMP CTreeClassMap::put_ParentRR(VARIANT newVal)
{
    // TODO: Add your implementation code here
    newVal.pdispVal->QueryInterface(IID_ITreeClassMap, (void**)&_parent);
    
    return S_OK;
}


делаю так, но программа вылетает


--------------------
The more closely you look at one thing, the less closely can you see something else.
PM MAIL   Вверх
xvr
Дата 3.11.2010, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Цитата(RastaDja @ 3.11.2010,  14:00)
Цитата

OLECHAR FAR* szMember = L"ParentFF";

я так делал, но тут ошибка преобразования

Не должно. Букву 'L' перед строкой не забыли?

Цитата

делаю так, но программа вылетает
В каком месте вылетает?

Кроме того, пригляделся к коду, там еще ошибка:
Цитата

Код

 p.pdispVal->Invoke(
        id,
        IID_NULL,
        LOCALE_USER_DEFAULT,
        DISPATCH_METHOD,
        &dispparamsNoArgs, NULL, NULL, NULL);
      // pVal.pdispVal->Invoke(id,PROP_PUT,p);

Не от того объекта зовете, должно быть
Код

 DISPPARAMS dispparams = {&p, NULL, 1, 0};
 pVal.pdispVal->Invoke(
        id,
        IID_NULL,
        LOCALE_USER_DEFAULT,
        DISPATCH_PROPERTYPUT,
        &dispparam, NULL, NULL, NULL);



Это сообщение отредактировал(а) xvr - 3.11.2010, 16:18
PM MAIL   Вверх
RastaDja
Дата 3.11.2010, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 337
Регистрация: 1.11.2010

Репутация: 1
Всего: 5



спасибо за помощь, я нашол решение.
Клас
Код

class ATL_NO_VTABLE CNodeMy23 : public ISaveMy23,
    ...
{
public:
    ...
    INodeMy23* _parent;
    map<CComBSTR, CComVariant> m_varMap;
    CNodeMy23()
    {
        _parent = NULL; //обезательно
    }
..
}

Add функция
Код

STDMETHODIMP CNodeMy23::add(BSTR key, VARIANT pVal)
{
    // TODO: Add your implementation code here
    
    if(pVal.vt == VT_DISPATCH){
        INodeMy23* pNode;
        if(SUCCEEDED(pVal.pdispVal->QueryInterface(IID_INodeMy23, (void**)&pNode))){
        //    MessageBox(NULL, L"this is INodeMy23", L"message", 1);
            pNode->put_Par((INodeMy23*)this);
        }
        else{
        //    MessageBox(NULL, L"this is Any Object", L"message", 1);
        }
    }
    m_varMap[key] = pVal;
    return S_OK;
}

Property
Код

STDMETHODIMP CNodeMy23::get_Par(INodeMy23** pVal)
{
    // TODO: Add your implementation code here
    *pVal = (INodeMy23*)_parent;
    (*pVal)->AddRef();
    return S_OK;
}

STDMETHODIMP CNodeMy23::put_Par(INodeMy23* newVal)
{
    // TODO: Add your implementation code here
    _parent = newVal;
    return S_OK;
}


ещё раз большое спасибо smile 

но я ещё на 100% не уверен в правельной работе кода

Добавлено через 1 минуту и 25 секунд
З.Ы
 поэтому тему не закрываю


--------------------
The more closely you look at one thing, the less closely can you see something else.
PM MAIL   Вверх
xvr
Дата 3.11.2010, 19:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 8
Всего: 223



Вроде все правильно

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: COM/DCOM/ActiveX/ATL/CORBA | Следующая тема »


 




[ Время генерации скрипта: 0.0940 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.