Excel через excel.olb
От: potap  
Дата: 22.05.03 10:30
Оценка:
Люди,

как из проги на VC отследить ввод пользователя в некоторые листы.

В excel-евской книге (VBA — модуле) разрешается продекларировать несколько функции из моей dll, написанной опять же на VC.

VC 6, Excel 2000,
прога и dll используют классы, сгенерённые на основе excel.olb.

Заранее благодарен.
Re: Excel через excel.olb
От: potap  
Дата: 22.05.03 11:08
Оценка:
А как ваще прицепится в VC-программе к event-ам, загорающимся в Excel-евских VBA-объектах.
Нельзя небозь?
Re[2]: Excel через excel.olb
От: KGP http://kornilow.newmail.ru
Дата: 22.05.03 11:36
Оценка: 3 (1)
Здравствуйте, potap, Вы писали:

P>А как ваще прицепится в VC-программе к event-ам, загорающимся в Excel-евских VBA-объектах.

P>Нельзя небозь?


В наличии событийные интерфейсы :
IDocEvents
IWorkbookEvents — событие SheetChange попробуй
...
IAppEvents
IOLEObjectEvents
IRefreshEvents
Re[3]: Excel через excel.olb
От: potap  
Дата: 22.05.03 11:51
Оценка:
Я в COM-е, к сожалению, чайник . Как это сделать с позиции сгенерённых классов на основе excel.olb: _Application, _Workbook, _Worksheet и пр.

KGP>В наличии событийные интерфейсы :

KGP>IDocEvents
KGP>IWorkbookEvents — событие SheetChange попробуй
KGP>...
KGP>IAppEvents
KGP>IOLEObjectEvents
KGP>IRefreshEvents
Re[4]: Excel через excel.olb
От: potap  
Дата: 22.05.03 12:24
Оценка:
Ну хорошо, сгенерил я класс AppEvents.
У него есть метод
void SheetChange(LPDISPATCH Sh, LPDISPATCH Target);
А где, собственно, реакцию-то писать? Не внутри же этой ф-ции. Там InvokeHelper стоит. Наверняка очевидность спрашиваю — не бейте ногами .

Здравствуйте, potap, Вы писали:

P>Я в COM-е, к сожалению, чайник . Как это сделать с позиции сгенерённых классов на основе excel.olb: _Application, _Workbook, _Worksheet и пр.


KGP>>В наличии событийные интерфейсы :

KGP>>IDocEvents
KGP>>IWorkbookEvents — событие SheetChange попробуй
KGP>>...
KGP>>IAppEvents
KGP>>IOLEObjectEvents
KGP>>IRefreshEvents
Re[5]: Excel через excel.olb
От: Dym On Россия  
Дата: 22.05.03 13:08
Оценка: 3 (1)
Здравствуйте, potap, Вы писали:

P>Ну хорошо, сгенерил я класс AppEvents.

P>У него есть метод
P>void SheetChange(LPDISPATCH Sh, LPDISPATCH Target);
P>А где, собственно, реакцию-то писать? Не внутри же этой ф-ции. Там InvokeHelper стоит. Наверняка очевидность спрашиваю — не бейте ногами .

Надо написать реализацию интерфеса IDocEvents, а потом с помощью интерфейса IConnectionPoint связать его с Sheet'ом.
Вроде так... в теории...
Счастье — это Glück!
Re[6]: Excel через excel.olb
От: potap  
Дата: 22.05.03 14:02
Оценка:
Здравствуйте, Dym On, Вы писали:

Теория это, конечно, хорошо... Примерчик бы...

DO>Надо написать реализацию интерфеса IDocEvents, а потом с помощью интерфейса IConnectionPoint связать его с Sheet'ом.

DO>Вроде так... в теории...
Re[7]: Excel через excel.olb
От: potap  
Дата: 22.05.03 14:50
Оценка:
Хорошо,
а как мне создать WorkbookEvents ?
Re[8]: Excel через excel.olb
От: Dym On Россия  
Дата: 22.05.03 14:59
Оценка:
Здравствуйте, potap, Вы писали:

