Re: WinWORD отсоединяет мои приемники событий
От: Lamer-Programmer  
Дата: 01.11.06 15:49
Оценка: 3 (1)
Здравствуйте, yurafitt!

Я сталкивался с подобной проблемой: евент привязывается только к первому открытому документу. К сожалению, статьи Микрософта не искал, могу предложить мой солюшен:
Во-первых, привязываешься к событию, которое определяет активный документ Ворда. В его обработчике, имея указатель на свою, грубо говоря, кнопку, освобождаешь её евент, лезешь через активный документ к меню, дальше к интересующей кнопке, привязываешь к ней новый евент. Примерно так:

_ATL_FUNC_INFO ActiveFileEventsInfo ={CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH}};
_ATL_FUNC_INFO OnClickMyButtonInfo ={CC_STDCALL,VT_EMPTY,1,{VT_DISPATCH}};

void __stdcall CWord::ActiveFileEvents(IDispatch * Ctrl)
{
try
{
USES_CONVERSION;
MyButtonEvents::DispEventUnadvise((IDispatch*)MyButton); //отвязываешь ивент, он и так не работает

CComPtr <Office::CommandBar> CmdBar;
CComPtr <Office::_CommandBars> CmdBars;
CComPtr <Office::CommandBarControl> NewBar1;
CComPtr <Office::CommandBarControls> BarControls;

CComQIPtr<MSWord::_Document> Doc(Ctrl);
ATLASSERT(Doc);
Doc->get_CommandBars(&CmdBars);
ATLASSERT(CmdBars);
CmdBars->get_Item(_variant_t("My Button"),&CmdBar);
ATLASSERT(CmdBar);
CmdBar->PutVisible(VARIANT_TRUE);

BarControls = CmdBar->GetControls();
ATLASSERT(BarControls);

CComVariant vPos1(1);// тут позиция кнопки, но можешь как-нибудь по-другому

NewBar1 = BarControls->GetItem(vPos1);
ATLASSERT(NewBar1);
MyButton = NewBar1;

MyButtonEvents::DispEventAdvise((IDispatch*)MyButton); //привязываешь заново
}
catch(...) { }
}

Не забудь привязать это события, как и евент кнопки — структуры у них одинаковые( в OnConnection, например )

а в хедере обьявляешь так
#import "C:\Program Files\Common Files\DESIGNER\MSADDNDR.DLL" raw_interfaces_only, raw_native_types, no_namespace, named_guids
#import "C:\Program Files\Microsoft Office\OFFICE11\MSWORD.OLB" rename("ExitWindows","MyExitWindows"),named_guids,rename_namespace("MSWord")
using namespace MSWord;
extern _ATL_FUNC_INFO OnClickMyButtonInfo;
extern _ATL_FUNC_INFO ActiveFileEventsInfo;

typedef IDispEventSimpleImpl</*nID =*/ 2,CWord, &__uuidof(Office::_CommandBarButtonEvents)> MyButtonEvents;
typedef IDispEventSimpleImpl</*nID =*/ 3,CWord, &__uuidof(MSWord::ApplicationEvents2)> FileEventsActive;

class ATL_NO_VTABLE CWord :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CWord, &CLSID_Word>,
public IDispatchImpl<IWord, &IID_IWord, &LIBID_WORDADDINLib>,
public IDispatchImpl<_IDTExtensibility2, &IID__IDTExtensibility2, &LIBID_AddInDesignerObjects>,
public MyButtonEvents,
public FileEventsActive,
.....
{
BEGIN_SINK_MAP(CWord)
SINK_ENTRY_INFO(2,__uuidof(Office::_CommandBarButtonEvents),0x01,OnClickMyButton,&OnClickMyButtonInfo)
SINK_ENTRY_INFO(3,__uuidof(MSWord::ApplicationEvents2),0x0a,ActiveFileEvents,&ActiveFileEventsInfo)
END_SINK_MAP()

void __stdcall OnClickMyButton(IDispatch* Ctrl);
void __stdcall ActiveFileEvents(IDispatch* Ctrl);

};

ну вобщем и всё... в активном документе создаётся новый екземплер твоего тулбара, к которому привязывается новый обработчик событий.
В схватке "человек против компьютера" всегда побеждает логика!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.