While I labor over my post for my 3rd law of EnScript, here's an interesting problem. A former colleague of mine, Jeff, emailed me with a sample script. He wanted his user interface to be a wizard, and wanted a subsequent tab to update what it displayed based upon what the user put into the previous tab.
If the only update that needs to occur is to redisplay data from some variable, then this will happen automatically. When the user clicks "Next" on a tab, the widgets on that dialog will write their data to their corresponding variables. When the next tab is displayed, that dialog will automatically re-read its variables. If variables are being shared between widgets on the different dialogs, then everything will appear to be in sync.
However, if you need to do something more complex (a simple example being to update the text in a
StaticTextClass, which doesn't have a linked variable), then you need to override
DialogClass::ActivateEvent().
ActivateEvent() is called whenever a
DialogClass object is displayed, i.e., has become active. There's also
WindowClass::Setup(), which is called when a dialog, or a parent dialog, is first displayed because of
Execute() or
Wizard().
Meanwhile,
CanClose() corresponds to the user clicking "Ok" or one of "Next" or "Previous". Returning false from
CanClose() will cause the user to remain looking at the current dialog; the idea is that you could perform some validation in
CanClose() and if it failed, call
ErrorMessage() and return false.
With
DialogClass/
WindowClass virtual functions, it is generally necessary to call the parent function. If you don't, bad things will happen. The exception to this is
CheckControls().
Below is a modified version of Jeff's test script that demonstrates how this works. Try modifying one of the
ActivateEvent() functions to return false.
class MainClass {
String test, test2;
int myint;
void Main() {
myint = 7;
test = "text";
test2 = "text2";
SystemClass::ClearConsole();
MasterDialogClass dlg(this);
dlg.Wizard();
}
}
class PageDialogClass1: DialogClass {
StaticTextClass Message;
PageDialogClass1(DialogClass parent, MainClass &m):
DialogClass(parent, "First Page"),
Message(this, m.test, START, START, DEFAULT, DEFAULT, READONLY)
{
}
}
class PageDialogClass2: DialogClass {
StringEditClass Str_Text;
IntEditClass Int;
PageDialogClass2(DialogClass parent, MainClass &m):
DialogClass(parent, "Second Page"),
Str_Text (this, "Text", START, START, 80, DEFAULT, 0, m.test2, 80, WindowClass::REQUIRED),
Int(this, "Int", SAME, NEXT, 100, DEFAULT, 0, m.myint, 0, 30, 0)
{
}
virtual void Setup() {
Console.WriteLine("Page2 Setup");
DialogClass::Setup();
}
virtual bool ActivateEvent() {
Console.WriteLine("Page2 ActivateEvent");
return DialogClass::ActivateEvent();
}
virtual bool CanClose() {
Console.WriteLine("Page2 CanClose");
return DialogClass::CanClose();
}
}
class PageDialogClass3: DialogClass {
MainClass Main;
StaticTextClass Message;
IntEditClass Int;
PageDialogClass3(DialogClass parent, MainClass &m):
DialogClass(parent, "Third Page"),
Main = m,
Message(this, m.test2, START, START, 80, 12, READONLY), //I want this to show the text entered on Page2
Int(this, "Int", SAME, NEXT, 100, DEFAULT, 0, m.myint, 0, 30, 0)
{
}
virtual void Setup() {
Console.WriteLine("Page3 Setup");
DialogClass::Setup();
}
virtual bool ActivateEvent() {
Console.WriteLine("Page3 ActivateEvent");
Message.SetText(Main.test2);
return DialogClass::ActivateEvent();
}
virtual bool CanClose() {
Console.WriteLine("Page3 CanClose");
return DialogClass::CanClose();
}
}
class MasterDialogClass: DialogClass {
PageDialogClass1 Page1;
PageDialogClass2 Page2;
PageDialogClass3 Page3;
MasterDialogClass(MainClass m):
DialogClass(null, ""),
Page1(this, m),
Page2(this, m),
Page3(this, m)
{}
virtual void Setup() {
Console.WriteLine("Master Setup");
DialogClass::Setup();
}
virtual bool ActivateEvent() {
Console.WriteLine("Master ActivateEvent");
return DialogClass::ActivateEvent();
}
virtual bool CanClose() {
Console.WriteLine("Master CanClose");
return DialogClass::CanClose();
}
}