这个图表明的函数的调用顺序,主要代码如下:

 // MyAddin.cpp : Implementation of DLL Exports.

 // Note: Proxy/Stub Information
// To merge the proxy/stub code into the object DLL, add the file
// dlldatax.c to the project. Make sure precompiled headers
// are turned off for this file, and add _MERGE_PROXYSTUB to the
// defines for the project.
//
// If you are not running WinNT4.0 or Win95 with DCOM, then you
// need to remove the following define from dlldatax.c
// #define _WIN32_WINNT 0x0400
//
// Further, if you are running MIDL without /Oicf switch, you also
// need to remove the following define from dlldatax.c.
// #define USE_STUBLESS_PROXY
//
// Modify the custom build rule for MyAddin.idl by adding the following
// files to the Outputs.
// MyAddin_p.c
// dlldata.c
// To build a separate proxy/stub DLL,
// run nmake -f MyAddinps.mk in the project directory. #include "stdafx.h"
#include "resource.h"
#include <initguid.h>
#include "MyAddin.h"
#include "dlldatax.h" #include "MyAddin_i.c"
#include "WordAddin.h" #ifdef _MERGE_PROXYSTUB
extern "C" HINSTANCE hProxyDll;
#endif CComModule _Module; BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_WordAddin, CWordAddin)
END_OBJECT_MAP() /////////////////////////////////////////////////////////////////////////////
// DLL Entry Point extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
MessageBox(NULL,"DllMain",NULL,MB_OK);
lpReserved;
#ifdef _MERGE_PROXYSTUB
if (!PrxDllMain(hInstance, dwReason, lpReserved))
return FALSE;
#endif
if (dwReason == DLL_PROCESS_ATTACH)
{
_Module.Init(ObjectMap, hInstance, &LIBID_MYADDINLib);
DisableThreadLibraryCalls(hInstance);
}
else if (dwReason == DLL_PROCESS_DETACH)
_Module.Term();
return TRUE; // ok
} /////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE STDAPI DllCanUnloadNow(void)
{
MessageBox(NULL,"DllCanUnloadNow",NULL,MB_OK);
#ifdef _MERGE_PROXYSTUB
if (PrxDllCanUnloadNow() != S_OK)
return S_FALSE;
#endif
return (_Module.GetLockCount()==) ? S_OK : S_FALSE;
} /////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
MessageBox(NULL,"DllGetClassObject",NULL,MB_OK);
#ifdef _MERGE_PROXYSTUB
if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
return S_OK;
#endif return _Module.GetClassObject(rclsid, riid, ppv);
} /////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry STDAPI DllRegisterServer(void)
{
MessageBox(NULL,"DllRegisterServer",NULL,MB_OK);
#ifdef _MERGE_PROXYSTUB
HRESULT hRes = PrxDllRegisterServer();
if (FAILED(hRes))
return hRes;
#endif
// registers object, typelib and all interfaces in typelib return _Module.RegisterServer(TRUE);
} /////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry STDAPI DllUnregisterServer(void)
{
MessageBox(NULL,"DllUnregisterServer",NULL,MB_OK);
#ifdef _MERGE_PROXYSTUB
PrxDllUnregisterServer();
#endif return _Module.UnregisterServer(TRUE);
}

还有一份代码如下:

 // WordAddin.h : Declaration of the CWordAddin

 #ifndef __WORDADDIN_H_
