代码之家  ›  专栏  ›  技术社区  ›  Alfred Myers

为什么TypeLib枚举在visualbasic6.0中不作为枚举公开?

  •  6
  • Alfred Myers  · 技术社区  · 15 年前

    我有一个VB6项目引用COMSVCSLib,其中一个方法调用COMSVCSLib的共享PropertyGroup管理器.CreatePropertyGroup经过 锁定方法 过程 作为参数。

    清除VB6代码:

    Dim groupName       As String
    Dim spmMgr          As COMSVCSLib.SharedPropertyGroupManager
    Dim spmGroup        As COMSVCSLib.SharedPropertyGroup
    
    Dim bGroupExists    As Boolean
    
    Set spmMgr = New COMSVCSLib.SharedPropertyGroupManager
    
    With spmMgr
        Set spmGroup = .CreatePropertyGroup(groupName, LockMethod, Process, bGroupExists)
    
    End With
    

    在对objectbrowser做了一点研究之后,我发现它们都在comsvsclib中作为常量公开。

    Object Browser

    typedef enum {
        LockSetGet = 0,
        LockMethod = 1
    } __MIDL___MIDL_itf_autosvcs_0469_0002;
    

    2 回复  |  直到 15 年前
        1
  •  11
  •   Mike Spross Alex Martelli    15 年前

    免责声明 IDL for VB Tutorial

    VB6要求实际枚举具有名称,而不仅仅是 typedef 我要一个名字。这个 __MIDL___MIDL_itf_autosvcs_0469_0002 类型定义 其中定义了枚举常量。

    在OLE Viewer中查看类型库时 enum 可能是这样的:

    typedef [public] __MIDL___MIDL_itf_autosvcs_0469_0002 LockModes;
    
    typedef enum {
        LockSetGet = 0,
        LockMethod = 1
    } __MIDL___MIDL_itf_autosvcs_0469_0002;
    

    第一个 类型定义 创建公共名称 LockModes 作为自动生成的 MIDL___MIDL_itf_autosvcs_0469_0002 枚举 . 编译原始类型库时 midl 编译器生成了长 __MIDL 原件名称 枚举 自动创建了一个 类型定义

    原始IDL可能这样定义枚举:

    typedef enum {
         LockSetGet = 0,
         LockMethod = 1
    } LockModes;
    

    米德尔 编译器处理 枚举 这样写的定义,它会自动为 枚举 (因为它不见了-它应该出现在 枚举 关键字)。这就是 __米德尔 米德尔 编译器还会自动生成第二个 类型定义 它的别名是 类型定义 自动生成的 姓名。

    问题是VB6无法理解以这种方式创建的枚举。它希望一切都在一个 类型定义 (即,你给出 一个名字,以及命名 ):

    typedef enum LocksMode {
        LockSetGet = 0,
        LockMethod = 1
    } LocksMode;
    

    IDL治疗 类型定义 与C或C++相同的方法是:不必给枚举本身一个名称,因为 已经有名字了,但是你 可以 如果选择,请为枚举指定一个名称。换言之 类型定义 枚举 以及 枚举 作为两个不同的,但模糊相关的东西,所以在你的情况下,它看到一个 类型定义 命名 类型定义 ,这是另一个的公共别名 类型定义

    类型定义 锁定模式 在对象浏览器中,由于它是枚举的别名,因此在对象浏览器中也可以看到枚举常量。然而 实际枚举本身

    为了演示最后一点,如果您在VB6代码中键入此命令,Intellisense将工作并编译,但显然,它不是非常理想:

    MsgBox COMSVCSLib.[__MIDL___MIDL_itf_autosvcs_0469_0002].LockMethod
    

    此代码之所以有效,是因为可以将通常会导致语法错误的名称(例如以下划线开头的名称)放在方括号中,以允许VB6接受通常非法的名称。此外,用自动生成的名称作为常量的前缀也适用于Intellisense,因为它是VB6与 类型定义 只是一个别名回到了这个“真实”,但自动生成的名称,而VB6显然不能把所有的片段放在一起,实现两个名称引用相同 枚举 ).

    枚举 常量,例如, COMSVCSLib.LockMethod 应该有用。我不太清楚这到底为什么有效,我也不确定如果两个不同的 枚举

    最后,通过使用oleviewer中的IDL创建一个自定义IDL文件,替换现有的IDL文件,可以用另一种方法解决这个问题 枚举 typedef带有一个 类型定义 对于每个 枚举 枚举 以及 类型定义 同名(即。 typedef enum LockModes { ... } LockModes; ),但由于oleviewer不一定生成有效的IDL,因此您可能需要对其进行更多的调整才能使其真正编译。如果你能让这个工作,那么你可以参考你的自定义 .tlb 从VB6项目(而不是 COMSVCSLib 图书馆)和 枚举 会像你所期望的那样工作。

    如果您想走这条路,您还需要另外两个工具,它们应该已经安装在您的开发机器上(但您可能需要搜索它们):

    • midl.exe .idl 文件。因此,您可以将IDL从oleviewer复制到记事本中,按照上面所述修改枚举定义,并将其另存为 .idl公司 文件,并将其传递给 midl.exe文件 要创建新的typelib:

      midl my-custom-typelib.idl

    • regtlib.exe :此工具可以注册.tlb文件,如果要将其添加为对VB6项目的引用,则需要该文件:

      regtlib.exe my-custom-typelib.tlb

        2
  •  1
  •   Corin    15 年前

    它作为枚举公开。在classes列表中选择LockModes并查看下面的信息部分。您将看到它是一个枚举。或者你可以打字 LockModes.

    在对象查看器中,枚举中的每个项都标识为常量值,但它不是独立的常量。当您选择 <globals> 类列表中的项。