C ++ Builder - 程序结束错误和本地化错误

时间:2018-05-20 00:05:12

标签: error-handling localization c++builder

我对使用Embarcadero C ++ Builder完成的程序有疑问。

第一部分: 我想制作独立的.exe文件,并根据我已禁用“与动态RTL链接”并禁用“与运行时包链接”。但是,每次我结束我的程序,我都会收到错误“异常程序终止”。我已经开始调查,并找到了部分解决方案。当我启用与运行时包的链接时,不会出现该错误,但.exe文件将无法在未安装C ++ builder的PC上运行,因为缺少某些.bpl文件。所以,就目前而言,我有两种可能性:对所有PC都有“异常程序终止”错误,或者没有功能性.exe文件。除了那个错误,我的程序运行得很好。

第二部分: 我制作了3个单元的全功能程序,我想用资源DLL向导在英语上翻译它。我可以预览翻译的表单,但我无法构建它,因为它说错误但我看不到有关错误的更多细节。我真的不知道如何有没有错误的工作程序,本地化版本有错误。我得到了“全部清理”然后“全部构建”的建议,但由于该错误,我甚至无法清除所有内容。

我真的不知道该怎么做了,我现在正在努力解决这些问题一周,我真的希望有人可以帮助我。谢谢:))

1 个答案:

