IMoniker::BindToObject 方法 (objidl.h)
绑定到指定的 对象。 绑定过程涉及查找对象,在必要时将其置于运行状态,并为调用方提供指向所标识对象上指定接口的指针。
语法
HRESULT BindToObject(
[in] IBindCtx *pbc,
[in] IMoniker *pmkToLeft,
[in] REFIID riidResult,
[out] void **ppvResult
);
参数
[in] pbc
指向绑定上下文对象上的 IBindCtx 接口的指针,该接口在此绑定操作中使用。 绑定上下文缓存绑定过程中绑定的对象,包含应用于使用绑定上下文的所有操作的参数,并提供名字对象实现应检索有关其环境的信息的方法。
[in] pmkToLeft
如果名字对象是复合名字对象的一部分,则指向此名字对象左侧的名字对象指针。 此参数主要由名字对象实现者用来启用复合名字对象的各个组件之间的协作。 名字对象客户端应使用 NULL。
[in] riidResult
客户端希望用来与名字对象标识的对象通信的接口的 IID。
[out] ppvResult
接收 riid 中请求的接口指针的指针变量的地址。 成功返回后,*ppvResult 包含指向名字对象标识的对象的请求接口指针。 成功后,实现必须在名字对象上调用 AddRef 。 调用方负责调用 Release。 如果发生错误,*ppvResult 应为 NULL。
返回值
此方法可以返回E_OUTOFMEMORY和E_UNEXPECTED的标准返回值,以及以下值。
返回代码 | 说明 |
---|---|
|
绑定操作成功。 |
|
找不到此名字对象标识的对象,或此名字对象所属的复合名字对象所标识的某个对象。 |
|
无法在绑定上下文 BIND_OPTS 结构指定的时间限制内完成绑定操作。 |
|
绑定操作需要最终用户的帮助。 返回此值的最常见原因是需要密码或需要装载软盘。 返回此值时,使用键“ConnectManually”调用 IBindCtx::GetObjectParam 来检索导致错误的名称对象。 然后,可以调用 IMoniker::GetDisplayName 来获取显示名称,显示传达所需信息的对话框,例如装载软盘的说明或请求密码,然后重试绑定操作。 |
|
找到了中间对象,但它不支持完成绑定操作所需的接口。 例如,如果项名字对象容器不支持 IOleItemContainer 接口,则返回此值。 |
|
无法访问存储对象。 |
此方法还可以返回与 IOleItemContainer::GetObject 方法关联的错误。
注解
BindToObject 实现名字对象的主要函数,即查找由名字对象标识的对象,并返回指向其接口之一的指针。
给调用方的说明
如果使用名字对象作为两个对象之间的持久连接,则通过调用 BindToObject 来激活连接。通常在以下过程中调用 BindToObject :
- 使用调用 CreateBindCtx 函数创建绑定上下文对象。
- 使用名字对象调用 BindToObject ,检索指向所标识对象上所需接口的指针。
- 释放绑定上下文。
- 通过获取的接口指针,对 对象执行所需的操作。
- 使用 完 对象后,释放对象的接口指针。
HRESULT hr; // An error code
IMoniker * pMnk; // A previously acquired interface moniker
// Obtain an IBindCtx interface.
IBindCtx * pbc;
hr = CreateBindCtx(NULL, &pbc);
if (FAILED(hr)) exit(0); // Handle errors here.
// Obtain an implementation of pCellRange.
ICellRange * pCellRange;
hr = pMnk->BindToObject(pbc, NULL, IID_ICellRange, &pCellRange);
if (FAILED(hr)) exit(0); // Handle errors here.
// Use pCellRange here.
// Release interfaces after use.
pbc->Release();
pCellRange->Release();
如果只打算执行一个绑定操作,并且不需要保留绑定上下文对象,也可以使用 BindMoniker 函数。 此帮助程序函数封装绑定上下文的创建、调用 BindToObject 和释放绑定上下文。
支持对象链接的 COM 容器使用名字对象来查找链接对象并获取对链接对象的访问,但通常不直接调用 BindToObject 。 相反,当用户激活容器中的链接时,链接容器通常使用链接处理程序的实现调用 IOleObject::D oVerb,该实现在链接对象中存储的名字对象上调用 BindToObject (如果它无法处理谓词) 。
实施者说明
实现的功能取决于你是否希望名字对象具有前缀;也就是说,无论你期望 pmkToLeft 参数是否为 NULL 。 例如,标识容器中的对象的项名字对象需要 pmkToLeft 标识容器。 因此,项名字对象使用 pmkToLeft 从该容器请求服务。 如果希望名字对象具有前缀,则应使用 pmkToLeft 参数 (例如,调用其上的 BindToObject) 从它标识的对象请求服务。如果预期名字对象没有前缀,则 BindToObject 实现应首先检查正在运行的对象表 (ROT) ,以查看对象是否已在运行。 若要获取指向 ROT 的指针,实现应调用对pbc 参数的 IBindCtx::GetRunningObjectTable。 然后,可以调用 IRunningObjectTable::GetObject 方法,查看当前名字对象是否已在 ROT 中注册。 如果是这样,可以立即调用 QueryInterface 以获取指向调用方请求的接口的指针。
BindToObject 实现绑定到某个对象时,它应使用pbc 参数调用 IBindCtx::RegisterObjectBound,以在绑定上下文中存储对绑定对象的引用。 这可确保绑定对象一直运行,直到释放绑定上下文,这可以避免后续绑定操作在以后再次加载它的费用。
如果绑定上下文的BIND_OPTS结构指定BINDFLAGS_JUSTTESTEXISTENCE标志,则实现可以选择在 ppvResult (中返回 NULL,但你也可以忽略标志并) 执行完整的绑定操作。
特定于实现的注释
实现 | 备注 |
---|---|
反名字对象 | 未实现此方法。 它返回E_NOTIMPL。 |
类名字对象 |
如果 pmkLeft 为 NULL,则调用 CoGetClassObject,使用 CLSID 使用 CreateClassMoniker 中的 (或通过 MkParseDisplayName) 和当前 (IBindCtx) 的 CLSCTX 初始化类名字对象。
如果 pmkLeft 为非 NULL,请为 IClassActivator 调用 pmkLeft-BindToObject>,并使用其初始化的 CLSID 调用 IClassActivator::GetClassObject,以及当前 (IBindCtx) 的 CLSCTX 和区域设置参数。 |
文件名字对象 |
当 pmkToLeft 为 NULL 时,该方法在 ROT 中查找名字对象,如果找到,则查询所请求接口指针的检索对象。 如果在 ROT 中找不到名字对象,则 方法从文件系统加载 对象并检索请求的接口指针。
如果 pmkLeft 不为 NULL,则调用 pmkLeft-BindToObject> for IClassFactory 和 IClassActivator,而不是使用 GetClassFile (或其他方法) 文件名字对象引用的文件内容来实例化和初始化类,而是在 pcf 中检索此指针。 如果此操作失败并出现E_NOINTERFACE,则返回MK_E_INTERMEDIATEINTERFACENOTSUPPORTED。 如果成功检索 IClassFactory 指针,请调用 pcf-CreateInstance> (IID_IPersistFile, (void**) &ppf) ,以获取要初始化的类的新实例,并使用 IPersistFile 或其他适当的方法根据文件名字对象的现有初始化路径对其进行初始化。 |
泛型复合名字对象 | 如果 pmkToLeft 为 NULL,此方法在 ROT 中查找名字对象,如果找到,则查询所请求接口指针的检索对象。 如果 pmkToLeft 不为 NULL,该方法以递归方式调用复合的最右侧组件上的 BindToObject ,并将复合的其余部分作为该调用的 pmkToLeft 参数传递。 |
项名字对象 | 如果 pmkToLeft 为 NULL,则此方法返回E_INVALIDARG。 否则,方法调用 pmkToLeft 参数上的 BindToObject,请求 IOleItemContainer 接口指针。 然后, 方法调用 IOleItemContainer::GetObject,传递名字对象中包含的字符串,并返回请求的接口指针。 |
OBJREF 名字对象 | pmkToLeft 参数必须为 NULL。 由于 OBJREF 名字对象表示正在运行的对象,因此不会进行激活。 如果表示的对象不再运行, BindToObject 将失败并E_UNEXPECTED。 |
指针名字对象 | 此方法查询所请求接口的包装指针。 |
URL 名字对象 | 由于 URL 名字对象支持异步绑定,因此其 BindToObject 的实际返回值可能因绑定上下文中建立的对象参数而异。 有关详细信息,请参阅以下内容。 |
无论使用同步还是异步使用,URL 名字对象的绑定操作的语义都是相同的,如下所示:
- URL 名字对象从绑定上下文中拉取绑定操作的进一步信息。 例如,名字对象可以获取指向在绑定上下文中注册的 IBindStatusCallback 和 IEnumFORMATETC 接口的指针。 更多信息可以包括通过 IBindCtx::SetBindOptions 在绑定上下文中指定的其他绑定选项,例如 dwTickCountDeadline 参数或 BIND_MAYBOTHERUSER 的 grfFlags 值。
-
接下来,名字对象检查绑定上下文的 ROT,以确定引用的对象是否已在运行。 名字对象可以通过以下调用获取此信息:
IBindCtx::GetRunningObjectTable(&prot) prot->IsRunning(this)
-
如果对象已在运行,则名字对象使用以下调用检索正在运行的对象:
prot->GetObject(this, &punk)
- 然后,名字对象为请求的接口调用 QueryInterface 。
- 否则,名字对象通过调用 IBindStatusCallback::GetBindInfo 来查询客户端以获取其他绑定信息。 然后,名字对象启动绑定操作,并通过调用 IBindStatusCallback::OnStartBinding 将生成的 IBinding 接口传递回客户端。
- 如果在步骤 1 中确定这是异步绑定,则 BindToObject 此时返回MK_S_ASYNCHRONOUS,ppv 中为 NULL。 调用方将在稍后的某个时间点接收 IBindStatusCallback::OnObjectAvailable 方法期间的实际对象指针。 然后,以下步骤以异步方式对调用方执行,通常是在另一个执行线程上。
-
URL 名字对象指定的资源的类通过以下方法之一确定:
- URL 名字对象检查数据的媒体类型。 如果媒体类型是 application/x-oleobject,则实际数据 (Content-Body 的前 16 个字节) 包含资源的 CLSID,后续数据将由 类本身解释。 对于所有其他媒体类型,URL 名字对象在系统注册表中查找 HKEY_CLASSES_ROOT\MIME\Database\Content-Type\<media-type>\CLSID 密钥。 请注意,在批准 application/oleobject 之前,将使用 application/x-oleobject。
- URL 名字对象将到达数据的某些部分与 HKEY_CLASSES_ROOT\FileTypes 下系统注册表中注册的模式匹配。
- 最后,如果所有其他操作都失败,URL 名字对象使用 HKEY_CLASSES_ROOT\.??? 将资源的尾随扩展(如果有)关联到 CLSID 系统注册表中的键,由 GetClassFile 和 shell 完成。
- 确定 类后,URL 名字对象使用 coCreateInstance 创建一个实例,CLSCTX_SERVER请求 IUnknown 接口。
- URL 名字对象接下来为 IPersistMoniker 接口调用新创建的 对象的 QueryInterface 方法。 如果 QueryInterface 成功,则 URL 名字对象调用 IPersistMoniker::Load , (此) 作为名字对象参数传递自己。 对象通常调用 BindToStorage ,询问他们感兴趣的存储接口。
-
否则,URL 名字对象调用 QueryInterface for IPersistStream ,如果成功,则调用 IPersistStream::Load,为传输异步填充的流对象传递 IStream 指针。
如果要调用的类未标记为类别CATID_AsyncAware,则调用 ISequentialStream::Read 或 ISequentialStream::Write 引用数据块,直到数据变得可用。 这些调用在传统 COM 意义上会阻止。 将输入一个消息循环,该循环允许处理某些消息,并相应地调用线程的 IMessageFilter 。
如果类标记为类别CATID_AsyncAware,则对 ISequentialStream::Read 或 ISequentialStream::Write 的调用,该引用数据尚不可用将返回E_PENDING。
- 否则,URL 名字对象调用 QueryInterface for IPersistFile ,如果成功,则会将下载完成到临时文件中。 完成后,URL 名字对象调用 IPersistFile::Load。 创建的文件与其他 Internet 下载的数据一起缓存。 客户端必须确保不删除此文件。
- 当对象从前面步骤中所述的各种 Load 调用之一返回时,URL 名字对象将调用 IBindStatusCallback::OnObjectAvailable 方法,以返回客户端在客户端调用 BindToObject 时客户端最初请求的接口指针。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows 2000 Professional [仅限桌面应用] |
最低受支持的服务器 | Windows 2000 Server [仅限桌面应用] |
目标平台 | Windows |
标头 | objidl.h |