Здравствуйте, 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);
};
ну вобщем и всё... в активном документе создаётся новый екземплер твоего тулбара, к которому привязывается новый обработчик событий.