缺少方法的奇怪情况:SXS和控件.在“对象不支持此属性或方法"中添加结果吗? [英] Strange Case of the missing method: SXS and Controls.Add results in "object doesn't support this property or method"?

查看:119
本文介绍了缺少方法的奇怪情况:SXS和控件.在“对象不支持此属性或方法"中添加结果吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用VB6编写的使用UserControl的项目,当注册OCX时该项目运行良好,但是如果我并排运行同一项目,则显示错误.

I have a project written in VB6 that uses a UserControl, The project runs fine when the OCX is registered, but if I run the same project with a side by side manifest it results in an error.

只要控件是静态加载的(在窗体上之前添加),我就可以毫无问题地使用该控件,但是如果我在使用任何新控件(属性或方法)时向其添加动态控件,则会出现此错误:

I can use the Control with no problem as long as it's loaded statically (added before on the form) but if I add a dynamic control to form on any use of the new control (property or method) I get this error:

对象不支持此属性或方法

Object doesn't support this property or method

此错误可以通过以下方式重现:

This error can be reproduced this way:

  1. 在VB6中创建OCX项目
  2. 添加用户控件
  3. 添加方法,例如DoSomething到控件
  4. 创建一个exe项目
  5. 将控件添加到表单中,例如UserControl1
  6. 在事件调用中DoSomething
  7. 动态加载,例如:

  1. Create an OCX project in VB6
  2. Add a user control
  3. Add a method, e.g. DoSomething to the control
  4. Create an exe project
  5. Add the control to form, e.g. UserControl1
  6. In an event call DoSomething
  7. Load dynamically Like:

Dim y As Control
UserControl1.DoSomething        '<-------- CASE(1) THIS IS ALLRIGHT!'
Set y = Controls.Add("Project1.UserControl1", "y")
y.DoSomething                   '<---- (CASE 2) THIS WILL FAIL USING SXS'

我将WinDbg中的错误追溯到IDispatch::GetIDsOfNames,在第二种情况下调用该错误将失败.

I tracked the error in WinDbg back to IDispatch::GetIDsOfNames that when called in second case will fail.

有什么主意吗?!

我的坏人,这是清单.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity name="client.exe" version="1.0.0.0" type="win32" processorArchitecture="x86"/>

<file name="Project1.ocx">
 <comClass
     clsid="{C8CF7991-A8F2-4360-9404-03C9A052C245}"
     description="Project1.UserControl1"
     tlbid="{47853CCC-7BE6-4377-9C82-38A0B7755F65}"
     threadingModel="apartment"
     miscStatusContent="recomposeonresize,cantlinkinside,insideout,activatewhenvisible,setclientsitefirst"
     progid="Project1.UserControl1"/>
 <typelib
     tlbid="{47853CCC-7BE6-4377-9C82-38A0B7755F65}"
     version="1.0"
     helpdir=""
     flags="control,hasdiskimage"/>
</file>

<comInterfaceExternalProxyStub 
     iid="{0E4F313E-7EF3-4FE6-9591-9F7D2D819AEE}"
     name="UserControl1"
     proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"/>
<comInterfaceExternalProxyStub 
     iid="{53307849-4F14-4A59-B0CA-DE4950CE499D}"
     name="UserControl1"
     proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"/>

</assembly>

推荐答案

简短的答案:这是VB6的已知问题. "Controls.Add"语句不能同时使用.尝试改用加载"语句.

The short answer: This is a known problem with VB6. The "Controls.Add" statement does not work with side-by-side. Try using a "Load" statement instead.

长答案:即使您使用ProgID创建控件,VB6仍将控件的CLSID编译为可执行文件.执行"Control.Add"将验证CLSID相同.不要问为什么,这是一个不为所动的谜团.同时,必须准备并排win32(与.Net并排-另一个主题),以处理多个清单使用的同一ProgID(在激活上下文之间切换时) (例如),因此它会在内部为每个ProgID生成一个新的临时CLSID.最后,当您调用CLSIDFromProgID时,您将获得临时的CLSID.如果您随后调用CoCreateInstance,它将正常工作-sxs使用CLSID.但是,如果您要在任何地方(注册表,内部表)查找CLSID,都将找不到它.接下来是VB6程序,它调用CLSIDFromProgID,然后检查接收到的CLSID是否在内部表中.失败.

The long answer: VB6 compiles the CLSID of the control into the executable even though you use a ProgID to create the control. Execution of "Control.Add" verifies that the CLSID is the same. Don't ask why, this is a mystery better not touched. At the same time win32 side-by-side (as opposed by .Net side-by-side -- another topic) must be prepared to handle the same ProgID being used by more than one manifest (when you flip-flop between activation contexts, for example) so it internally generates a new, temporary, CLSID for each ProgID. In the end when you call CLSIDFromProgID you will get the temporary CLSID. If you then call CoCreateInstance it works fine - sxs honors the CLSID. But if you go looking for the CLSID anywhere (registry, your internal table) you will not find it. And here comes the VB6 program calling CLSIDFromProgID then checking if the CLSID it receives is in the internal table. Fail.

这篇关于缺少方法的奇怪情况:SXS和控件.在“对象不支持此属性或方法"中添加结果吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