答案 0 :(得分:0)

  1. <强>本地化

    不确定您的本地化工具是否适合Borland / Embarcadero应用程序(可能仅适用于 MSVC ++ 应用程序可能存在问题)。

    我自己进行本地化(因为我需要自定义内容,如内部消息和表格翻译。所以我编写了一个~55 KByte解析器,将*.h,*.cpp,*.dfm所有窗口作为输入并创建*.ini文件和*.h将读取所选语言ini并将所有表单翻译成它(Caption,Hint,...)然后只为每种新语言复制ini并翻译字符串。这样我就可以在运行时切换语言无需任何 DLL 或重新启动,客户可以自行添加新语言,无需源代码或编程技能。

    无法共享代码,因为它使用了我的一些不可共享(公司)库,用于字符串,动态列表和快速ini文件访问(它们包含在55 KByte估计中)但我可以共享可执行文件(win32 standalone在 BDS2006 VCL BDS2006 代码格式编译中编译:

    使用慢速下载(无需注册即可免费使用)。我甚至在配方中添加了一个窗口进行测试。您只需运行exe,完成后使用输出中的文件。但是,输出的源文件使用快速ini文件访问(我无法共享),因此您需要对其进行编码(或替换为您的样式访问)。这是基于winapi的解决方法,我的 ini.h 可以解决这个问题:

    #ifndef _ini_h
    #define _ini_h
    class inifile
        {
    public:
        AnsiString section,filename;
    
        // inline
        inifile()   {close();}
        inifile(inifile& a) { *this=a; }
        ~inifile()  {close();}
        inifile* operator = (const inifile *a) { *this=*a; return this; }
        //inifile* operator = (const inifile &a) { ...copy... return this; }
    
        int open(AnsiString name) // open ini file
            {
            close();
            if (FileExists(name)) { filename=name; return 1; }
            return 0;
            }
        void close() // close ini file
            {
            filename="";
            section="";
            }
        int sec_getid(const AnsiString &sec, bool _add) // select section to work with ignoring the returned ID
            {
            section=sec;
            return 0;
            }
        AnsiString key_get(int section_id,const AnsiString &key,const AnsiString &def) // read key from section of ini with default value
            {
            if (filename=="") return def;
            char dest[1024]; AnsiString val;
            GetPrivateProfileString(section.c_str(),key.c_str(),def.c_str(),dest,1024,filename.c_str());
            val=dest; return val;
            }
        };
    #endif
    

    因此该应用有3个文件夹

    1. formulars
    2. 在此处填写表单的所有*.h,*.cpp;*.dfm个文件。解析*.h正在public: (skip user declarations)停止以防止与用户代码冲突。您还可以在组件行末尾添加注释:

      // LANGUAGE_SKIP_CAPT
      // LANGUAGE_SKIP_TEXT
      // LANGUAGE_SKIP_HINT
      

      或任何防止翻译的组合都会弄乱它。

      1. 消息
      2. 忽略这一点,*.cpp源内文消息_messages[]的源文件必须使用以下评论中的标记进行正确编码:

        AnsiString _messages[_msg_enum_end+1]=
            {
        //  LANGUAGE_MSG000_TEXT_BEG
            "Error: message id out of range !!!",
        
            "OpenGL FBO support is missing !!! ... switching to simplified graphics",
            "OpenGL VBO support is missing !!! ... switching to simplified graphics",
            "Sorry: ATI graphic card detected !!! ... switching to simplified graphics",
            "Sorry: ATI Radeon HD 5450 graphic card detected !!! ... disabling preview features",
        
            "Done.",
        //  LANGUAGE_MSG000_TEXT_END
            "",
            ""
            };
        
        1. 输出
        2. 这里的应用程序输出4个文件

          • init.h 可以忽略这只是窗口状态的初始/退出加载/删除
          • init的
          • init.ini ini文件可以忽略这一点 进入app ini。
          • language.h 这就是你想要的翻译例程
          • english.ini 使用当前窗口文本翻译ini文件

          此处生成的language.h示例:

          #include <math.h>
          #include "ini.h" // use the ini.h above
          
          void language_init(AnsiString name)
              {
              int sec;
              inifile ini;
              ini.open(name);
          
              sec=ini.sec_getid("Twin_EditorSetup",true);
              win_EditorSetup->ck_specchar->Caption=ini.key_get(sec,"C_ck_specchar","Special chars.");
              win_EditorSetup->ck_specchar->Hint   =ini.key_get(sec,"H_ck_specchar","View special characters on/off");
              win_EditorSetup->cb_colors->Hint   =ini.key_get(sec,"H_cb_colors","Select color for editing");
              win_EditorSetup->ed_tabs->Text   =ini.key_get(sec,"T_ed_tabs","1");
              win_EditorSetup->ed_tabs->Hint   =ini.key_get(sec,"H_ed_tabs","Tabulator size");
              win_EditorSetup->ck_smart->Caption=ini.key_get(sec,"C_ck_smart","Smart eol");
              win_EditorSetup->ck_smart->Hint   =ini.key_get(sec,"H_ck_smart","Delete empty space at end of edited line");
              win_EditorSetup->RadioGroup1->Caption=ini.key_get(sec,"C_RadioGroup1","");
              win_EditorSetup->RadioGroup1->Hint   =ini.key_get(sec,"H_RadioGroup1","");
              win_EditorSetup->rb_eol1310->Caption=ini.key_get(sec,"C_rb_eol1310","CR LF");
              win_EditorSetup->rb_eol1310->Hint   =ini.key_get(sec,"H_rb_eol1310","EOL CR LF 13 10");
              win_EditorSetup->rb_eol13->Caption=ini.key_get(sec,"C_rb_eol13","CR");
              win_EditorSetup->rb_eol13->Hint   =ini.key_get(sec,"H_rb_eol13","EOL CR 13");
              win_EditorSetup->rb_eol10->Caption=ini.key_get(sec,"C_rb_eol10","LF");
              win_EditorSetup->rb_eol10->Hint   =ini.key_get(sec,"H_rb_eol10","EOL LF 10");
              win_EditorSetup->txt_tabs->Caption=ini.key_get(sec,"C_txt_tabs","TAB:");
              win_EditorSetup->txt_tabs->Hint   =ini.key_get(sec,"H_txt_tabs","");
              win_EditorSetup->pan_color->Caption=ini.key_get(sec,"C_pan_color","");
              win_EditorSetup->pan_color->Hint   =ini.key_get(sec,"H_pan_color","Pick color");
          
              sec=ini.sec_getid("Global",true);
          
              ini.close();
              }
          

          所以在您的主应用表单中,cpp包含language.h 但在声明其指针后(在TForm1 *Form1;之后的行之后),否则您将获得访问冲突错误。现在使用选定的语言ini文件调用language_init任何语言更改或Apps init,如下所示:

          if (Form1->Visible) language_init(ExtractFilePath(Application->ExeName)+"english.ini");
          
          如果winapi用于ini.h !!!

          ,则需要指定完整路径
        3. <强>包

          没有 MCVE 很难说。您很可能使用非标准的第3方软件包,或者代码中有错误。我敢打赌你有内存泄漏,这往往会不时出现这样的错误(特别是在退出应用程序时)尝试在项目选项中使用 CodeGuard ,它会告诉你运行时错误并允许您更好地调试它们,但它不适用于大型项目。此外,如果您使用较旧的编译器或需要调试内存泄漏,请参阅以下内容:

        4. 他们可能会解决您的问题(即使是那些您还不知道的问题)

          P.S。

          如果你对这里感兴趣是这个工具的主要来源(但没有支持的*.h文件,它将无法工作,但你可以看看它是如何工作的,以防你想要自己编码:

          //--- Formular decoder storage class ver 2.40 -------------------------------
          
          #ifndef _frm_decode_h
          #define _frm_decode_h
          //---------------------------------------------------------------------------
          const int _frm_cmp_prop_none    =0x00000000;
          // language properties
          const int _frm_cmp_prop_capt    =0x00000001;
          const int _frm_cmp_prop_text    =0x00000002;
          const int _frm_cmp_prop_hint    =0x00000004;
          // ini properties
          const int _frm_cmp_prop_align   =0x00010000;
          const int _frm_cmp_prop_pos     =0x00020000;
          const int _frm_cmp_prop_check   =0x00040000;
          const int _frm_cmp_prop_down    =0x00080000;
          const int _frm_cmp_prop_page    =0x00100000;
          
          class _frm_component
              {
          public:
              AnsiString name;        // name in C++
              int prop;               // component class enum
              int action;             // if true do not save/load by language
              };
          _frm_component frm_component[]=
              {
              // standard
              "TMenuItem"         ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_check,0,
              "TLabel"            ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TEdit"             ,_frm_cmp_prop_text|_frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TMemo"             ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TButton"           ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TCheckBox"         ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_check,0,
              "TRadioButton"      ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_check,0,
              "TListBox"          ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TComboBox"         ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TScrollBar"        ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_pos  ,0,
              "TGroupBox"         ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TRadioGroup"       ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TPanel"            ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TAction"           ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              // additional
              "TBitBtn"           ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TSpeedButton"      ,_frm_cmp_prop_capt|_frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_down ,0,
              "TStringGrid"       ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TCategoryButtons"  ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              // win32
              "TProgressBar"      ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              // system
              "TPaintBox"         ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              // win3.1
              "TTabbedNotebook"   ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align|_frm_cmp_prop_page ,0,
              "TFileListBox"      ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TDirectoryListBox" ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "TDriveComboBox"    ,                   _frm_cmp_prop_hint|_frm_cmp_prop_align                    ,0,
              "",0,0
              };
          //---------------------------------------------------------------------------
          class frm_decode
              {
          public:
              AnsiString form;            // formular class name in C++
              struct _component:_frm_component
                  {
                  // language properties
                  AnsiString text,hint;
                  // init properties
                  AnsiString align;       // -only for internal init purposes
                  AnsiString checked,down,position,left,top,width,height;
          
                  int skip;               // znacky
          
                  void reset()
                      {
                      text="";
                      hint="";
                      align="alNone";
                      checked="False";
                      down="False";
                      position="1";
                      left="0";
                      top="0";
                      width="1";
                      height="1";
                      skip=0;
                      }
                  };
              struct _message { AnsiString id,txt; };
              List<_component> cmp;
              List<_message> msg;
          
              frm_decode(){ reset(); }
              void reset()     { form=""; cmp.reset(); msg.reset(); }
              void load_form(AnsiString file);                    // load formular (file.h, file.dfm)
              void load_msg(AnsiString file);                     // load messages (file.h, file.cpp)
              void save_lang_ini(inifile &ini);                   // save language to ini
              void save_init_ini(inifile &ini);                   // save initialisation to ini
              void save_lang_cpp(AnsiString &txt,bool end=true);  // save language loader (C++) to txt
              void save_init_cpp(AnsiString &txt,bool end=true);  // save init loader (C++) to txt
              void save_exit_cpp(AnsiString &txt,bool end=true);  // save exit saver (C++) to txt
              };
          //---------------------------------------------------------------------------
          void frm_decode::load_form(AnsiString file)
              {
              // nepodporuje "/* ... */"
              int hnd,adr,siz,i,j,l,e,_skip;
              AnsiString lin,s,s0,ss;
              _component a;
              BYTE *txt;
              reset();
          
              // load list of components from: file.h
              hnd=FileOpen(file+".h",fmOpenRead);
              if (hnd<0) return;
              siz=FileSeek(hnd,0,2);
                  FileSeek(hnd,0,0);
              txt=new BYTE[siz];
              if (txt==NULL) { FileClose(hnd); return; }
              FileRead(hnd,txt,siz);
              FileClose(hnd);
              for (adr=0;adr<siz;)
                  {
                  lin=txt_load_lin(txt,siz,adr,true);
                  l=lin.Length();
          
                  for (_skip=0;i<=l;) // osetri zacky este pred odrezanim pokecu
                      {
                      s=str_load_str(lin,i,true);
                      if (s=="LANGUAGE_SKIP_CAPT") _skip|=_frm_cmp_prop_capt;
                      if (s=="LANGUAGE_SKIP_TEXT") _skip|=_frm_cmp_prop_text;
                      if (s=="LANGUAGE_SKIP_HINT") _skip|=_frm_cmp_prop_hint;
                      }
          
                  if (str_is_mask(lin,"*//*")) { s=lin; lin=""; for (i=1;i<l;i++) if ((s[i]=='/')&&(s[i+1]=='/')) break; else lin+=char(s[i]); l=lin.Length(); }
                  s=""; s0=""; e=0;
                  for (i=1;i<=l;)
                      {
                      s0=s;
                      s=str_load_str(lin,i,true);
                      if (s=="private:")  // stop processing for non formular symbols
                          {
                          adr=siz; break;
                          }
          
                      if (!e) { e=1; continue; }
                      if (s0=="class")
                          {
                          form=s;
                          continue;
                          }
                      if (s!="")
                       for (j=0;;j++)
                          {
                          if (frm_component[j].name=="") break;
                          if (frm_component[j].name==s0)
                              {
                              a.reset();
                              a.name="";
                              if (s[1]!='*') s=" "+s;
                              for (int q=2;q<=s.Length();q++) a.name+=s[q];
                              a.prop=frm_component[j].prop;
                              a.action=0;
                              a.skip=_skip;
                              cmp.add(a);
                              break;
                              }
                          }
                      }
                  }
              delete txt;
          
              // load component properties from: file.dfm
              int cmpid=-1;
              hnd=FileOpen(file+".dfm",fmOpenRead);
              if (hnd<0) return;
              siz=FileSeek(hnd,0,2);
                  FileSeek(hnd,0,0);
              txt=new BYTE[siz];
              if (txt==NULL) { FileClose(hnd); return; }
              FileRead(hnd,txt,siz);
              FileClose(hnd);
              for (adr=0;adr<siz;)
                  {
                  lin=txt_load_lin(txt,siz,adr,true);
                  l=lin.Length();
          
                  for (i=1;i<=l;i++)  // if cutted '' line then continue
                   if (lin[i]>32)
                      {
                      if (lin[i]!='\'') i=-1;
                      break;
                      }
                  if (i<0) { s=""; s0=""; e=0; }  // else new line
                  for (i=1;i<=l;)
                      {
                      int q=1;
                      if (s!="")
                       if (s[1]=='\'')
                          {
                          if (s[s.Length()]!='\'')
                              {
                              s+=" "+str_load_str(lin,i,true);
                              if (s[s.Length()]!='\'') continue;
                              }
                          q=0;
                          }
                      if (q)
                          {
                          int qqq=0;  // handle cutted '' line
                          ss=str_load_str(lin,i,true);
                          if ((s0!="")&&((ss!="")&&(ss[1]=='\''))) { qqq=1; s+=ss; }
                          if ((s0!="")&&(ss=="+"))                 { qqq=1; }
                          if (!qqq) { s0=s; s=ss; }
          
                          if (s!="")
                           if (s[1]=='\'')
                            if (s[s.Length()]!='\'')
                            e=0;
                          }
          /*          // odstran ''
                      if (s!="")
                       if (s[1]=='\'')
                        if (s[s.Length()]=='\'')
                          { ss=""; for (q=2;q<s.Length();q++) ss+=s[q]; s=ss; }
          */
                      if (!e) { e=1; continue; }
                      if (s!="")
                      if (s0=="object")
                          {
                          cmpid=-1;
                          if (s[s.Length()]==':')
                              {
                              AnsiString t=s;
                              s=""; for (j=1;j<t.Length();j++) s+=char(t[j]);
                              }
                          for (j=0;j<cmp.num;j++)
                           if (cmp[j].name==s)
                              {
                              cmpid=j;
                              break;
                              }
                          continue;
                          }
                      if (cmpid<0) continue;
          
                      char aa;
                      bool tt;
                      int ii,cc,ll=s.Length();
                      if (ll>0)
                          {
                          ss="";
                          tt=false;
                          for (ii=1;ii<=ll;ii++)
                              {
                              aa=s[ii];
                              if (aa=='\'') { tt=!tt; continue; }
                              if (tt)     { ss+=aa; continue; }
                              if (aa!='#'){ ss+=aa; continue; }
                              cc=0;
                              for (ii++;ii<=ll;ii++)
                                  {
                                  aa=s[ii];
                                  if (aa=='\'') { ii--; break; }
                                  if (aa< '0') { ii--; break; }
                                  if (aa> '9') { ii--; break; }
                                  cc*=10; cc+=aa-'0';
                                  }
                              ss+=char(cc);
                              }
                          s=ss;
                          }
          
                      if (s0=="Action"  ) cmp[cmpid].action=1;
                      if (s0=="Caption" ) cmp[cmpid].text=s;
                      if (s0=="Text"    ) cmp[cmpid].text=s;
                      if (s0=="Hint"    ) cmp[cmpid].hint=s;
          
                      if (s0=="Align"   ) cmp[cmpid].align=s;
                      if (s0=="Checked" ) cmp[cmpid].checked=s;
                      if (s0=="Down"    ) cmp[cmpid].down=s;
                      if (s0=="Position") cmp[cmpid].position=s;
                      if (s0=="Left"    ) cmp[cmpid].left=s;
                      if (s0=="Top"     ) cmp[cmpid].top=s;
                      if (s0=="Width"   ) cmp[cmpid].width=s;
                      if (s0=="Height"  ) cmp[cmpid].height=s;
                      }
                  }
              delete txt;
          
          
              // load list of messages from: file.cpp
              load_msg(file+".cpp");
              }
          //---------------------------------------------------------------------------
          void frm_decode::load_msg(AnsiString file)
              {
              // nepodporuje "/* ... */"
              int hnd,adr,siz,i,l,e;
              AnsiString lin,s;
              BYTE *txt;
          
              hnd=FileOpen(file,fmOpenRead);
              if (hnd<0) return;
              siz=FileSeek(hnd,0,2);
                  FileSeek(hnd,0,0);
              txt=new BYTE[siz];
              if (txt==NULL) { FileClose(hnd); return; }
              FileRead(hnd,txt,siz);
              FileClose(hnd);
          
              e=msg.num;
              for (adr=0;adr<siz;)
                  {
                  lin=txt_load_lin(txt,siz,adr,true);
                  l=lin.Length();
                  for (i=1;i<=l;)
                      {
                      s=str_load_str(lin,i,true);
                      if (s=="_msg_enum_beg")
                       for (;adr<siz;)
                          {
                          lin=txt_load_lin(txt,siz,adr,true);
                          l=lin.Length();
                          for (i=1;i<=l;)
                              {
                              s=str_load_str(lin,i,true);
                              if (s=="_msg_enum_end") { adr=siz; i=l+1; break; }
                              if (str_is_mask(s,"_msg*"))
                                  {
                                  _message m;
                                  m.id=s;
                                  m.txt="";
                                  msg.add(m);
                                  }
                              }
                          }
                      }
                  }
              for (adr=0;adr<siz;)
                  {
                  lin=txt_load_lin(txt,siz,adr,true);
                  l=lin.Length();
                  for (i=1;i<=l;)
                      {
                      s=str_load_str(lin,i,true);
                      if (s=="_messages[_msg_enum_end+1]")
                       for (;adr<siz;)
                          {
                          if (e>=msg.num) break;
                          s="";
                          for (;adr<siz;adr++)
                           if (txt[adr]=='"')
                              {
                              adr++;
                              for (;adr<siz;adr++)
                               if (txt[adr]=='"')
                                  {
                                  adr++;
                                  msg[e].txt=s;
                                  e++;
                                  break;
                                  }
                               else s+=char(txt[adr]);
                              break;
                              }
                          }
                      }
                  }
          
              delete txt;
          
              }
          //---------------------------------------------------------------------------
          void frm_decode::save_lang_ini(inifile &ini)
              {
              int i,p,s,sec;
              AnsiString key,val;
              sec=ini.sec_getid(form,true);
              for (i=0;i<msg.num;i++) ini.key_set(sec,msg[i].id,msg[i].txt);
          
              for (i=0;i<cmp.num;i++)
                  {
                  if (cmp[i].action) continue;
                  key=cmp[i].name;
                  p=cmp[i].prop;
                  s=cmp[i].skip;
                  if ((int(p&_frm_cmp_prop_capt)!=0)&&(int(s&_frm_cmp_prop_capt)==0)) ini.key_set(sec,"C_"+key,cmp[i].text);
                  if ((int(p&_frm_cmp_prop_text)!=0)&&(int(s&_frm_cmp_prop_text)==0)) ini.key_set(sec,"T_"+key,cmp[i].text);
                  if ((int(p&_frm_cmp_prop_hint)!=0)&&(int(s&_frm_cmp_prop_hint)==0)) ini.key_set(sec,"H_"+key,cmp[i].hint);
                  }
              }
          //---------------------------------------------------------------------------
          void frm_decode::save_init_ini(inifile &ini)
              {
              int i,p,sec;
              AnsiString key,val;
              sec=ini.sec_getid(form,true);
              for (i=0;i<cmp.num;i++)
                  {
                  if (cmp[i].action) continue;
                  key=cmp[i].name;
                  p=cmp[i].prop;
          
                  if (cmp[i].align=="alLeft")     ini.key_set(sec,"XS_"+key,cmp[i].width);
                  if (cmp[i].align=="alRight")    ini.key_set(sec,"XS_"+key,cmp[i].width);
                  if (cmp[i].align=="alTop")      ini.key_set(sec,"YS_"+key,cmp[i].height);
                  if (cmp[i].align=="alBottom")   ini.key_set(sec,"YS_"+key,cmp[i].height);
                  if (cmp[i].align=="alClient")
                      {
                      }
                  if (cmp[i].align=="alNone")
                      {
          /*
                      ini.key_set(sec,"X0_"+key,cmp[i].left);
                      ini.key_set(sec,"Y0_"+key,cmp[i].top);
                      ini.key_set(sec,"XS_"+key,cmp[i].width);
                      ini.key_set(sec,"YS_"+key,cmp[i].height);
          */
                      }
                  if (int(p&_frm_cmp_prop_check   )!=0) ini.key_set(sec,"CHK_"+key,(cmp[i].checked=="True")?"1":"0");
                  if (int(p&_frm_cmp_prop_down    )!=0) ini.key_set(sec,"DWN_"+key,(cmp[i].down   =="True")?"1":"0");
                  if (int(p&_frm_cmp_prop_pos     )!=0) ini.key_set(sec,"POS_"+key, cmp[i].position                );
                  }
              }
          //---------------------------------------------------------------------------
          void frm_decode::save_lang_cpp(AnsiString &txt,bool end)
              {
              int i,p,s;
              AnsiString cpp,lin,key,frm,tabl,endl;
              tabl=char(9); endl=char(13); endl+=char(10);
              cpp="";
              if (txt=="")
                  {
                  lin="";
                  lin+="#include <math.h>"+endl;
                  lin+="#include \"ini.h\""+endl+endl;
                  lin+="void language_init(AnsiString name)"+endl;
                  lin+=tabl+"{"+endl;
                  lin+=tabl+"int sec;"+endl;
                  lin+=tabl+"inifile ini;"+endl;
                  lin+=tabl+"ini.open(name);"+endl;
                  cpp+=lin;
                  }
              frm=""; for (i=2;i<=form.Length();i++) frm+=form[i];
              cpp+=endl;
              cpp+=tabl+"sec=ini.sec_getid(\""+form+"\",true);"+endl;
              for (i=0;i<msg.num;i++)
                  {
                  lin=tabl+"_messages[";
                  if (i<100) lin+=" ";
                  if (i<10) lin+=" ";
                  lin+=i;
                  lin+="]=ini.key_get(sec,\""+msg[i].id+"\",\""+msg[i].txt+"\");"+endl;
                  cpp+=lin;
                  }
              for (i=0;i<cmp.num;i++)
                  {
                  if (cmp[i].action) continue;
                  key=cmp[i].name;
                  p=cmp[i].prop;
                  s=cmp[i].skip;
                  lin="";
                  if ((int(p&_frm_cmp_prop_capt)!=0)&&(int(s&_frm_cmp_prop_capt)==0)) lin+=tabl+frm+"->"+key+"->Caption=ini.key_get(sec,\"C_"+key+"\",\""+cmp[i].text+"\");"+endl;
                  if ((int(p&_frm_cmp_prop_text)!=0)&&(int(s&_frm_cmp_prop_text)==0)) lin+=tabl+frm+"->"+key+"->Text   =ini.key_get(sec,\"T_"+key+"\",\""+cmp[i].text+"\");"+endl;
                  if ((int(p&_frm_cmp_prop_hint)!=0)&&(int(s&_frm_cmp_prop_hint)==0)) lin+=tabl+frm+"->"+key+"->Hint   =ini.key_get(sec,\"H_"+key+"\",\""+cmp[i].hint+"\");"+endl;
                  cpp+=lin;
                  }
              if (end)
                  {
                  lin=endl;
                  lin+=tabl+"ini.close();"+endl;
                  lin+=tabl+"}"+endl;
                  cpp+=lin;
                  }
              txt+=cpp;
              }
          //---------------------------------------------------------------------------
          void frm_decode::save_init_cpp(AnsiString &txt,bool end)
              {
              int i,p;
              AnsiString cpp,lin,key,frm,tabl,endl,endlx;
              tabl=char(9); endl=char(13); endl+=char(10); endlx="\\"+endl;
              cpp="";
              if (txt=="")
                  {
                  lin="";
                  lin+="//---------------------------------------------------------------------------"+endl;
                  lin+="#include <math.h>"+endl;
                  lin+="#include \"ini.h\""+endl;
                  lin+="//---------------------------------------------------------------------------"+endl;
                  lin+="#define _def_program_init(name) for(;;)"+endlx;
                  lin+=tabl+"{"+endlx;
                  lin+=tabl+"int sec;"+endlx;
                  lin+=tabl+"inifile ini;"+endlx;
                  lin+=tabl+"ini.open(name);"+endlx;
          //      lin+=tabl+"if (!ini.open(name)) break;"+endlx;
                  cpp+=lin;
                  }
              frm=""; for (i=2;i<=form.Length();i++) frm+=form[i];
              cpp+=tabl+"sec=ini.sec_getid(\""+form+"\",true);"+endlx;
              for (i=0;i<cmp.num;i++)
                  {
                  if (cmp[i].action) continue;
                  key=cmp[i].name;
                  p=cmp[i].prop;
                  lin="";
          
                  if (cmp[i].align=="alLeft")   lin+=tabl+frm+"->"+key+"->Width =ini.key_geti(sec,\"XS_"+key+"\","+cmp[i].width +");"+endlx;
                  if (cmp[i].align=="alRight")  lin+=tabl+frm+"->"+key+"->Width =ini.key_geti(sec,\"XS_"+key+"\","+cmp[i].width +");"+endlx;
                  if (cmp[i].align=="alTop")    lin+=tabl+frm+"->"+key+"->Height=ini.key_geti(sec,\"YS_"+key+"\","+cmp[i].height+");"+endlx;
                  if (cmp[i].align=="alBottom") lin+=tabl+frm+"->"+key+"->Height=ini.key_geti(sec,\"YS_"+key+"\","+cmp[i].height+");"+endlx;
                  if (cmp[i].align=="alClient")
                      {
                      }
                  if (cmp[i].align=="alNone")
                      {
          /*
                      lin+=tabl+frm+"->"+key+"->Left  =ini.key_geti(sec,\"X0_"+key+"\","+cmp[i].left  +");"+endlx;
                      lin+=tabl+frm+"->"+key+"->Top   =ini.key_geti(sec,\"Y0_"+key+"\","+cmp[i].top   +");"+endlx;
                      lin+=tabl+frm+"->"+key+"->Width =ini.key_geti(sec,\"XS_"+key+"\","+cmp[i].width +");"+endlx;
                      lin+=tabl+frm+"->"+key+"->Height=ini.key_geti(sec,\"YS_"+key+"\","+cmp[i].height+");"+endlx;
          */
                      }
                  if (int(p&_frm_cmp_prop_check   )!=0) lin+=tabl+frm+"->"+key+"->Checked =ini.key_geti(sec,\"CHK_"+key+"\","+cmp[i].checked +");"+endlx;
                  if (int(p&_frm_cmp_prop_down    )!=0) lin+=tabl+frm+"->"+key+"->Down    =ini.key_geti(sec,\"DWN_"+key+"\","+cmp[i].down    +");"+endlx;
                  if (int(p&_frm_cmp_prop_pos     )!=0) lin+=tabl+frm+"->"+key+"->Position=ini.key_geti(sec,\"POS_"+key+"\","+cmp[i].position+");"+endlx;
                  cpp+=lin;
                  }
              if (end)
                  {
                  lin+=tabl+"ini.close();"+endlx;
                  lin+=tabl+"break;"+endlx;
                  lin+=tabl+"}"+endl;
                  cpp+=lin;
                  }
              txt+=cpp;
              }
          //---------------------------------------------------------------------------
          void frm_decode::save_exit_cpp(AnsiString &txt,bool end)
              {
              int i,p;
              AnsiString cpp,lin,key,frm,tabl,endl,endlx;
              tabl=char(9); endl=char(13); endl+=char(10); endlx="\\"+endl;
              cpp="";
              if (txt=="")
                  {
                  lin+="//---------------------------------------------------------------------------"+endl;
                  lin+="#define _def_program_exit(name) for(;;)"+endlx;
                  lin+=tabl+"{"+endlx;
                  lin+=tabl+"int sec;"+endlx;
                  lin+=tabl+"inifile ini;"+endlx;
                  lin+=tabl+"ini.open(name);"+endlx;
                  cpp+=lin;
                  }
              frm=""; for (i=2;i<=form.Length();i++) frm+=form[i];
              cpp+=tabl+"sec=ini.sec_getid(\""+form+"\",true);"+endlx;
              for (i=0;i<cmp.num;i++)
                  {
                  if (cmp[i].action) continue;
                  key=cmp[i].name;
                  p=cmp[i].prop;
                  lin="";
                  if (cmp[i].align=="alLeft")   lin+=tabl+"ini.key_set(sec,\"XS_"+key+"\","+frm+"->"+key+"->Width );"+endlx;
                  if (cmp[i].align=="alRight")  lin+=tabl+"ini.key_set(sec,\"XS_"+key+"\","+frm+"->"+key+"->Width );"+endlx;
                  if (cmp[i].align=="alTop")    lin+=tabl+"ini.key_set(sec,\"YS_"+key+"\","+frm+"->"+key+"->Height);"+endlx;
                  if (cmp[i].align=="alBottom") lin+=tabl+"ini.key_set(sec,\"YS_"+key+"\","+frm+"->"+key+"->Height);"+endlx;
                  if (cmp[i].align=="alClient")
                      {
                      }
                  if (cmp[i].align=="alNone")
                      {
          /*
                      lin+=tabl+"ini.key_set(sec,\"X0_"+key+"\","+frm+"->"+key+"->Left  );"+endlx;
                      lin+=tabl+"ini.key_set(sec,\"Y0_"+key+"\","+frm+"->"+key+"->Top   );"+endlx;
                      lin+=tabl+"ini.key_set(sec,\"XS_"+key+"\","+frm+"->"+key+"->Width );"+endlx;
                      lin+=tabl+"ini.key_set(sec,\"YS_"+key+"\","+frm+"->"+key+"->Height);"+endlx;
          */
                      }
                  if (int(p&_frm_cmp_prop_check   )!=0) lin+=tabl+"ini.key_set(sec,\"CHK_"+key+"\",int("+frm+"->"+key+"->Checked));"+endlx;
                  if (int(p&_frm_cmp_prop_down    )!=0) lin+=tabl+"ini.key_set(sec,\"DWN_"+key+"\",int("+frm+"->"+key+"->Down   ));"+endlx;
                  if (int(p&_frm_cmp_prop_pos     )!=0) lin+=tabl+"ini.key_set(sec,\"POS_"+key+"\",    "+frm+"->"+key+"->Position);"+endlx;
                  cpp+=lin;
                  }
              if (end)
                  {
                  lin+=tabl+"ini.save(name);"+endlx;
                  lin+=tabl+"ini.close();"+endlx;
                  lin+=tabl+"break;"+endlx;
                  lin+=tabl+"}"+endl;
                  lin+="//---------------------------------------------------------------------------"+endl;
                  cpp+=lin;
                  }
              txt+=cpp;
              }
          //---------------------------------------------------------------------------
          #endif
          //---------------------------------------------------------------------------