#define __WORDADDIN_H_ #include "resource.h" // main symbols
#include "stdafx.h"
#include "StdAfx.h"
#import "C:\Program Files\Common Files\designer\MSADDNDR.dll" raw_interfaces_only, raw_native_types, no_namespace, named_guids extern _ATL_FUNC_INFO OnClickButtonInfo; /////////////////////////////////////////////////////////////////////////////
// CWordAddin
class ATL_NO_VTABLE CWordAddin :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CWordAddin, &CLSID_WordAddin>,
public IDispatchImpl<IWordAddin, &IID_IWordAddin, &LIBID_MYADDINLib>,
public IDispatchImpl<_IDTExtensibility2, &IID__IDTExtensibility2, &LIBID_AddInDesignerObjects>,
public IDispEventSimpleImpl<,CWordAddin,&__uuidof(Office::_CommandBarButtonEvents)>,
public IDispatchImpl<IRibbonExtensibility, &IID_IRibbonExtensibility, &LIBID_Office>
{
public:
CWordAddin()
{
int i = ;
} DECLARE_REGISTRY_RESOURCEID(IDR_WORDADDIN) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CWordAddin)
COM_INTERFACE_ENTRY(IWordAddin)
//DEL COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY2(IDispatch, IWordAddin)
COM_INTERFACE_ENTRY(_IDTExtensibility2)
COM_INTERFACE_ENTRY(IRibbonExtensibility)
END_COM_MAP() BEGIN_SINK_MAP(CWordAddin)
SINK_ENTRY_INFO(, __uuidof(Office::_CommandBarButtonEvents),/*dispid*/ 0x01, OnClickButton1, &OnClickButtonInfo)
END_SINK_MAP() // IWordAddin
public:
STDMETHOD(OnMyButton)(/*[in]*/IDispatch* pIDispControl);
CComQIPtr <Word::_Application> m_spApp;
CComPtr < Office::_CommandBarButton> m_spCmdButton;
typedef IDispEventSimpleImpl</*nID =*/ ,CWordAddin, &__uuidof(Office::_CommandBarButtonEvents)> CommandButton1Events;
// _IDTExtensibility2
STDMETHOD(OnConnection)(IDispatch * Application, ext_ConnectMode ConnectMode, IDispatch * AddInInst, SAFEARRAY * * custom)
{
::MessageBox(NULL,"OnConnection","",MB_OK);
OutputDebugString("OnConnection");
//Delete it for the Office 2007 CComPtr < Office::_CommandBars> spCmdBars;
CComQIPtr <Word::_Application> spApp(Application);
m_spApp = spApp;
ATLASSERT(spApp); HRESULT hr = spApp->get_CommandBars(&spCmdBars);
if(FAILED(hr))
return hr; ATLASSERT(spCmdBars); CComVariant vName("MyAddin");
CComPtr <Office::CommandBar> spNewCmdBar;
CComVariant vPos();
CComVariant vTemp(VARIANT_TRUE);
CComVariant vEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR);
spNewCmdBar = spCmdBars->Add(vName, vPos, vEmpty, vTemp); CComPtr < Office::CommandBarControls> spBarControls;
spBarControls = spNewCmdBar->GetControls();
ATLASSERT(spBarControls); CComVariant vToolBarType();
CComVariant vShow(VARIANT_TRUE);
CComPtr < Office::CommandBarControl> spNewBar;
spNewBar = spBarControls->Add(vToolBarType, vEmpty, vEmpty, vEmpty, vShow);
ATLASSERT(spNewBar); CComQIPtr < Office::_CommandBarButton> spCmdButton(spNewBar);
ATLASSERT(spCmdButton); HBITMAP hBmp =(HBITMAP)::LoadImage(_Module.GetResourceInstance(),
MAKEINTRESOURCE(IDB_BITMAP),IMAGE_BITMAP,,,LR_LOADMAP3DCOLORS); ::OpenClipboard(NULL);
::EmptyClipboard();
::SetClipboardData(CF_BITMAP, (HANDLE)hBmp);
::CloseClipboard();
::DeleteObject(hBmp); spCmdButton->PutStyle(Office::msoButtonIconAndCaption);
hr = spCmdButton->PasteFace();
if (FAILED(hr))
return hr; spCmdButton->PutVisible(VARIANT_TRUE);
spCmdButton->PutCaption(OLESTR("myAddin"));
spCmdButton->PutEnabled(VARIANT_TRUE);
spCmdButton->PutTooltipText(OLESTR("test1"));
spCmdButton->PutTag(OLESTR("test1")); spNewCmdBar->PutVisible(VARIANT_TRUE); m_spCmdButton = spCmdButton; CommandButton1Events::DispEventAdvise((IDispatch*)m_spCmdButton);
return S_OK;
}
STDMETHOD(OnDisconnection)(ext_DisconnectMode RemoveMode, SAFEARRAY * * custom)
{
MessageBox(NULL,"OnDisconnection",NULL,MB_OK);
if(m_spCmdButton != NULL)
CommandButton1Events::DispEventUnadvise((IDispatch*)m_spCmdButton);
return S_OK;
}
STDMETHOD(OnAddInsUpdate)(SAFEARRAY * * custom)
{
MessageBox(NULL,"OnAddInsUpdate",NULL,MB_OK);
return S_OK;
}
STDMETHOD(OnStartupComplete)(SAFEARRAY * * custom)
{
MessageBox(NULL,"OnStartupComplete",NULL,MB_OK);
return S_OK;
}
STDMETHOD(OnBeginShutdown)(SAFEARRAY * * custom)
{
MessageBox(NULL,"OnBeginShutdown",NULL,MB_OK);
return S_OK;
} void __stdcall OnClickButton1(IDispatch * /*Office::_CommandBarButton**/ Ctrl,VARIANT_BOOL * CancelDefault); // IRibbonExtensibility
STDMETHOD(raw_GetCustomUI)(BSTR RibbonID, BSTR * RibbonXml)
{
MessageBox(NULL,"raw_GetCustomUI",NULL,MB_OK);
OutputDebugString("raw_GetCustomUI");
char szRibbon[MAX_PATH*] = {0x00};
LoadString(_Module.GetModuleInstance(),IDS_RIBBON_XML, \
szRibbon, MAX_PATH*);
if (RibbonXml == NULL)
return E_POINTER; OutputDebugString(szRibbon); CComBSTR bstr(szRibbon);
bstr.CopyTo(RibbonXml);//use this to avoid heap destroy
bstr.Empty();
return S_OK;
}
}; #endif //__WORDADDIN_H_

这是两个主要的文件。

注意两个问题:

160         CComBSTR bstr(szRibbon);
161 bstr.CopyTo(RibbonXml);//use this to avoid heap destroy
162 bstr.Empty();
这三行代码是为了防止程序退出时,插件对word的内存进行修改,导致堆错误,Word会Crash。函数的含义请参考MSDN。

Word Add-in 函数调用顺序的更多相关文章

  1. java初始化构造函数调用顺序

    类初始化时构造函数调用顺序: (1)初始化对象的存储空间为零或null值:  (2)调用父类构造函数:  (3)按顺序分别调用类成员变量和实例成员变量的初始化表达式:  (4)调用本身构造函数. 例子 ...

  2. c++深/浅拷贝 && 构造函数析构函数调用顺序练习题

    1.深/浅拷贝 编译器为我们提供的合成拷贝构造函数以及合成的拷贝赋值运算符都是浅拷贝.浅拷贝只是做简单的复制,如果在类的构造函数中new出了内存,浅拷贝只会简单的复制一份指向该内存的指针,而不会再开辟 ...

  3. python函数调用顺序、高阶函数、嵌套函数、闭包详解

    一:函数调用顺序:其他高级语言类似,Python 不允许在函数未声明之前,对其进行引用或者调用错误示范: def foo(): print 'in the foo' bar() foo() 报错: i ...

  4. 一个能让你了解所有函数调用顺序的Android库

    http://mobile.51cto.com/android-536059.htm 原理 本库其实并没有什么黑科技,本库也没有java代码,核心就是2个build.gradle中的task.首先,原 ...

  5. iOS开发app启动原理及视图和控制器的函数调用顺序

    main()函数是整个程序的入口,在程序启动之前,系统会调用exec()函数.在Unix中exec和system的不同在于,system是用shell来调用程序,相当于fork+exec+waitpi ...

  6. python 函数调用顺序

    def foo(): print ('in the foo') bar() def bar(): print ('in the bar') foo() 1.foo函数进入内存 2.bar函数进入内存 ...

  7. C# 构造函数调用顺序

    了解C#的一个类的加载过程,对于语言机制的理解和写出高效的语言很有帮助,这里简单介绍一下类的实例的构造函数调用过程.C#类的实例的构造过程是,先为实例的数据字段分配内存,并对所有字段按字节置零(0或者 ...

  8. c++构造函数析构函数调用顺序

    #include <iostream> using namespace std; class A { public: A () { cout<<"A 构造 " ...

  9. cocos2dx--两个场景切换各函数调用顺序

    场景A切换到场景B,有切换特效 调用顺序例如以下:(AAABABABA) A:构造函数 A:onEnter A:onEnterTransitionDidFinish B:构造函数 A:onExitTr ...

