Restricting Field Access
When defining a template, one may not be interest in certain fields of the structure at all, or one may only require read or write access to particular fields. The external field objects have a set of attributes that can be set to record this information. For example, we currently retrieve window placement information primarily so that we can reset it, so we define WINDOWPLACEMENT as follows:
defineField: #length type: DWORDField writeOnly;
defineField: #flags type: DWORDField filler;
defineField: #showCmd type: DWORDField new;
defineField: #ptMinPosition type: (StructureField type: POINTL) beFiller;
defineField: #ptMaxPosition type: (StructureField type: POINTL) beFiller;
defineField: #rcNormalPosition type: (StructureField type: RECT)
If we compile this structure, then we will not get compiled accessors for the filler fields. If the structure is not compiled or uncompiled, then a MessageNotUnderstood exception will be raised if any attempt is made to get or set those fields.
WINDOWPLACEMENT also includes a write only field, the first, #length. A common Win32™ practice is for the first field of a structure to be a 32-bit integer specifying the length of the structure. This is useful for both error checking (the callee can verify that the structure is of a size it is expecting) and versioning (the callee can sometimes tell which version of an API the caller is expecting to use by testing the structure size). We must set the length field to satisfy Windows™ that we've passed the appropriate structure, but we never need to read it. When compiled we would not get an automatically generated read accessor for the length field, and if uncompiled attempting to read it would generate a MessageNotUnderstood exception.
We can mark fields as read only in a similar way; examples can be found in DRAWITEMSTRUCT:
defineField: #ctlType type: DWORDField readOnly;
defineField: #ctlID type: DWORDField readOnly;
defineField: #itemID type: DWORDField readOnly;
defineField: #itemAction type: DWORDField readOnly;
defineField: #itemState type: DWORDField readOnly;
defineField: #hwndItem type: DWORDField readOnly;
defineField: #hDC type: DWORDField readOnly;
defineField: #rcItem type: (StructureField type: RECT) beReadOnly;
defineField: #itemData type: DWORDField readOnly
Note that this structure includes another embedded ExternalStructure. When #rcItem is sent to a DRAWITEMSTRUCT the answer will be a pointer instance of RECT which references the original data, i.e. modifications to the RECT will update the DRAWITEMSTRUCT in place. An identical but independent RECT could be obtained by sending the original answer from #rcItem the #copy message.