Question on form.Destroy(0)

General help with the Ecere Cross Platform GUI toolkit: Window, common controls, events, etc.
Help with the 2D Graphics library: Surface, Display, Bitmap, Font and others.
Post Reply
samsam598
Posts: 212
Joined: Thu Apr 14, 2011 9:44 pm

Question on form.Destroy(0)

Post by samsam598 »

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
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Question on form.Destroy(0)

Post by jerome »

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
samsam598
Posts: 212
Joined: Thu Apr 14, 2011 9:44 pm

Re: Question on form.Destroy(0)

Post by samsam598 »

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
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Question on form.Destroy(0)

Post by jerome »

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
Post Reply