|
Unlike Visual Basic where you can save forms in a text format, Forte
only offers PEX files in which forms themselves are stored in some
sort of uu-encoded format, i.e. totally unreadable and inaccessible.
You can insert/modify class definitions, but forms themselves seem
impossible at this stage.
Theo
|
| I have another customer who is just starting to look into doing
something like this. So I began playing around yesterday and the attached
PEX file is what I came up with it. It is defintely not fancy but it
does have examples of adding: labels, datafields, radiolists, dropdown,
pushbuttons, submenus and menu items. Since pop-ups aren't
supported in V2 I didn't mess with them but under V3 you should be able
to do them as well.
Again, this is very simple example but points out how to do
several things like how to know when a dynamically created button is
clicked as well as when a dynamically created menu itme is activated.
Have Fun!
Jeff
begin TOOL dynoscreen;
includes DisplayProject;
includes Framework;
-- START FORWARD CLASS DECLARATIONS
forward main is mapped;
-- END FORWARD CLASS DECLARATIONS
-- START FORWARD CURSOR DECLARATIONS
-- END FORWARD CURSOR DECLARATIONS
-- START CONSTANT DEFINITIONS
-- END CONSTANT DEFINITIONS
-- START C DATA TYPE DEFINITIONS
-- END C DATA TYPE DEFINITIONS
-- START CLASS DEFINITIONS
class main is mapped inherits from DisplayProject.UserWindow
has public event addedfield;
has public event getval;
has public method Init;
has public method Display;
has public method CheckIfFieldExists(input FieldName: Framework.TextData): boolean;
has property
shared=(allow=on, override=on, default=off);
transactional=(allow=on, override=on, default=off);
monitored=(allow=on, override=on, default=off);
distributed=(allow=off, override=off);
has
+515146310000109800000d5a9fe4010100002101020000000002020600940800
+1d009fff010104210f1011120101011700009fff000000000900000bb80fa000
+000000000000000000010160600000000000000000009d0bb89d0fa000000105
+030301fffd0000000000000c0405000600000201000100004b000001000b0300
+0021010200000000050400001c01000506007a08004d009fff010101010f1011
+120101011700009fff010000000900005dc05dc0000000000303030300020404
+a0a00000000000000000009d5dc09d5dc000000105066b010000005dc05dc000
+060006000021010200000000070706007c08000d009fff010104010f10111201
+01011700009fff34000000097d4b094f0df70000000003030303000501016060
+0000000000000000009d094f9d0df700000105081001000000094f0df7000402
+01009fff009fff0001010000090000000404000000020a000b0c080000210202
+000000000a0b0906000302010000006400000a06007c08000d009fff01010401
+0f1011120101011700009fff3500000009000006830df7000100010303030300
+07010160600000000000000000009d06839d0df7000001050d10010000000683
+0df700040201009fff009fff00010100000e0000000404000000020f0010000d
+0000210202000000000f100e06000302010000000000000f06007c08000d009f
+ff010104010f1011120101011700009fff36000000099d01340003410b8e0001
+000103030303000a010160600000000000000000009d03419d0b8e0000010511
+100100000003410b8e00040102009fff009fff00010100001200000004040000
+0002131415001100002102020000000013151206000302010000006400001306
+007c08000d000000010104010f1011120101011700009fff3a00000009000002
+dd05f50001000103030303000f010160600000000000000000009d02dd9d05f5
+0000010516100100000002dd05f500040202009fff009fff0001010000170000
+000004040000000002001819001a001b00160000210302000000001a191b1706
+000302010000000000001806000302070000000000001906007c08000d009fff
+010104010f1011120101011700009fff3b000000099d02790000a7037c000100
+02030303030013010160600000000000000000009ca79d037c000001051c1001
+00000000a7037c00040101009fff009fff00010100001d000004040000021e00
+1c0000210102000000001e1d06000302010000000000001e060092080081029f
+ff21210401212121212121212100009fff3c00000009000000a7037c00010001
+0303030300190101a0a00000000000000000009ca79d037c0000010301091f02
+0100009e00442094001f00001c0113135768696368206669656c6420746f2067
+65740a1a06007808020102080867657476616c75650102042121212121212121
+1700019fff0e00000009009d013d010b0279000200010303030300130101a0a0
+0000000000000000009d010b9d02790000010909096765742076616c75650002
+011b0600b008000902080877686963686f6e6501020421212121210101011700
+020808746578746461746114000000099d03209ca70237022e00020002030303
+030013010180a00000000000000000009d02379d022e00000103020103200300
+03042000002104020001a60121222324210001a6010125002500001c0103034f
+6e65220001a6010226002600001c01030354776f230001a6010327002700001c
+0105055468726565240001a6010428002800001c010404466f75721406000302
+070000000000001506007c08000d000000010104010f1011120101011700009f
+ff3d000000099d05f564021505990001000203030303000f0101606000000000
+00000000009d02159d0599000001052910010000000215059900040201009fff
+009fff00010100002a0000000404000000022b002c0029000021020200000000
+2b2c2a06000302010000000000002b06007c08000d000000010104010f101112
+0101011700009fff3e000000091100014d057000010001030303030015010160
+600000000000000000009d014d9d0570000001052d1001000000014d05700004
+0201009fff009fff00010100002e0000000404000000022f0030002d00002102
+0200000000302f2e06000302010000000000002f06007c08000d009fff010104
+010f1011120101011700009fff4000000009000000a705700001000103030303
+002b010160600000000000000000009ca79d05700000010531100100000000a7
+057000040102009fff009fff0001010000320000000404000000023300340031
+000021020200000000333432060003020100000000006433060092080081029f
+ff21210401212121212121212100009fff4100000009000000a7027100010001
+03030303002f0101a0a00000000000000000009ca79d02710000010301093502
+0100009e00442094003500001c010b0b526f7720746f205573650a3406009208
+0081029fff21210401212121212121212100009fff42000000099d02d50000a7
+02370001000203030303002f0101a0a00000000000000000009ca79d02370000
+0103010936020100009e00442094003600001c010b0b436f6c20746f20557365
+0a3006009208008102000021210401212121212121212100009fff3f00000009
+9d01669ca700a702a30002000103030303002b0101a0a0000000000000000000
+9ca79d02a300000103010937020100009e00442094003700001c010d0d496e73
+6572742057686572650a2c06007c08000d000000010104010f10111201010117
+00009fff4300000009009d014d00c80599000200010303030300150101606000
+00000000000000009cc89d05990000010538100100000000c805990004010200
+9fff009fff0001010000390000000404000000023a003b003800002102020000
+00003a3b3906000302010000000000003a0600f6080089020303726f7701020b
+21212121210101011700030707496e74656765721000000009000000c802cd00
+01000103030303002c010280a00000000000000000009cc89d02cd0000010302
+0107000a000009ff8100009e004000240301003b0600f6080089020606636f6c
+756d6e01020b21212121210101011700040707496e746567657211000000099d
+02cd0000c802cd0001000203030303002c010280a00000000000000000009cc8
+9d02cd00000103020107000a000009ff8100009e004000240301001006007c08
+000d000707427574746f6e73010104010f1011120101011700059fff2e000000
+09009d034103410df70002000103030303000a01016060000000000000000000
+9d03419d0df7000001053c100100000003410df700040304009fff009fff0001
+0100003d00000000000000040400000000000000023e000000000000003f0040
+004100420000004300440000003c00002107020000000041423f3e4043443d06
+0003020100000000001e3e060092080081029fff212104012121212121212121
+00009fff44000000090000012c0279000100010303030300100101a0a0000000
+0000000000009d012c9d027900000103010945020100009e0044209400450000
+1c0115154669656c64204e616d650a546f204372656174650a3f0600f6080089
+0209096669656c646e616d6501020b2121212121010101170008080854657874
+446174612200000009199d014d00c8023f00020001030303030010010280a000
+00000000000000009cc89d023f000001030201070008000009ff8100009e0040
+0014030100400600780802010209096d616b656c6162656c0102042121212121
+2121211700099fff31000000099d02d59d012c010b02dd000200020303030300
+100101a0a00000000000000000009d010b9d02dd000001090a0a6d616b65206c
+6162656c00020141060078080201020d0d6d616b65646174616669656c640102
+0421212121212121211700069fff0c000000099d06409d012c010b037c000200
+030303030300100101a0a00000000000000000009d010b9d037c000001090d0d
+6d616b65646174616669656c6400020142060078080201020c0c6d616b656472
+6f70646f776e01020421212121212121211700079fff15000000099d0a179d01
+2c010b03be000200040303030300100101a0a00000000000000000009d010b9d
+03be000001090c0c6d616b6564726f70646f776e00020143060078080201020d
+0d6d616b65726164696f6c697374010204212121212121212117000a9fff3200
+0000099d029b9d0237010b0352000300020303030300100101a0a00000000000
+000000009d010b9d0352000001090d0d6d616b65726164696f6c697374000201
+44060078080201020e0e6d616b6570757368627574746f6e0102042121212121
+21212117000b9fff33000000099d060e9d0237010b03e8000300030303030300
+100101a0a00000000000000000009d010b9d03e8000001090e0e6d616b657075
+7368627574746f6e0002010b06007c08000d0008084d61696e47726964010104
+010f10111201010117000c9fff0d00000009009d06e702050205000200010303
+03030007010160600000000000000000009d02059d020500000105461001ffff
+0001f401f400040000009fff009fff0001010000470404024600002100020000
+00004706000302010000000000000c0600030209000000000000471a7e898f9c
+e29ced9d015a9d01669d01729d01df9d01eb9d01f79d02669d02729d027e9d02
+f19d02fe9d030a9d03169d03809d038b9d03979d03e99d04039d04619d04c29d
+04d09d04d89d04e29d04ea9d04f49d04fc9d05089d05109d051b9d05279d0596
+9d05a29d05ae9d061b9d06279d06339d069f9d06ab9d06b79d07099d071b9d07
+6f9d07819d07d69d07ea9d08589d08649d08709d08d39d093b9d09cd9d09de9d
+09ea9d0a3d9d0a599d0ac59d0b279d0b909d0bf79d0c609d0ccb9d0d389d0d42
+9d0d4e9d0d5a9cd9191a385e5f6b7e88898d8f9cad9cd39cd49ce09ce29cec9c
+ed9d010b9d01319d01329d013e9d01559d015a9d01649d01669d01729d01909d
+01b69d01b79d01c39d01da9d01df9d01e99d01eb9d01f79d02159d023d9d023e
+9d024a9d02619d02669d02709d02729d027e9d029c9d02c29d02c39d02cf9d02
+e89d02f19d02fb9d02fe9d030a9d03169d03349d035b9d035c9d03689d037d9d
+03809d038a9d038b9d03979d03b59d03da9d03db9d03dd9d03e99d03ed9d0403
+9d04299d04519d04529d04619d048f9d04b89d04b99d04bc9d04c09d04c29d04
+cc9d04d09d04d89d04dc9d04e29d04ea9d04ee9d04f49d04fc9d05009d05089d
+05109d05149d051b9d05279d05459d056d9d056e9d057a9d05919d05969d05a0
+9d05a29d05ae9d05cc9d05f29d05f39d05ff9d06169d061b9d06259d06279d06
+339d06519d06769d06779d06839d069a9d069f9d06a99d06ab9d06b79d06d59d
+06fa9d06fb9d06fd9d07099d070d9d071b9d07399d07609d07619d07639d076f
+9d07739d07819d079f9d07c79d07c89d07ca9d07d69d07da9d07ea9d08089d08
+2f9d08309d083c9d08539d08589d08629d08649d08709d08989d08bd9d08be9d
+08c19d08c69d08d39d08fe9d09259d09269d09299d092e9d093b9d09609d0988
+9d09899d09959d09b49d09cd9d09d79d09de9d09ea9d0a089d0a2e9d0a2f9d0a
+319d0a3d9d0a419d0a599d0a889d0aaf9d0ab09d0ab39d0ab89d0ac59d0aec9d
+0b169d0b179d0b279d0b529d0b7c9d0b7d9d0b909d0bba9d0be49d0be59d0bf7
+9d0c229d0c4c9d0c4d9d0c609d0c8c9d0cb69d0cb79d0ccb9d0cf19d0d199d0d
+1a9d0d269d0d379d0d389d0d429d0d429d0d4e9d0d5a0000
-20caa1f1
end class;
-- END CLASS DEFINITIONS
-- START SERVICE OBJECT DEFINITIONS
-- END SERVICE OBJECT DEFINITIONS
-- START CURSOR DEFINITIONS
-- END CURSOR DEFINITIONS
-- START TYPEDEF DEFINITIONS
-- END TYPEDEF DEFINITIONS
-- START METHOD DEFINITIONS
------------------------------------------------------------
method main.Init
begin
super.Init();
row = 1;
column = 1;
whichone = new;
fieldname = new;
whichone = new;
end method;
------------------------------------------------------------
method main.Display
begin
//
// Sample code to generate and work with a dyanmic screen.
//
// What we are basically doing is to create new widgets and
// parent them to a grid that is on the display. My grid
// is called MainGrid.
//
//
// Author: Jeff Nester
// Phone: (423)989-9515
///////////////////////////////////////////////////////////
self.Open();
//
// Set up a counter to use when creating labels.
//
TextGraphicCounter : integerdata = new(value=1);
//
// The following is setting up a Submenu called Jeff
// that has doit as an item. If you do not have a menu bar
// already you must instantiate one. My example is starting
// without a menu
//
window.menu = new; // create the necessary holder for the menu
smenu :submenu = new; // create a submenu
smenu.name = 'mFile'; // Name it mFile
smenu.text ='File'; // and display the item File
smenu.parent = self.window.menu; // put it on the screen
mitem : menucommand = new; // create an item
mitem.name = 'mExit'; // the name is mExit
mitem.text = 'Exit'; // and the display message is Exit
mitem.parent = smenu; // add it to the sub menu we set up
event loop
//
// Post the addedfield event so the screen will start with
// the correct data in the list of fields field.
post addedfield;
when task.Shutdown do
exit;
// Make a label
//
when <makelabel>.click do
//
// Labels are of type textgraphic
//
newfield : textgraphic = new;
newfield.text = fieldname.value; // set the label
//
// I am going to generate a unique name for the labels
//
n : textdata = new;
n.replaceparameters('Label %1',TextGraphicCounter);
TextGraphicCounter.setvalue(TextGraphicCounter.value + 1);
newfield.name = n; // set the widgets name
//
// To position the field into the appropriate cell in the
// grid we must set the row and column.
//
newfield.row = row;
newfield.column = column;
newfield.parent = <MainGrid>; // set grid as parent
column = column + 1;
post addedfield; // Notify the screen that a field was added
//
// Add a pushbutton
//
when <makepushbutton>.click do
//
// Verify if the field name already exists if it does
// don't let them add it again.
//
if CheckIfFieldExists(fieldname) then
self.window.messagedialog('Field with name already exists!');
continue;
end if;
newfield : pushbutton = new; // Create the button widget
newfield.label = fieldname.value; // set its label
newfield.name = fieldname.value; // set its name
//
// To position the field into the appropriate cell in the
// grid we must set the row and column.
//
newfield.row = row;
newfield.column = column;
newfield.height = 250; // set button height
newfield.parent = <MainGrid>; // set grid as parent
column = column + 1;
post addedfield; // notify form that it has added a field
//
// Make a DataField
//
when <makedatafield>.click do
if CheckIfFieldExists(fieldname) then
self.window.messagedialog('Field with name already exists!');
continue;
end if;
newfield : datafield = new;
newfield.name = fieldname.value; // set the field name
newfield.textvalue = 'test'; // set a default value
newfield.row = row; // set location to insert
newfield.column = column;
newfield.parent = <MainGrid>; // define parent
column = column + 1;
post addedfield; // notify the list of fields field
//
// Make a drop down list
//
when <makedropdown>.click do
if CheckIfFieldExists(fieldname) then
self.window.messagedialog('Field with name already exists!');
continue;
end if;
newfield : droplist = new; // create the new widget
newfield.name=fieldname.value; // set its name
//
// The next several lines are to create the array of listelements
// to set the droplist to
//
tmp : listelement = new;
tmp.textvalue='One';
tmparray : array of listelement = new;
tmparray.appendrow(tmp);
tmp = new;
tmp.textvalue ='Two';
tmparray.appendrow(tmp);
//
newfield.setelementlist(tmparray); // set the element list
newfield.row = row; // set the insert point
newfield.column = column;
newfield.textvalue = tmparray[1].textvalue;
newfield.parent = <MainGrid>; // define the parent
column = column + 1;
post addedfield; // notify the list all fields field
//
// Make a radio list
//
when <makeradiolist>.click do
if CheckIfFieldExists(fieldname) then
self.window.messagedialog('Field with name already exists!');
continue;
end if;
newfield : radiolist = new; // create new widget
newfield.name=fieldname.value;// set its name
//
// Set up the array of listelements that we need for the
// radio button
//
tmp : listelement = new;
tmp.textvalue='One';
tmp.integervalue = 1;
tmparray : array of listelement = new;
tmparray.appendrow(tmp);
tmp = new;
tmp.textvalue ='Two';
tmparray.appendrow(tmp);
//
newfield.setelementlist(tmparray); // set the widget
newfield.row = row; // define the insert position
newfield.column = column;
newfield.parent = <MainGrid>; // set the parent
column = column + 1;
post addedfield; // notify the list all fields field
//
// When you double click on the list of fields or select
// one and click on the getvalue button we want to go get
// the data associated with the field
//
when <whichone>.doubleclick do
post getval;
when <getvalue>.click do
post getval;
//
// This code actually retrieves the data that is stored in the
// field
//
when getval do
tmp : textdata = new;
//
// Use GetFieldByName to retrieve the particular fieldwidget
fieldobj : fieldwidget = <maingrid>.getfieldbyname(whichone);
//
// Since different kind of widgets store their data differently
// you must cast the object to get to the appropriate attributes
//
if fieldobj <> NIL then
if fieldobj.isa(datafield) then
self.window.messagedialog((datafield)(fieldobj).textvalue);
elseif fieldobj.isa(droplist) then
self.window.messagedialog((droplist)(fieldobj).textvalue);
elseif fieldobj.isa(radiolist) then
self.window.messagedialog((radiolist)(fieldobj).textvalue);
elseif fieldobj.isa(textgraphic) then
self.window.messagedialog((textgraphic)(fieldobj).text);
elseif fieldobj.isa(pushbutton) then
self.window.messagedialog((pushbutton)(fieldobj).label);
else
self.Window.messagedialog('Dont know the field type');
end if;
else
self.window.messagedialog ('No such field');
end if;
//
// To trap a click on a dynamic button you must catch ChildClick
// on the grid and then evaluate what was clicked on and then take
// appropriate action
//
when <maingrid>.ChildClick (DE=eventInfo, FW=child, x=x, y=y, mod=modifier, Node=node, row=row, col=column) do
if fw.isa(pushbutton) then
tmp : textdata = new;
tmp.ReplaceParameters(
'PushButton: %1 was pushed.',
(pushbutton)(fw).name);
self.window.messagedialog(tmp);
end if;
//
// The addedfield event tells us to update the whichone field
// this field is where I show the list of fields. I am updating
// it this way to show how to run through all of the fields in the
// grid.
//
when addedfield do
tmp : array of listelement = new;
tmp2 : listelement;
//
// Performing a For loop through <grid>.Children will return
// all children of the grid.
//
for fw in <maingrid>.children do
tmp2 = new;
tmp2.textvalue.setvalue(fw.name);
tmp.appendrow(tmp2);
end for;
<whichone>.setelementlist( tmp );
//
// To catch activation of the dyanmically created menu bars you
// have to listen for menu.childactivate and then determine
// which one was activated and then take what ever action you
// need to
//
when self.window.menu.childactivate (m = child ) do
if (m.name.isequal('mExit')) then
post task.shutdown;
end if;
end event;
self.Close();
end method;
------------------------------------------------------------
method main.CheckIfFieldExists(input FieldName: Framework.TextData): boolean
begin
fieldobj : fieldwidget = <maingrid>.getfieldbyname(FieldName);
if fieldobj <> NIL then
return TRUE;
end if;
return FALSE;
end method;
-- END METHOD DEFINITIONS
HAS PROPERTY
CompatibilityLevel = 0;
ProjectType = APPLICATION;
Restricted = FALSE;
MultiThreaded = TRUE;
LibraryName = 'dynoscre';
StartingMethod = (class = main, method = Display);
end dynoscreen;
|