P>Хорошо,

P>а как мне создать WorkbookEvents ?
Ты имееш в виду реализацию IDocEvents...

Как-то так, только на примере SheetEvents (не охота переписывать):
class CSheetEvents : public IDocEvents
{
public:
        // будем реализовывать
        CSheetEvents(void);
        ULONG STDMETHODCALLTYPE AddRef();
        ULONG STDMETHODCALLTYPE Release();
        HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppv);
        HRESULT STDMETHODCALLTYPE Change(RangePtr Target) ;                     

        // все остальное заглушки  
        HRESULT STDMETHODCALLTYPE SelectionChange(RangePtr Target) { return S_OK;  };
        HRESULT STDMETHODCALLTYPE BeforeDoubleClick(RangePtr Target, TOLEBOOL* Cancel) { return S_OK;  };
        HRESULT STDMETHODCALLTYPE BeforeRightClick(RangePtr Target, TOLEBOOL* Cancel) { return S_OK;  };
        HRESULT STDMETHODCALLTYPE Activate(void) { return S_OK;  };
        HRESULT STDMETHODCALLTYPE Deactivate(void) { return S_OK;  };
        HRESULT STDMETHODCALLTYPE Calculate(void) { return S_OK;  }; 
        HRESULT STDMETHODCALLTYPE FollowHyperlink(RangePtr Target) { return S_OK;  };

private:
        long m_Ref;
};

//----------------------------------------------------------------------------
CSheetEvents::CSheetEvents(void)
{
  m_Ref = 0;
}

//----------------------------------------------------------------------------
ULONG STDMETHODCALLTYPE CSheetEvents::AddRef(void)
{
  InterlockedIncrement(&m_Ref);
  return m_Ref;
}

//----------------------------------------------------------------------------
ULONG STDMETHODCALLTYPE CSheetEvents::Release(void)
{
  InterlockedDecrement(&m_Ref);
  if(m_Ref == 0){
    delete this;
    return 0;
  }else
    return m_Ref;
}
//----------------------------------------------------------------------------

HRESULT STDMETHODCALLTYPE CSheetEvents::QueryInterface(REFIID riid, void ** ppv)
{
  if(riid == IID_IUnknown || riid == IID_SheetEvents){
    *ppv = this;
    AddRef();
    return S_OK;
  }else
    return E_NOINTERFACE;
}
//----------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CSheetEvents::Change(RangePtr Target)
{
  // делаем что хотим с Target
  return S_OK;
}
//----------------------------------------------------------------------------
Счастье — это Glück!
Re[7]: Excel через excel.olb
От: Vi2 Удмуртия http://www.adem.ru
Дата: 23.05.03 06:49
Оценка:
Здравствуйте, potap, Вы писали:

P>Теория это, конечно, хорошо... Примерчик бы...

Есть статьи на форуме, например, Как подключиться к событиям СOM-объекта на С++ и поиск по ключевым словам.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[9]: Excel через excel.olb
От: potap  
Дата: 23.05.03 07:49
Оценка:
Здравствуйте, Dym On, Вы писали:

DO>Здравствуйте, potap, Вы писали:


P>>Хорошо,

P>>а как мне создать WorkbookEvents ?
DO>Ты имееш в виду реализацию IDocEvents...

.... Не совсем. Я уже сгенерил "From A TypeLib" excel9.olb при помощи ClassWizard-а класс WorkbookEvents. Но как мне создать экземпляр этого класса? До этого я создавал классы последовательно.

Сначала класс _Application. Вот так:
LPDISPATCH pDisp;
LPUNKNOWN pUnk;
CLSID clsid;
_Application app;
::CLSIDFromProgID(L"Excel.Application", &clsid);//Даже для 7-го // from registry
::GetActiveObject(clsid, NULL, &pUnk);
VERIFY(pUnk->QueryInterface(IID_IDispatch,(void**) &pDisp)==S_OK);
m_ExcelApp.AttachDispatch(pDisp);
pUnk->Release();


