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?
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).
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).
精彩评论