VB6 ImageList Frm 代码生成

发布于 2024-08-26 08:15:41 字数 2212 浏览 9 评论 0原文

注意:这可能是在黑暗中拍摄的,我纯粹出于好奇而问。

当使用 ImageList 控件时Microsoft Common Control lib (mscomctl.ocx) 我发现 VB6 生成的 FRM 代码无法解析为实际属性/方法名称,我很好奇解析是如何进行的。下面给出了生成的 FRM 代码的示例,其中包含 3 个图像的 ImageList:

   Begin MSComctlLib.ImageList ImageList1 
      BackColor       =   -2147483643
      ImageWidth      =   100
      ImageHeight     =   45
      MaskColor       =   12632256
      BeginProperty Images {2C247F25-8591-11D1-B16A-00C0F0283628} 
         NumListImages   =   3
         BeginProperty ListImage1 {2C247F27-8591-11D1-B16A-00C0F0283628} 
            Picture         =   "Form1.frx":0054
            Key             =   ""
         EndProperty
         BeginProperty ListImage2 {2C247F27-8591-11D1-B16A-00C0F0283628} 
            Picture         =   "Form1.frx":3562
            Key             =   ""
         EndProperty
         BeginProperty ListImage3 {2C247F27-8591-11D1-B16A-00C0F0283628} 
            Picture         =   "Form1.frx":6A70
            Key             =   ""
         EndProperty
      EndProperty
   End

根据我的经验,BeginProperty 标记通常意味着正在分配一个复合属性(对象),例如大多数控件的 Font 对象,例如:

Begin VB.Form Form1 
   Caption         =   "Form1"
   ClientHeight    =   10950
   ClientLeft      =   60
   ClientTop       =   450
   ClientWidth     =   7215
   BeginProperty Font 
      Name            =   "MS Serif"
      Size            =   8.25
      Charset         =   0
      Weight          =   400
      Underline       =   0   'False
      Italic          =   -1  'True
      Strikethrough   =   0   'False
   EndProperty
End

可以很容易地看到解析为 VB.Form.Font.

对于 ImageList,没有名为 Images 的属性。与属性 Images 关联的 GUID 指示实现接口 IImages 的 ListImages 类型。这种类型是有意义的,因为 ImageList 控件有一个名为 ListImages 的属性,该属性的类型为 IImages。其次,类型 IImage 上不存在属性 ListImage1、ListImage2 和 ListImage3,但与这些属性关联的 GUID 指示实现接口 IImage 的类型 ListImage。这种类型也是有意义的,因为 IImages 实际上是 IImage 的集合。

我不明白的是 VB6 如何进行这些关联。 VB6 如何知道在名称 Images -> 之间建立关联? ListImages 纯粹是因为关联类型(由 GUID 提供) - 也许是因为它是该类型的唯一属性?其次,它如何将ListImage1、ListImage2和ListImage3解析为集合IImages的添加项,是否使用Add方法?或者也许是 ControlDefault 属性?

也许VB6对此控件具有特定的知识并且不存在逻辑解析?

Note: This is probably a shot in the dark, and its purely out of curiosity that I'm asking.

When using the ImageList control from the Microsoft Common Control lib (mscomctl.ocx) I have found that VB6 generates FRM code that doesn't resolve to real property/method names and I am curious as to how the resolution is made. An example of the generated FRM code is given below with an ImageList containing 3 images:

   Begin MSComctlLib.ImageList ImageList1 
      BackColor       =   -2147483643
      ImageWidth      =   100
      ImageHeight     =   45
      MaskColor       =   12632256
      BeginProperty Images {2C247F25-8591-11D1-B16A-00C0F0283628} 
         NumListImages   =   3
         BeginProperty ListImage1 {2C247F27-8591-11D1-B16A-00C0F0283628} 
            Picture         =   "Form1.frx":0054
            Key             =   ""
         EndProperty
         BeginProperty ListImage2 {2C247F27-8591-11D1-B16A-00C0F0283628} 
            Picture         =   "Form1.frx":3562
            Key             =   ""
         EndProperty
         BeginProperty ListImage3 {2C247F27-8591-11D1-B16A-00C0F0283628} 
            Picture         =   "Form1.frx":6A70
            Key             =   ""
         EndProperty
      EndProperty
   End

From my experience, a BeginProperty tag typically means a compound property (an object) is being assigned to, such as the Font object of most controls, for example:

Begin VB.Form Form1 
   Caption         =   "Form1"
   ClientHeight    =   10950
   ClientLeft      =   60
   ClientTop       =   450
   ClientWidth     =   7215
   BeginProperty Font 
      Name            =   "MS Serif"
      Size            =   8.25
      Charset         =   0
      Weight          =   400
      Underline       =   0   'False
      Italic          =   -1  'True
      Strikethrough   =   0   'False
   EndProperty
End

Which can be easily seen to resolve to VB.Form.Font.<Property Name>.

With ImageList, there is no property called Images. The GUID associated with property Images indicates type ListImages which implements interface IImages. This type makes sense, as the ImageList control has a property called ListImages which is of type IImages. Secondly, properties ListImage1, ListImage2 and ListImage3 don't exist on type IImages, but the GUID associated with these properties indicates type ListImage which implements interface IImage. This type also makes sense, as IImages is in fact a collection of IImage.

What doesn't make sense to me is how VB6 makes these associations. How does VB6 know to make the association between the name Images -> ListImages purely because of an associated type (provided by the GUID) - perhaps because it's the only property of that type? Secondly, how does it resolve ListImage1, ListImage2 and ListImage3 into additions to the collection IImages, and does it use the Add method? Or perhaps the ControlDefault property?

Perhaps VB6 has specific knowledge of this control and no logical resolution exists?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

哎呦我呸! 2024-09-02 08:15:41

您可以通过这个相当人为的示例来了解发生了什么。从 ActiveX 项目开始,添加 Class1 并将其标记为 Persistable = 1

' Class1
Option Explicit

Private m_sText As String

Property Get Text() As String
    Text = m_sText
End Property

Property Let Text(sValue As String)
    m_sText = sValue
End Property

Private Sub Class_ReadProperties(PropBag As PropertyBag)
    With PropBag
        m_sText = .ReadProperty("txt", "")
    End With
End Sub

Private Sub Class_WriteProperties(PropBag As PropertyBag)
    With PropBag
        .WriteProperty "txt", m_sText, ""
    End With
End Sub

添加 UserControl1

' UserControl1
Option Explicit

Private m_oData As Class1

Property Get Data() As Class1
    Set Data = m_oData
End Property

Private Sub UserControl_Initialize()
    Set m_oData = New Class1
    m_oData.Text = "this is a test"
End Sub

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    With PropBag
        Set m_oData = .ReadProperty("rs", Nothing)
    End With
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    With PropBag
        .WriteProperty "rs", m_oData, Nothing
    End With
End Sub

添加 Form1 并在其上放置 UserControl1 并保存。您可能想要为 Sub Main 添加 Module1

' Module1
Sub Main()
    With New Form1
        .Show
    End With
End Sub

这是我的 Form1.frm 文件

VERSION 5.00
Begin VB.Form Form1 
   Caption         =   "Form1"
   ClientHeight    =   2400
   ClientLeft      =   48
   ClientTop       =   432
   ClientWidth     =   3744
   LinkTopic       =   "Form1"
   ScaleHeight     =   2400
   ScaleWidth      =   3744
   StartUpPosition =   3  'Windows Default
   Begin Project1.UserControl1 UserControl11 
      Height          =   516
      Left            =   924
      TabIndex        =   0
      Top             =   588
      Width           =   1020
      _ExtentX        =   1799
      _ExtentY        =   910
      BeginProperty rs {326250A4-CA0D-4F88-8F20-DAA391CF8E79} 
         txt             =   "this is a test"
      EndProperty
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

因此 UserControl1 确定对象 m_oData 被持久保存为属性 rs 在其 WriteProperty 重载中。 Class1 确定其 m_sText 成员变量(或 Text 公共属性)在 中保留为 txt 成员>IPropertyBag frm 正在通过。没有什么要求公共属性名称与内部属性包名称匹配。我个人会使用短 ID 只是为了最大限度地减少膨胀(如果可能的话,使用 VB6)。

You can see what's going on with this fairly contrived example. Start with an ActiveX project and add Class1 and mark it as Persistable = 1

' Class1
Option Explicit

Private m_sText As String

Property Get Text() As String
    Text = m_sText
End Property

Property Let Text(sValue As String)
    m_sText = sValue
End Property

Private Sub Class_ReadProperties(PropBag As PropertyBag)
    With PropBag
        m_sText = .ReadProperty("txt", "")
    End With
End Sub

Private Sub Class_WriteProperties(PropBag As PropertyBag)
    With PropBag
        .WriteProperty "txt", m_sText, ""
    End With
End Sub

Add UserControl1

' UserControl1
Option Explicit

Private m_oData As Class1

Property Get Data() As Class1
    Set Data = m_oData
End Property

Private Sub UserControl_Initialize()
    Set m_oData = New Class1
    m_oData.Text = "this is a test"
End Sub

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    With PropBag
        Set m_oData = .ReadProperty("rs", Nothing)
    End With
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    With PropBag
        .WriteProperty "rs", m_oData, Nothing
    End With
End Sub

Add Form1 and place a UserControl1 on it as save it. You might wan to add Module1 for Sub Main

' Module1
Sub Main()
    With New Form1
        .Show
    End With
End Sub

Here is my Form1.frm file

VERSION 5.00
Begin VB.Form Form1 
   Caption         =   "Form1"
   ClientHeight    =   2400
   ClientLeft      =   48
   ClientTop       =   432
   ClientWidth     =   3744
   LinkTopic       =   "Form1"
   ScaleHeight     =   2400
   ScaleWidth      =   3744
   StartUpPosition =   3  'Windows Default
   Begin Project1.UserControl1 UserControl11 
      Height          =   516
      Left            =   924
      TabIndex        =   0
      Top             =   588
      Width           =   1020
      _ExtentX        =   1799
      _ExtentY        =   910
      BeginProperty rs {326250A4-CA0D-4F88-8F20-DAA391CF8E79} 
         txt             =   "this is a test"
      EndProperty
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

So UserControl1 determines that object m_oData is persisted as property rs in its WriteProperty overload. Class1 determines that its m_sText member variable (or Text public property) is persisted as txt member in the IPropertyBag the frm is passing. There is nothing that requires public property names to match internal property bag names. I would personally use shorted IDs just to minimize bloat (if possible with VB6 at all).

对你而言 2024-09-02 08:15:41

我猜测 GUID ({2C247F25-8591-11D1-B16A-00C0F0283628}) 指向关联的 ImageList 控件,而 ListImage1、ListImage2 等...只是用来枚举所有图像。

它有点像 WPF 关联控件的早期版本(例如,TextBox 可以引用其封闭的网格进行放置)。

I am guessing that the GUID ({2C247F25-8591-11D1-B16A-00C0F0283628}) points to the associated ImageList control and ListImage1, ListImage2, etc... is just there to enumerate all the images.

It's kind of like an early version of WPF associated controls (e.g. a TextBox can reference its enclosing grid for placement).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文