Forms
Word has accumulated three separate ways to put a fillable control in a document, and UniOffice exposes all three. They do not interoperate: a control built with one is read back with that one’s API, and a document can contain all three at once with each invisible to the other two. Word groups them in the same Developer ribbon section, which is why they get confused for one another.
| Mechanism | Create with | Read back with | Reach for it when |
|---|---|---|---|
| Legacy form fields | para.AddTextInput, AddCheckBox, AddDropdownList | doc.FormFields() | You are filling a document somebody else produced this way. |
| Content controls | doc.AddStructuredDocumentTag(), para.AddStructuredDocumentTag(), cell.AddStructuredDocumentTag() | doc.StructuredDocumentTags(), para.StructuredDocumentTags() | You are writing new documents. This is Word’s current mechanism and the only one with rich text, date pickers and locking. |
| ActiveX controls | not possible | run.Control(), then a type switch over ctrl.Choice | The document already contains them. |
Content controls are the default answer. They are the only mechanism where
creation and read-back both work end to end, and the only one whose controls can
hold formatted content, a table, or an image. Each carries a Tag that a
program looks it up by and an Alias that a person sees, and comes in plain
text, rich text, date, drop-down list, combo box and picture variants. SetLock
keeps a control from being deleted while leaving its contents editable, which is
what makes them usable as template regions.
Legacy form fields are worth knowing about because they turn up in older
templates, not because you would choose them. There are exactly three types, no
formatting, and several of the FormField setters overwrite the field’s whole
property list rather than one property of it. Creating them programmatically
also does not survive a save in the current release; the details are on
Legacy Form Fields. Reading and filling existing ones works
fine.
ActiveX is read-and-modify only, and it is the rawest of the three.
run.Control() hands back a schema type and you branch on which of
Choice.CheckBox, Choice.TextBox, Choice.ComboBox and the rest is non-nil.
There is no typed wrapper, no interface, and no constructor. A control type the
library does not model still round-trips unchanged on save, but there is nothing
you can read or write on it.
Both doc.FormFields() and doc.StructuredDocumentTags() walk the whole
document, tables, headers and footers included, so a program can find and fill
every field without knowing the layout. StructuredDocumentTags() also descends
into controls nested inside other controls. That overlaps with what the
templates guides do by string substitution;
content controls survive editing where placeholder strings do not.
Where to look
| Guide | Covers |
|---|---|
| Legacy Form Fields | Adding legacy text, checkbox and drop-down fields. |
| Content Controls | Structured document tags: every control type, locking, placeholders, and discovery by tag. |
| ActiveX Controls | Reading and setting ActiveX control values. |
| Fill Out a Form | Populating the fields of a document you opened. |