How to save and load the control states of a dialog with IniFileSave() and IniFileLoad()

 

The attached is a simplified EA to find the correct way in using IniFileSave() and IniFileLoad() to save and load the control states of a dialog to and from a file. 

After the EA is started. Firstly, I save the origial state of the Edit object by clicking the Save button. then, i made some change to the value of the Edit object. Thirdly, I clicked the Load button.But, Alas! the loaded value in the Edit object is not what I "saved" before. I only simply call  IniFileSave() to save the control states and iniFileLoad() to load the control states(as you can see from the attached file.), have I missed something ? This problem has vexed me for days. PLeeeeease heeeeeeeeelp. waiting for your reply and many thanks for your guidelines.

taozemin.

 


Documentation on MQL5: Standard Constants, Enumerations and Structures / Objects Constants / Object Types
Documentation on MQL5: Standard Constants, Enumerations and Structures / Objects Constants / Object Types
  • www.mql5.com
Standard Constants, Enumerations and Structures / Objects Constants / Object Types - Reference on algorithmic/automated trading language for MetaTrader 5
Files:
SaveLoadEA.ex5  185 kb
DlgDemo.mqh  7 kb
 

Hi, I just reviewed the UI related source code (for example, Dialog.mqh, WndContainer.mqh, Edit.mqh, etc.).

I thinke that you can not use "IniFileSave()" and "IniFileLoad()" to save/load the content of the edit box. These functions can only save/load the position and status of the dialog box (they are implemented in the Dialog.mqh, but the edit box control doesn't implement the save/load feature.)

So you need to write your own code the load/save the content in your application.

You may refer to the code below: 

void CAppDialog::IniFileSave(void)
  {
   string filename=IniFileName()+IniFileExt();
   int handle=FileOpen(filename,FILE_WRITE|FILE_BIN|FILE_ANSI);
//---
   if(handle!=INVALID_HANDLE)
     {
      Save(handle); 
      FileClose(handle); 
     }
  }

 

bool CDialog::Save(const int file_handle)
  {
//--- check
   if(file_handle==INVALID_HANDLE)
      return(false);
//--- save
   FileWriteStruct(file_handle,m_norm_rect);
   FileWriteInteger(file_handle,m_min_rect.left);
   FileWriteInteger(file_handle,m_min_rect.top);
   FileWriteInteger(file_handle,m_minimized);
//--- result
   return(CWndContainer::Save(file_handle));
  }

 

bool CWndContainer::Save(const int file_handle)
  {
   bool result=true;
//--- loop by elements of group
   int total=m_controls.Total();
   for(int i=0;i<total;i++)
     {
      CWnd *control=Control(i);
      //--- check of pointer
      if(control==NULL)
         continue;
      result&=control.Save(file_handle);
     }
//--- result
   return(result);

 

class CObject
  {
   ..............................

   //--- methods for working with files
   virtual bool      Save(const int file_handle)                         { return(true);   }
  ......................................
  };

 The CEdit class is inherited from CObject (indirectly) but the "Save" method is not overridden to provide more implementations. 

 
Jian Chen:

Hi, I just reviewed the UI related source code (for example, Dialog.mqh, WndContainer.mqh, Edit.mqh, etc.).

I thinke that you can not use "IniFileSave()" and "IniFileLoad()" to save/load the content of the edit box. These functions can only save/load the position and status of the dialog box (they are implemented in the Dialog.mqh, but the edit box control doesn't implement the save/load feature.)

So you need to write your own code the load/save the content in your application.

You may refer to the code below: 

 

 

 

 The CEdit class is inherited from CObject (indirectly) but the "Save" method is not overridden to provide more implementations. 


I've implemented the Save and Load method for CEdit class:


Add the Save & Load declarations in the public section first:

   //--- methods for working with files
   virtual bool      Save(const int file_handle);
   virtual bool      Load(const int file_handle);


with the functions:

bool CEdit::Save(const int file_handle)
  {
//--- check
   if(file_handle==INVALID_HANDLE)
      return(false);
//---
   FileWriteString(file_handle,Text(),100);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CEdit::Load(const int file_handle)
  {
//--- check
   if(file_handle==INVALID_HANDLE)
      return(false);
//---
   if(!FileIsEnding(file_handle))
   {
      string ReadString = FileReadString(file_handle,100);
      if( ReadString=="" ) Text(NULL); else Text(ReadString);
   }
//--- succeed
   return(true);
  }
 

Sorry for the necro, but it's killing me to know: is there some reason they didn't just include the implementation into CEdit?

It seems logical to have Save / Load functionality already included, especially because one would expect the end-user to switch timeframes and it's unusual to have the text information disappear every time they do, or, as a programmer, having to programmatically fill out the Edit field each time (even though you do that now with Save / Load, it has the benefit of not having to figure out what the last information was).

And, ideally, you wouldn't be editing the classes that another developer provides you if you want customization. Instead, you'd create your own class, inherit the class you want to customize, and then override methods. And while you could inherit CEdit and add the implementation yourself, I'm not sure this was a good reason to.

Am I missing something? Maybe there was a good reason for not including it in the base class and requiring the file to be manually edited or the class to be inherited and the methods implemented.

Reason: