shell使用两个接口来初始化shell扩展:IShellExtInit和IPersistFile的实例(IClassFactory::CreateInstance创建的对象)。shell使用IShellExtInit接口初始化上下文菜单处理程序,拖放处理程序和属性表处理程序的实例。shell使用IPersistFile来初始化图标处理程序,数据处理程序和放置处理程序的实例。该接口由OLE定义。
IShellExtInit接口向标准的IUnknown接口添加了一个附加成员函数初始化.处理程序的初始化函数应该保留shell传递给该函数的参数的副本以备以后使用。显示如何初始化实例的示例如下。
STDMETHODIMP CShellExt :: Initialize(LPCITEMIDLIST pIDFolder,
LPDATAOBJECT pDataObj,HKEY hRegKey)
{
//初始化可以多次调用。
if(m_pDataObj)
m_pDataObj->Release();
//保存对象指针。
if(pDataObj){
m_pDataObj = pDataObj;
pDataObj->AddRef();
}
//复制注册表句柄。
if(hRegKey)
RegOpenKeyEx(hRegKey,NULL,0L,MAXIMUM_ALLOWED,
&this->hRegKey);
return NOERROR;
}
外壳扩展处理程序必须实现三个功能:入口点函数(通常称为DllMain或LibMain),DllCanUnloadNow和DllGetClassObject.
DllCanUnloadNow和DllGetClassObject基本上与任何OLE进程内服务器DLL相同。以下示例显示了DllCanUnloadNow的使用。
STDAPI DllCanUnloadNow(void)
{
// g_cRefThisDll必须放在instance-specifc中
//数据部分。
return ResultFromScode((g_cRefThisDll==0) ? S_OK : S_FALSE);
}
DllGetClassObject需要公开DLL中对象的类工厂。有关暴露类工厂的更多信息,请参阅Microsoft Win32软件开发工具包(SDK)中包含的OLE文档。以下示例显示如何暴露类工厂。
// DllGetClassObject - 一个DLL entrypoint函数
//大多数进程内服务器DLL。
STDAPI的DllGetClassObject(REFCLSID rclsid,REFIID RIID,LPVOID * ppvOut)
{
*ppvOut = NULL; //假设失败
if(IsEqualIID(rclsid,CLSID_ShellExtension)){
return CShellExtSample_Create(riid, ppvOut);
} else {
return CLASS_E_CLASSNOTAVAILABLE;
}
}