小弟开发了一个ATL组件,我现在想在Word打开的时候自动调用我的程序,请赐教!!

解决方案 »

  1.   

    Word 有 事件接口吗? 如果有的话. 可以通过连接点调用连接到它的事件源. 打开会不会通知你我就不清楚了
      

  2.   

    http://support.microsoft.com/kb/183599
      

  3.   

    使用VC++获得Microsoft Word97应用事件
    概要 
    这文章证明怎样使用VC++.获得微软word97应用事件。但是,在这文章中观念和代码是并非对Microsoft Word特有。 他们是适用于整个套微软office应用, 以及任何其它类似的应用程序。 更多信息 
    下列的步给怎样建立MFC应用,它可以捕获Microsoft Word 97 Application事件Startup(), DocumentChange()和Quit(): 使用MFC AppWizard创造一个新对话框。给出项目的名字WordEvents, 接受缺省的设置.给你的对话框添加两按键,并分别命名为"Start and Setup"和"Quit and Clean Up"。添加下列的代码到 "Start and Setup"按键的句柄:// 检查看是否你已经启动服务器.
    if(m_app.m_lpDispatch != NULL) {AfxMessageBox("Server already started.");
    return;}char buf[256]; // General purpose buffer.// 打开自动化服务器.
    COleException e;if(!m_app.CreateDispatch("Word.Application.8", &e)) {sprintf(buf, "Error on CreateDispatch(): %ld (%08lx)",e.m_sc, e.m_sc);
    AfxMessageBox(buf, MB_SETFOREGROUND);
    return;}// 通过自动化使服务器变得可见.// I.e.: Application.Visible = TRUEDISPID dispID;
    unsigned short *ucPtr;
    BYTE *parmStr;
    ucPtr = L"visible";m_app.m_lpDispatch->GetIDsOfNames(IID_NULL, &ucPtr, 1, LOCALE_USER_DEFAULT, &dispID);
    parmStr = (BYTE *)( VTS_VARIANT );
    m_app.InvokeHelper(dispID, DISPATCH_METHOD | DISPATCH_PROPERTYPUT, VT_EMPTY,NULL, parmStr, &COleVariant((short)TRUE));// 事件获得.// {000209F7-0000-0000-C000-000000000046}static const GUID IID_IWord8AppEvents = {0x000209f7,0x000,0x0000,{0xc0,0x00,0x0,0x00,0x00,0x00,0x00,0x46 } };// 建立事件步骤// 1. 得到服务器的IConnectionPointContainer接口.
    // 2. 调用IConnectionPointContainerFindConnectionPoint()寻找到希望获得的接口
    // 3. 调用IConnectionPoint::Advise()HRESULT hr;// 得到服务器的IConnectionPointContainer接口.
    IConnectionPointContainer *pConnPtContainer;
    hr = m_app.m_lpDispatch->QueryInterface(IID_IConnectionPointContainer,(void **)&pConnPtContainer);
    ASSERT(!FAILED(hr));// 为使你感兴趣的事件找到联系点.
    hr = pConnPtContainer->FindConnectionPoint(IID_IWord8AppEvents,&m_pConnectionPoint);
    ASSERT(!FAILED(hr));// 得到你的事件实现的IUnknown界面.
    LPUNKNOWN pUnk = m_myEventSink.GetInterface(&IID_IUnknown);
    ASSERT(pUnk);// 建立advisory联系!
    hr = m_pConnectionPoint->Advise(pUnk, &m_adviseCookie);
    ASSERT(!FAILED(hr));// 释放IConnectionPointContainer
    pConnPtContainer->Release(); 下面是"Quit and Clean Up"按钮的处理句柄代码:// 如果你已启动服务器.if(m_app.m_lpDispatch == NULL) {AfxMessageBox("You haven't started the server yet.");return;}m_pConnectionPoint->Unadvise(m_adviseCookie);// 告诉服务器放弃.// Application.Quit()DISPID dispID; // Temporary DISPIDunsigned short *ucPtr; // Temporary name holderucPtr = L"quit";m_app.m_lpDispatch->GetIDsOfNames(IID_NULL, &ucPtr, 1, LOCALE_USER_DEFAULT, &dispID);m_app.InvokeHelper(dispID, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);// 释放应用对象.
    m_app.ReleaseDispatch(); 打开MFC ClassWizard (CTRL+W),加入一个源自CCmdTarget的新类MyEventSink。按下面的顺序加入新方法:void Startup()
    void Quit()
    void DocumentChange()在MyEventSink.cpp中,我们会看到下面的代码:void MyEventSink::Startup() { AfxMessageBox("MyEventSink::Startup() called."); }
    void MyEventSink::Quit() { AfxMessageBox("MyEventSink::Quit() called.");}
    void MyEventSink::DocumentChange(){ AfxMessageBox("MyEventSink::DocumentChange() called.");} 打开你的MyEventSink.cpp文找到IID_IMyEventSink声明. ClassWizard为你的界面产生一新的随机GUID, 但是因为你执行一已有GUID的特有接口,所以需要进行如下修改:static const GUID IID_IMyEventSink = {0x000209f7,0x000,0x0000,{0xc0,0x00,0x0,0x00,0x00,0x00,0x00,0x46}}; 给你的在WordEventsDlg.h中WordEventsDlg类添加下列的公共成员变量:COleDispatchDriver m_app;
    IConnectionPoint *m_pConnectionPoint;
    DWORD m_adviseCookie;
    MyEventSink m_myEventSink; WordEventsDlg.h中加入下面声明:#include "MyEventSink.h" 打开文件MyEventSink.h和找出声明的destructor;它将如下出现:// Implementation
    protected:
    virtual ~MyEventSink(); 在"Protected"之上写出声明:virtual ~MyEventSink();// Implementation
    protected:
    // virtual ~MyEventSink(); // 或者这行可以删除. 最后,确保OLE/COM库有机会预置.正好在你的"start and setup"按键的前面添加下列的代码.这个创造全局类。初始化函数会初始化OLE/COM库。// Ole初始化类
    class OleInitClass {public:OleInitClass() { OleInitialize(NULL);}
    ~OleInitClass() { OleUninitialize();}};OleInitClass g_OleInitClass; 运行下面的程序你会发现当你新建文档的时候会有一个菜单弹出。在创建事件获得函数时请按顺序进行,因为word中的这三个事件函数分别对应DISPIDs 1, 2和3,如果用户按顺序创建,则不需要修改。如果象excel中一样,事件不是按顺序的,则需要人工添加dispid号。
      

  4.   

    但是我现在想:当我打开Word的时候,Word自动运行我的程序
      

  5.   

    参考
    http://www.codeguru.com/Cpp/COM-Tech/atl/tutorials/article.php/c3591/
    http://support.microsoft.com/support/kb/articles/Q184/9/74.ASP
    http://support.microsoft.com/?kbid=230689
      

  6.   

    同一金刚兄的说法!
    你可以插件处理这个word打开事件,只要是这个事件你就ShellExecute打开你的exe也可以!
      

  7.   

    你机器上有没有装金山词霸啊?如果有的话,打开注册表,找到HKEY_CURRENT_USER->Software->Microsoft->Office->Word下面有一项Addins,这就是word的COM插件,在该项下面注册的所有项,在Word起动时都将被加载,再说说对Word文档打开事件的响应吧,Word支持连接点且应该支持通过IDispatch接口的Invoke()方法进行调用,所以只要你的插件控件支持IDispatch接口,且在Invoke()方法里对Word事件进行响应就行了,至于Word事件接口中的dispid你可以用OLE/COM Viewer工具打开msword.olb文件查看,在网上找些资料应该没问题的.
      

  8.   

    我现在已经写了个COM,可是我不知把打开Word的事件放在那里,因为我的插件是一个Button,不能按就得完成我的功能!!
      

  9.   

    处理Button的单击事件
    extern _ATL_FUNC_INFO OnClickButtonInfo;
    class ATL_NO_VTABLE CFolderToWordAddin : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CFolderToWordAddin, &CLSID_FolderToWordAddin>,
    public ISupportErrorInfo,
    public IDispatchImpl<IFolderToWordAddin, &IID_IFolderToWordAddin, &LIBID_FOLDERTOWORDLib>,
    public IDispatchImpl<_IDTExtensibility2, &IID__IDTExtensibility2, &LIBID_AddInDesignerObjects>,
    public IDispEventSimpleImpl<1,CFolderToWordAddin,&__uuidof(Office::_CommandBarButtonEvents)>{
    ....
    CComQIPtr < Office::_CommandBarButton> m_spCmdButton;
    void __stdcall OnClickButton(IDispatch * /*Office::_CommandBarButton**/ Ctrl,VARIANT_BOOL * CancelDefault);
    }BEGIN_SINK_MAP(CFolderToWordAddin)
    SINK_ENTRY_INFO(1, __uuidof(Office::_CommandBarButtonEvents),/*dispid*/
     0x01, OnClickButton, &OnClickButtonInfo)
    END_SINK_MAP()
    _ATL_FUNC_INFO OnClickButtonInfo ={CC_STDCALL,VT_EMPTY,2,
    {VT_DISPATCH,VT_BYREF | VT_BOOL}};
    _variant_t vtTrue(VARIANT_TRUE,VT_BOOL);DispEventAdvise((IDispatch*)m_spCmdButton,&__uuidof(Office::_CommandBarButtonEvents));void __stdcall CFolderToWordAddin::OnClickButton(IDispatch* /*Office::_CommandBarButton* 
    */ Ctrl,VARIANT_BOOL * CancelDefault)
    {
    USES_CONVERSION;
    TRACE(_T(" CFolderToWordAddin::OnClickButton\n"));
    CCFolderToWordDialog dlg;
    if(dlg.DoModal()!=IDOK) return;
    m_spApp->Options->ReplaceSelection = false; FolderToWord(dlg.m_fwo.m_strRootFolder, dlg.m_fwo);
    }
      

  10.   

    其实我的程序就是想在文档内加入一张浮动的图片,可我不知如何实现,关键不会用Shapes.AddPicture