65.9K
CodeProject is changing. Read more.
Home

Visual Form File Format

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.86/5 (3 votes)

Apr 8, 2009

BSD

1 min read

viewsIcon

14128

The format for a Visual Form File (VFF) in Backus-Naur format

Introduction

XAML this, XAML that, blah, blah, blah. I get so sick of hearing about how great XAML is, as if this were the most mind altering, earth shaking technology to hit the streets in years. Bah, humbug!

We've had something like this for years in the VCF! And, the predecessors to XAML dates back even further than that, to Delphi's form files, NeXT's NIB files, and so on. So, I thought I'd post what the format for a Visual Form File (VFF) looks like, in Backus-Naur format:

component-decl ::= "object" component-id component-properties 
    *(component-decl) [component-delegates]  "end"
component-id ::= component-name component-class ["," component-classid]

component-name ::= id
id ::= ALPHA *(ALPHA | DIGIT | '_' )
component-class ::= ALPHA *(ALPHA | DIGIT | '_' | "::" )
component-classid ::= ''' 1*(ALPHA | DIGIT | '-' ) '''

component-properties ::= 1*component-property
component-property ::= property-name '=' property-value
property-name ::= id | property-object-name  | property-collection-name
property-object-name ::= id '.' property-name
property-collection-name ::= id '[' property-collection-key ']'
property-collection-key ::= property-number | property-string
property-value ::= property-string | property-number | 
    property-component-ref | property-enum |
    property-enum-mask | property-binary | property-bool


property-string ::= ''' *(ALPHA | DIGIT | 'any printable unicode char' )  '''
property-number ::= 1*DIGIT ['.' 1*(DIGIT) ]
property-component-ref ::= ('@' component-name) | "null"
property-enum ::= id
property-enum-mask ::= '[' property-enum *[',' property-enum]  ']'
property-binary ::= '{'  binary-data  '}'
binary-data ::=  1*(binary-byte)
binary-byte ::= (DIGIT | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' ) 
    (DIGIT | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' )
property-bool ::=  "true" | "false"

component-delegates ::= "delegates"  *(component-delegate-decl) "end"
component-delegate-decl ::= delegate-name '=' delegate-array
delegate-name ::= id
delegate-array ::= '[' 1*(event-handler-ref)  ']'
event-handler-ref ::= component-instance '@' component-callback-method
component-instance ::= id
component-callback-method ::= component-classname "::" component-methodname
component-classname ::= id
component-methodname ::= id

A simple example:

object window1 : VCF::Window
  top = 500
  left = 500
  width = 400
  height = 300
end

Note that the class name must be a fully qualified C++ class name, including the namespace the class belongs to.

A more complex example might look like this:

object Form1 : Window, 'ED88C0A1-26AB-11d4-B539-00C04F0196DA'
 alignment = AlignNone
 anchor = 0
 bottom = 555.00000
 color.blue = 0.78431
 color.green = 0.81569
 color.red = 0.83137
 height = 537.00000
 left = 234.00000
 name = 'Form1'
 top = 70.00000
 visible = true
 width = 565.00000

 object label1 : VCF::Label, 'ED88C09F-26AB-11d4-B539-00C04F0196DA'
  anchor = [AnchorLeft,AnchorRight]
  bottom = 100.00000
  caption = 'This is a label!'
  color.blue = 0.50000
  color.green = 1.00000
  color.red = 0.00000
  height = 45.00000
  left = 20.00000
  name = 'label1'
  textAlignment = taTextLeft
  top = 55.00000
  verticalAlignment = tvaTextCenter
  visible = true
  width = 300.00000
  wordWrap = false
  
  delegates
  end
 end
 
 delegates   
 end

end

This is what we use to load up components dynamically at runtime. So, a form can be stored in this format and then loaded at runtime, dynamically no less (!), like so:

Window* window = Frame::createWindow( classid(VisualFormFilesWindow) );

So, no one thinks we're using some new fangled version of C++; "classid" is simply a macro that gets the VCF class instance from a given C++ class type.

When you call Frame::createWindow(), you get a new instance of your window class (called VisualFormFilesWindow), with all the controls and components as you've defined them in your VFF file! Voila!

There's more information on the VFF format here: Visual Form File format.

Something to note - in the latest version, we now support collection properties that can be specified via the RTTI macros, and can also be modified via the VFF format. For example:

object myObj : MyObjectWithItems
 items[0] = 10
 items[1] = 123 
end