tag:blogger.com,1999:blog-3330363568531008511.post-38604015927672936512007-05-02T12:55:00.000-07:002009-04-08T14:07:52.294-07:00Visual Form File formatXAML 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!<br /><br />We've had something like this for years in the VCF! And the predecessor 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:<br /><br /><pre><br />component-decl ::= "object" component-id component-properties <br /> *(component-decl) [component-delegates] "end"<br />component-id ::= component-name component-class ["," component-classid]<br /><br />component-name ::= id<br />id ::= ALPHA *(ALPHA | DIGIT | '_' )<br />component-class ::= ALPHA *(ALPHA | DIGIT | '_' | "::" )<br />component-classid ::= ''' 1*(ALPHA | DIGIT | '-' ) '''<br /><br />component-properties ::= 1*component-property<br />component-property ::= property-name '=' property-value<br />property-name ::= id | property-object-name | property-collection-name<br />property-object-name ::= id '.' property-name<br />property-collection-name ::= id '[' property-collection-key ']'<br />property-collection-key ::= property-number | property-string<br />property-value ::= property-string | property-number | <br /> property-component-ref | property-enum |<br /> property-enum-mask | property-binary | property-bool<br /><br /><br />property-string ::= ''' *(ALPHA | DIGIT | 'any printable unicode char' ) '''<br />property-number ::= 1*DIGIT ['.' 1*(DIGIT) ]<br />property-component-ref ::= ('@' component-name) | "null"<br />property-enum ::= id<br />property-enum-mask ::= '[' property-enum *[',' property-enum] ']'<br />property-binary ::= '{' binary-data '}'<br />binary-data ::= 1*(binary-byte)<br />binary-byte ::= (DIGIT | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' ) <br /> (DIGIT | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' )<br />property-bool ::= "true" | "false"<br /><br />component-delegates ::= "delegates" *(component-delegate-decl) "end"<br />component-delegate-decl ::= delegate-name '=' delegate-array<br />delegate-name ::= id<br />delegate-array ::= '[' 1*(event-handler-ref) ']'<br />event-handler-ref ::= component-instance '@' component-callback-method<br />component-instance ::= id<br />component-callback-method ::= component-classname "::" component-methodname<br />component-classname ::= id<br />component-methodname ::= id<br /></pre><br /><br />A simple example:<br /><pre><br />object window1 : VCF::Window<br /> top = 500<br /> left = 500<br /> width = 400<br /> height = 300<br />end<br /></pre><br />Note that the class name <em>must</em> be a fully qualified C++ class name, including the namespace the class belongs to.<br /><br />A more complex example might look like this:<br /><pre><br />object Form1 : Window, 'ED88C0A1-26AB-11d4-B539-00C04F0196DA'<br /> alignment = AlignNone<br /> anchor = 0<br /> bottom = 555.00000<br /> color.blue = 0.78431<br /> color.green = 0.81569<br /> color.red = 0.83137<br /> height = 537.00000<br /> left = 234.00000<br /> name = 'Form1'<br /> top = 70.00000<br /> visible = true<br /> width = 565.00000<br /><br /> object label1 : VCF::Label, 'ED88C09F-26AB-11d4-B539-00C04F0196DA'<br /> anchor = [AnchorLeft,AnchorRight]<br /> bottom = 100.00000<br /> caption = 'This is a label!'<br /> color.blue = 0.50000<br /> color.green = 1.00000<br /> color.red = 0.00000<br /> height = 45.00000<br /> left = 20.00000<br /> name = 'label1'<br /> textAlignment = taTextLeft<br /> top = 55.00000<br /> verticalAlignment = tvaTextCenter<br /> visible = true<br /> width = 300.00000<br /> wordWrap = false<br /> <br /> delegates<br /> end<br /> end<br /> <br /> delegates <br /> end<br /><br />end<br /></pre><br />This is what we use to load up components dynamically at runtime. So a form can be stored in format, and then loaded at runtime, dynamically no less (!), like so:<br /><br /><pre><br />Window* window = Frame::createWindow( classid(VisualFormFilesWindow) );<br /></pre><br /><br />So no one thinks we're using some new fangled version of C++, "classid" is simply a macro that gets the VCF <a href="http://vcf-online.org/docs/src_manual/classVCF_1_1Class.html">Class</a> instance from a given C++ class type.<br /><br />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! <span style="font-style: italic;">Voila!</span><br /><br />There's more information on the VFF format here: <br /><a href="http://vcfbuilder.org/?q=node/112">Visual Form File format</a><br /><br />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:<br /><pre><br />object myObj : MyObjectWithItems<br /> items[0] = 10<br /> items[1] = 123 <br />end<br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3330363568531008511-3860401592767293651?l=software-windmills.blogspot.com'/></div>Jim Craftonhttp://www.blogger.com/profile/06342609230425703376noreply@blogger.com1