随机推荐

  1. R语言(入门小练习篇)

    问题: 一组学生参加了数学.科学和英语考试.为了给所有的学生确定一个单一的成绩衡量指标,需要将这些科目的成绩组合起来.另外,还想将前20%的学生评定为A,接下来20%的学生评定为B,以此类推.最后,希 ...

  2. Oracle SQL Developer保持数据库连接的方法

    一.概述 从navicat切到pl/sql developer,但是发现个bug,因为本地客户端pl/sql developer的字符集 和数据库服务器的字符集不一致,导致一个很奇葩的东西. 本来我有 ...

  3. Artech的MVC4框架学习——第六章Model的验证

    第一Model验证旨在为通过Model绑定生成参数进行检验以确保用户输入数据的有效性(p318) 第二Model验证分两种:服务器端(三种解决方案 p256)和客户端(ajax\jQuery) 第三服 ...

  4. Artech的MVC4框架学习——第一章初步认识ASP.NET MVC

    前言: Artech觉得掌握ASP.NET MVC具有三个层次. 第一层了解基本的编程模式,掌握Controller和View的定义方式,知道路由如何注册以及验证规则如何定义. 第二个层次要求我们对A ...

  5. Mysql 忘记 root密码解决

    1 stop mysql Ubuntu/Debian: sudo /etc/init.d/mysql stop CentOs: sudo /etc/init.d/mysqld stop 2 启动saf ...

  6. 23种设计模式之享元模式(FlyWeight)

    享元模式是一种对象结构型模式,通过运用共享技术,有效地支持大量细粒度的对象.系统只使用少量的对象,而这些对象都很相似,状态变化很小,对象使用次数增多.享元对象能做到共享的关键是区分内部状态和外部状态. ...

  7. VC++ 学习笔记2 列表框添加字符串

    向列表框添加字符串 现在知道两种方法 方法一:直接在需要添加内容地方输入下面代码  IDC_LIST1为需要添加列表框的ID号 改为你的 ((CListBox*)GetDlgItem(IDC_LIST ...

  8. Android ScrollView嵌套ScrollView滚动的问题解决办法

    引用:http://mengsina.iteye.com/blog/1707464 http://fenglog.com/article.asp?id=449 Android ScrollView嵌套 ...

  9. Unity3D笔记 愤怒的小鸟<六> 弹弓发射小鸟

    要实现的目标 实现个性化的鼠标 实现弹弓 选择小鸟.拉升弹弓.发射小鸟 弹弓橡皮筋 声音 1.实现个性化鼠标 效果 2.添加弹弓 建立两个材质 创建一个空GameObject 把两个shoot拖进来统 ...

  10. iOS - 开发一套代码多个app展示不同图标和名称

    引言 公司项目重构之后,有了相对比较完善的开发体系,首先git分支分为日常.预发.生产三个主要分支,开发阶段都在日常(daily)分支下开相应功能的feature分支,开发完再合并. 我的iOS工程需 ...