Потом класс _Workbook:
_Workbook book(app.GetActiveWorkbook());


Потом класс _Worksheet
_Worksheet sheet(book.GetActiveSheet());


Совершенно аналогично создаю объект класса Range. Т.е. я создаю объекты по цепочке — сначала _Application, потом _Workbook и т.д. У каждого предыдущего объекта есть метод, возвращающий LPDISPATCH объекта, который я хочу создать.
В excel9.tlb описан класс WorkbookEvents. Но объекта, у которого бы был метод что-то типа GetEvents() я не нашёл .

Вы описываете достаточно сложный путь как подключиться к событиям. Но зачем же Microsoft сбацала в Excel9.olb классы <some_object>Events? Хотя я заподозревал, что не для того, чтобы дать возможность реагировать на события, а чтобы дать возможность генерить события. Или нет?

Спасибо.


DO>Как-то так, только на примере SheetEvents (не охота переписывать):

DO>
DO>class CSheetEvents : public IDocEvents
DO>{
DO>public:
DO>        // будем реализовывать
DO>        CSheetEvents(void);
DO>        ULONG STDMETHODCALLTYPE AddRef();
DO>        ULONG STDMETHODCALLTYPE Release();
DO>        HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppv);
DO>        HRESULT STDMETHODCALLTYPE Change(RangePtr Target) ;                     

DO>        // все остальное заглушки  
DO>        HRESULT STDMETHODCALLTYPE SelectionChange(RangePtr Target) { return S_OK;  };
DO>        HRESULT STDMETHODCALLTYPE BeforeDoubleClick(RangePtr Target, TOLEBOOL* Cancel) { return S_OK;  };
DO>        HRESULT STDMETHODCALLTYPE BeforeRightClick(RangePtr Target, TOLEBOOL* Cancel) { return S_OK;  };
DO>        HRESULT STDMETHODCALLTYPE Activate(void) { return S_OK;  };
DO>        HRESULT STDMETHODCALLTYPE Deactivate(void) { return S_OK;  };
DO>        HRESULT STDMETHODCALLTYPE Calculate(void) { return S_OK;  }; 
DO>        HRESULT STDMETHODCALLTYPE FollowHyperlink(RangePtr Target) { return S_OK;  };

DO>private:
DO>        long m_Ref;
DO>};

DO>//----------------------------------------------------------------------------
DO>CSheetEvents::CSheetEvents(void)
DO>{
DO>  m_Ref = 0;
DO>}

DO>//----------------------------------------------------------------------------
DO>ULONG STDMETHODCALLTYPE CSheetEvents::AddRef(void)
DO>{
DO>  InterlockedIncrement(&m_Ref);
DO>  return m_Ref;
DO>}

DO>//----------------------------------------------------------------------------
DO>ULONG STDMETHODCALLTYPE CSheetEvents::Release(void)
DO>{
DO>  InterlockedDecrement(&m_Ref);
DO>  if(m_Ref == 0){
DO>    delete this;
DO>    return 0;
DO>  }else
DO>    return m_Ref;
DO>}
DO>//----------------------------------------------------------------------------

DO>HRESULT STDMETHODCALLTYPE CSheetEvents::QueryInterface(REFIID riid, void ** ppv)
DO>{
DO>  if(riid == IID_IUnknown || riid == IID_SheetEvents){
DO>    *ppv = this;
DO>    AddRef();
DO>    return S_OK;
DO>  }else
DO>    return E_NOINTERFACE;
DO>}
DO>//----------------------------------------------------------------------------
DO>HRESULT STDMETHODCALLTYPE CSheetEvents::Change(RangePtr Target)
DO>{
DO>  // делаем что хотим с Target
DO>  return S_OK;
DO>}
DO>//----------------------------------------------------------------------------
DO>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.