It would appear that this is due to a bug where the base class'es property is not properly mapped to the child class property!
ACADProject.FormENU
inherits from MSForms.UserForm
. It has much more properties and methods than MSForms.UserForm
, but it is a MSForms.UserForm
, hence it can be stored in a variable of type MSForms.UserForm
.
It would appear that internally MSForms.UserForm
and its subclasses (the actual user forms designed by users) are implemented as different objects where the properties of the base dummy object return whatever the properties of the actual derived object return (which makes it look more of a has-a from the link above than of an is-a).
And it would appear that whoever mapped all the properties of MSForms.UserForm
to return the respective values of the actual subclass, forgot to map the Caption
property:
Dim FormAsSelf As UserForm1
Dim FormAsForm As MSForms.UserForm
Dim FormAsObject As Object
Set FormAsSelf = New UserForm1
Set FormAsForm = FormAsSelf
Set FormAsObject = FormAsSelf
Debug.Print "Caption from self: ", FormAsSelf.Caption, TypeName(FormAsSelf), ObjPtr(FormAsSelf), TypeOf FormAsSelf Is UserForm1
Debug.Print "Caption from form: ", FormAsForm.Caption, TypeName(FormAsForm), ObjPtr(FormAsForm), TypeOf FormAsForm Is UserForm1
Debug.Print "Caption from object: ", FormAsObject.Caption, TypeName(FormAsObject), ObjPtr(FormAsObject), TypeOf FormAsObject Is UserForm1
Unload FormAsSelf
Title |
Caption |
Type name |
Object address |
Is a UserForm ? |
Caption from self: |
UserForm1 |
UserForm1 |
4144272 |
True |
Caption from form: |
|
UserForm1 |
96261568 |
True |
Caption from object: |
UserForm1 |
UserForm1 |
4144272 |
True |
The other properties appear to be mapped correctly, so if you design a form with a pink background and request .BackColor
instead of .Caption
in the code above, you will get the same answer from all three (actually two) "sides" of the form:
Title |
BackColor |
Type name |
Object address |
Is a UserForm ? |
Caption from self: |
16744703 |
UserForm1 |
4144272 |
True |
Caption from form: |
16744703 |
UserForm1 |
96261568 |
True |
Caption from object: |
16744703 |
UserForm1 |
4144272 |
True |
As noted in a comment under a related question, this entire inheritance situation is similar to the relationships between Sheet1
and Worksheet
. Those, however, appear to be implemented differently internally, so there is only one "side" to begin with:
Dim SheetAsSelf As Sheet1
Dim SheetAsSheet As Excel.Worksheet
Dim SheetAsObject As Object
Set SheetAsSelf = ThisWorkbook.Worksheets(1)
Set SheetAsSheet = SheetAsSelf
Set SheetAsObject = SheetAsSelf
Debug.Print "Caption from self: ", SheetAsSelf.Name, TypeName(SheetAsSelf), ObjPtr(SheetAsSelf), TypeOf SheetAsSelf Is Sheet1
Debug.Print "Caption from sheet: ", SheetAsSheet.Name, TypeName(SheetAsSheet), ObjPtr(SheetAsSheet), TypeOf SheetAsSheet Is Sheet1
Debug.Print "Caption from object: ", SheetAsObject.Name, TypeName(SheetAsObject), ObjPtr(SheetAsObject), TypeOf SheetAsObject Is Sheet1
Title |
Name |
Type name |
Object address |
Is a Sheet1 ? |
Caption from self: |
Sheet1 |
Worksheet |
463669552 |
True |
Caption from sheet: |
Sheet1 |
Worksheet |
463669552 |
True |
Caption from object: |
Sheet1 |
Worksheet |
463669552 |
True |
(Although, if you dig deep enough, you will find that Worksheets are into even crazier shenanigans!)