com - 在 VB6 中将 UserControl 作为参数传递时出现问题

标签 com vb6 controls parameters

我有一个 COM 可见的方法,如下所示:

Public Sub SomeMethod(someControl as Object)
On Error Goto ErrHandler    

Dim someSpecificControl as SpecificControl

   MsgBox TypeOf someControl is Control
   MsgBox TypeOf someControl is SpecificControl

   On Error Resume Next
   Set someSpecificControl = someControl
   On Error Goto ErrHandler
   if someSpecificControl is Nothing then
      Exit Sub
   end if

   ' do stuff to the control

End Sub

其他组件将调用此方法(即通过 COM)并传入 SpecificControl 类型的控件。

我的问题是,当通过调试器运行时,参数化控件似乎不是正确的类型,即它在“cast”失败后退出子例程,而我本希望它不会退出。

使用TypeOf 我已经验证了参数化对象的类型为Control(如上所述),但我无法弄清楚为什么它被错误地传入。当在调试器之外运行时,它似乎表现正确 - 但我不能确定(因此这个问题)。

有人能解释一下吗?控件是否可能在装箱-拆箱过程中以某种方式被损坏?有更好的方法吗?

编辑:我按照 Kris Erickson 的建议使用了 TypeName 并得到了一些有趣的结果:

MsgBox TypeName(someControl) 
MsgBox "someControl is of type SpecificControl: " & TypeOf someControl is SpecificControl
MsgBox "someControl is of type UserControl: " & TypeOf someControl is UserControl
MsgBox "someControl is of type Control: " & TypeOf someControl is Control

我得到:

SpecificControl
someControl is of type SpecificControl: False
someControl is of type UserControl: False
someControl is of type Control: True

我想解决这个问题的唯一方法是避免将 UserControl 作为参数传递。

最佳答案

我使用 VBControlExtender 作为参数类型

Public Sub SomeMethod(someControl as VBControlExtender)

然后我得到这样的引用

Dim someSpecificControl as SpecificControl
Dim someSpecificControlExt as VBControlExtender

Set someSpecificControl = someControl.object
Set someSpecificControlExt = someControl

然后使用someSpecificControlExt访问LeftTabIndexTabStopNameMove 等扩展器和 someSpecificControl 的属性来访问我的用户控件的特定方法/属性。

仅供引用,代码的行为取决于用户控件是在当前项目中实现还是在 ocx 中引用。我正在使用Matt Curlands direct user control access hack这也让我能够做到这一点

Dim someSpecificControl as DirectSpecificControl

以便提前绑定(bind)someSpecificControl 属性/方法。

这就是我从控件获取someSpecificControlExt(扩展器)的方式:

Public Function GetExtendedControl(oCtl As IUnknown) As VBControlExtender
    Dim pOleObject      As IOleObject
    Dim pOleControlSite As IOleControlSite

    On Error Resume Next
    Set pOleObject = oCtl
    Set pOleControlSite = pOleObject.GetClientSite
    Set GetExtendedControl = pOleControlSite.GetExtendedControl
    On Error GoTo 0
End Function

这就是我获取 VB6 用户控件的内部 UserControl 的方法:

Public Function GetUserControl(oObj As Object) As UserControl
    Dim pControl        As UserControl

    Call CopyMemory(pControl, ObjPtr(oObj), 4)
    Set GetUserControl = pControl
    Call CopyMemory(pControl, 0&, 4)
End Function

GetUserControl 返回的引用有一个非常奇怪的 QueryInterface 实现 - 似乎 UserControl 接口(interface)专门模拟为 E_NOTIMPLMENTED.

关于com - 在 VB6 中将 UserControl 作为参数传递时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/863039/

相关文章:

c# - 实现用于捕获打印文本的 OPOS 打印机服务对象

vb6 - 无需访问 HKEY_CLASSES_ROOT 的远程 DLL 注册

wpf - 如何将从 Windows 窗体控件创建的位图捕获到 BitmapSource?

c# - 如何在tabcontrol标签页中添加按钮

c++ - CComPtr 和引用计数

.net - 是否可以在 VBScript 中获取 .Net 字符串对象实例?

.net - 注册 regasm 和 regsvcs

ms-access - 我应该如何锁定此 VB6/Access 应用程序中的表?

sql - 累积过去 12 个月的月度总数

controls - LabView - 无法永久更改字符串值,原因是什么?