Ecere SDK/eC Forums
http://ecere.org/community/
Print view

Question on form.Destroy(0)
http://ecere.org/community/viewtopic.php?f=5&t=224
Page 1 of 1
Author:  samsam598 [ Wed Mar 14, 2012 2:20 am ]
Post subject:  Question on form.Destroy(0)

Greetings!

I am trying to implement an InputBox function seen in other OO language like VB and Delphi.

Code: Select all

 
int num=InputBox();
 

InputBox function will open a pop up window,one can enter an integer in the window and then press OK button.After the popup windows closes,the main procedure will receive and make use of this integer value.
To make it,It is not difficult actually to me.But I encountered a problem on when the popup windows should be destroyed .

My first trial is to place the Destroy(0) in the int InputBox() function body after popup.Modal().But this does not work properly.The popup windows never close.

Then I place the Destroy(0) in the OK button's left click event handler right after the int variable 'number' has been modified in the popup windows class.It works,but I am confused now.

Code: Select all

 
import "ecere"
 
 int InputBox()
 {
   int num;
    FormInteger form{};
    form.Modal();
    num=form.number;  
 
    //form.Destroy(0);//first trial
 
    return num;
 }
 
class FormInteger : Window
{
   caption = "整数:";
   background = activeBorder;
   borderStyle = fixed;
   size = { 368, 148 };
   anchor = { horz = -107, vert = -153 };
 
public:
   int number;
   property int number
   {
      set { number=value;}
      get {return number;}
   }
   Button btnOK 
   {      
      this, caption = "OK", altO, isDefault = true, size = { 74, 21 }, position = { 256, 80 };
 
      bool NotifyClicked(Button button, int x, int y, Modifiers mods)
      {
 
         number=atoi(txtNumber.contents);
         //Destroy(0); //second trial
 
         return true;
      }
   };
   Label label1 { this, caption = "请输入整数:", size = { 140, 13 }, position = { 16, 8 } };
   EditBox txtNumber { this, size = { 326, 19 }, position = { 16, 32 } };
}
 


1.First trial:in the InputBox() body,the popup window created,opened in modal,read the property number's value and save to variable num,then it is destoryed.I think this is the proper sequence but it turns out it is totally wrong.
2.Second trial:in the button click event body,after the property number was set ,window was destroyed immediately.Now in the InputBox() body,the popup window created,opened in modal,when OK button was pressed,the window destoryed immediately,so how can I read and save the property number's value?I have though this for several times and believe this does not make sence,but it does actually.

This is why I am confused.Hope I described the question clear.

Thanks for the help.

Regards,
Sam
Author:  jerome [ Wed Mar 14, 2012 10:49 am ]
Post subject:  Re: Question on form.Destroy(0)

Hi Sam,

Modal() does not return until the window has been destroyed (e.g. the dialog is closed).
So the Destroy(0) should be in NotifyClicked.

Now, in a future version of eC, I want all named instantiations to automatically get a reference count of 1, and be decremented when they go out of scope. But for the moment, local instantiations get a reference count of 0, and do not automatically get decremented when they go out of scope.

(Global and member instantiations do however start at 1, and get decremented on module or containing class destruction, which is why making your FormInteger form { } global would solve this issue).

What this means is that for now you need to manually incref and decref the form instance when using a local instance:

Code: Select all

int InputBox()
{
   int num;
   FormInteger form{};
   incref form; // Keep form alive until we've read the value of number
   form.Modal();
   num=form.number;  
 
   delete form; // Decrement reference count by 1 (will get freed when 0) 
   return num;
}
Another thing you might want to do for your InputBox is to use a DataBox instead of an EditBox, and make the label point to the DataBox (or EditBox) (e.g. so that clicking on the label activates the box -- more useful when you have more than 1 control):

Code: Select all

class FormInteger : Window
{
   caption = "整数:";
   background = activeBorder;
   borderStyle = fixed;
   size = { 368, 148 };
   anchor = { horz = -107, vert = -153 };
 
public:
   int number;
   property int number
   {
      set { number=value; txtNumber.Refresh(); }
      get {return number;}
   }
   Button btnOK 
   {      
      this, caption = "OK", altO, isDefault = true, size = { 74, 21 }, position = { 256, 80 };
      NotifyClicked = ButtonCloseDialog;
   };
   Label lblTxtNumber { this, labeledWindow = txtNumber, size = { 140, 13 }, position = { 16, 8 } };
   SavingDataBox txtNumber { this, caption = "请输入整数:", data = &number, type = class(int), size = { 326, 19 }, position = { 16, 32 } };
}
P.S.: Forgot to mention, for an int you could also return the number as the value you pass to Destroy(), and it will be the result of Modal() :)

Cheers,

Jerome
Author:  samsam598 [ Wed Mar 14, 2012 7:31 pm ]
Post subject:  Re: Question on form.Destroy(0)

Clear.Thank you so much for the detailed explanation.
What does ButtonCloseDialog do?It is just an user defined buttonClick event handling function?

Regards,
Sam
Author:  jerome [ Wed Mar 14, 2012 10:50 pm ]
Post subject:  Re: Question on form.Destroy(0)

Hi Sam,

ButtonCloseDialog is a button click handling method predefined in the Window class.

It destroys the master window with a destroy code of the control's id:

Code: Select all

   bool ButtonCloseDialog(Button button, int x, int y, Modifiers mods)
   {
      Destroy(button.id);
      return true;
   }
Regards,

Jerome
All times are UTC-05:00 Page 1 of 1