// http://akelpad.sourceforge.net/forum/viewtopic.php?p=11473#11473
// Version: 2015-09-19
// Author: KDJ
//
// *** Regular expression tester for JavaScript ***
//
// Usage:
//   Call("Scripts::Main", 1, "RegExpTestJS.js")
//
// Shortcut keys in dialog box:
//   Enter - test
//   F1 - RegExp help
//   Shift+Alt+ Right, Left, Down, Up, End, Home, PgDn, PgUp - move dialog box,
//   Alt+ Num-(-), Num+(+) - change opaque/transparency level of dialog box.

var DT_DWORD    = 3;
var BM_GETCHECK = 240;
var BM_SETCHECK = 241;

var hMainWnd     = AkelPad.GetMainWnd();
var hEditWnd     = AkelPad.GetEditWnd();
var oSys         = AkelPad.SystemFunction();
var hGuiFont     = oSys.Call("gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
var hInstanceDLL = AkelPad.GetInstanceDll();
var pClassName   = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstanceDLL;

var nWndPosX;
var nWndPosY;
var nOpaque = 255;
var pREStr  = "/[a-z]/ig";
var pString = "";
var pWith   = "";
var bIgCase = 1;
var bGlobal = 0;
var bMultiL = 0;
var nNL     = 1;
var nAction = 1;
var oRE     = new RegExp();
var aRECol  = new Array();
var oSel    = {"Source1"  : 0,
               "Source1"  : 0,
               "RE1"      : 0,
               "RE2"      : 0,
               "String1"  : 0,
               "String2"  : 0,
               "With1"    : 0,
               "With2"    : 0,
               "Result1"  : 0,
               "Result2"  : 0,
               "GlobPro1" : 0,
               "GlobPro2" : 0};
var nBufSize = 65536;
var lpBuffer;
var hWndDlg;
var hWndEdHlp;
var hFocus;
var bIsTest;
var bIsReturn;

ReadIni();

if (AkelPad.GetSelStart() != AkelPad.GetSelEnd())
  pString = AkelPad.GetSelText(3 /*"\r\n"*/);

//Main window
var aWnd        = [];
var IDREGEXP    = 1000;
var IDSOURCE    = 1001;
var IDESCAPE    = 1002;
var IDUNESCAPE  = 1003;
var IDCOPYSOU   = 1004;
var IDEDSOURCE  = 1005;
var IDRE        = 1006;
var IDIGCASE    = 1007;
var IDGLOBAL    = 1008;
var IDMULTIL    = 1009;
var IDCOLLECT   = 1010
var IDCOPYRE    = 1011;
var IDEDRE      = 1012;
var IDSTRING    = 1013;
var IDNEWLINE   = 1014;
var IDNLWIN     = 1015;
var IDNLUNIX    = 1016;
var IDNLMAC     = 1017;
var IDCOPYSTR   = 1018;
var IDEDSTRING  = 1019;
var IDACTION    = 1020;
var IDMETEST    = 1021;
var IDMEEXEC    = 1022;
var IDMESEARCH  = 1023;
var IDMEMATCH   = 1024;
var IDMESPLIT   = 1025;
var IDMEREPLACE = 1026;
var IDEDWITH    = 1027;
var IDRESULT    = 1028;
var IDLASTIND   = 1029;
var IDRESETIND  = 1030;
var IDCOPYRES   = 1031;
var IDEDRESULT  = 1032;
var IDGLOBPRO   = 1033;
var IDEDGLOBPRO = 1034;
var IDTEST      = 1035;
var IDHELP      = 1036;
var IDOPAQMINUS = 1037;
var IDOPAQPLUS  = 1038;
var IDCLOSE     = 1039;

//Collection window
var aCol       = [];
var IDNAME     = 1000;
var IDLIST     = 1001;
var IDVALUE    = 1002;
var IDREVAL    = 1003;
var IDADD      = 1004;
var IDRENAME   = 1005;
var IDDELETE   = 1006;
var IDOK       = 1007;
var IDCOLCLOSE = 1008;

var WNDTYPE  = 0;
var WND      = 1;
var WNDEXSTY = 2;
var WNDSTY   = 3;
var WNDX     = 4;
var WNDY     = 5;
var WNDW     = 6;
var WNDH     = 7;
var WNDTXT   = 8;

//0x50000000 - WS_VISIBLE|WS_CHILD
//0x50000007 - WS_VISIBLE|WS_CHILD|BS_GROUPBOX
//0x50000009 - WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON
//0x50010000 - WS_VISIBLE|WS_CHILD|WS_TABSTOP
//0x50010001 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_DEFPUSHBUTTON
//0x50010003 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
//0x50010080 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL
//0x50210004 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|WS_VSCROLL|ES_MULTILINE
//0x50310004 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE
//0x50310804 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|WS_HSCROLL|WS_VSCROLL|ES_READONLY|ES_MULTILINE
//0x50A10003 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|LBS_STANDARD
//0x50002000 - WS_VISIBLE|WS_CHILD|SS_EDITCONTROL
//Windows              WNDTYPE,WND,WNDEXSTY,     WNDSTY,WNDX,WNDY,WNDW,WNDH, WNDTXT
aWnd[IDREGEXP   ] = ["BUTTON",  0,       0, 0x50000007,   7,  10, 491, 140, pTxtRegExp];
aWnd[IDSOURCE   ] = ["STATIC",  0,       0, 0x50000000,  15,  27, 150,  13, pTxtSource];
aWnd[IDESCAPE   ] = ["BUTTON",  0,       0, 0x50010000, 180,  23, 100,  20, pTxtEscape];
aWnd[IDUNESCAPE ] = ["BUTTON",  0,       0, 0x50010000, 285,  23, 100,  20, pTxtUnEscape];
aWnd[IDCOPYSOU  ] = ["BUTTON",  0,       0, 0x50010000, 390,  23, 100,  20, pTxtCopyPaste];
aWnd[IDEDSOURCE ] = ["EDIT",    0,   0x200, 0x50210004,  15,  45, 475,  35, ""];
aWnd[IDRE       ] = ["STATIC",  0,       0, 0x50000000,  15,  92,  30,  13, pTxtRE];
aWnd[IDIGCASE   ] = ["BUTTON",  0,       0, 0x50010003,  50,  92,  70,  16, pTxtIgCase];
aWnd[IDGLOBAL   ] = ["BUTTON",  0,       0, 0x50010003, 133,  92,  55,  16, pTxtGlobal];
aWnd[IDMULTIL   ] = ["BUTTON",  0,       0, 0x50010003, 190,  92,  55,  16, pTxtMultiL];
aWnd[IDCOLLECT  ] = ["BUTTON",  0,       0, 0x50010000, 285,  88, 100,  20, pTxtCollect];
aWnd[IDCOPYRE   ] = ["BUTTON",  0,       0, 0x50010000, 390,  88, 100,  20, pTxtCopyPaste];
aWnd[IDEDRE     ] = ["EDIT",    0,   0x200, 0x50210004,  15, 110, 475,  35, pREStr];
aWnd[IDSTRING   ] = ["BUTTON",  0,       0, 0x50000007,   7, 160, 491, 145, pTxtString];
aWnd[IDNEWLINE  ] = ["STATIC",  0,       0, 0x50000000,  50, 177,  70,  13, pTxtNewLine];
aWnd[IDNLWIN    ] = ["BUTTON",  0,       0, 0x50000009, 120, 177,  70,  16, pTxtNLWin];
aWnd[IDNLUNIX   ] = ["BUTTON",  0,       0, 0x50000009, 200, 177,  70,  16, pTxtNLUnix];
aWnd[IDNLMAC    ] = ["BUTTON",  0,       0, 0x50000009, 270, 177,  70,  16, pTxtNLMac];
aWnd[IDCOPYSTR  ] = ["BUTTON",  0,       0, 0x50010000, 390, 173, 100,  20, pTxtCopyPaste];
aWnd[IDEDSTRING ] = ["EDIT",    0,   0x200, 0x50310004,  15, 195, 475, 105, pString];
aWnd[IDACTION   ] = ["BUTTON",  0,       0, 0x50000007,   7, 315, 491,  65, pTxtAction];
aWnd[IDMETEST   ] = ["BUTTON",  0,       0, 0x50000009,  15, 335,  85,  16, pTxtMeTest];
aWnd[IDMEEXEC   ] = ["BUTTON",  0,       0, 0x50000009, 115, 335,  85,  16, pTxtMeExec];
aWnd[IDMESEARCH ] = ["BUTTON",  0,       0, 0x50000009, 215, 335,  85,  16, pTxtMeSearch];
aWnd[IDMEMATCH  ] = ["BUTTON",  0,       0, 0x50000009, 315, 335,  85,  16, pTxtMeMatch];
aWnd[IDMESPLIT  ] = ["BUTTON",  0,       0, 0x50000009, 415, 335,  75,  16, pTxtMeSplit];
aWnd[IDMEREPLACE] = ["BUTTON",  0,       0, 0x50000009,  15, 355, 120,  16, pTxtMeReplace];
aWnd[IDEDWITH   ] = ["EDIT",    0,   0x200, 0x50010080, 135, 355, 355,  20, pWith];
aWnd[IDRESULT   ] = ["BUTTON",  0,       0, 0x50000007,   7, 390, 491, 145, pTxtResult];
aWnd[IDLASTIND  ] = ["STATIC",  0,       0, 0x50000000,  50, 407, 130,  13, pTxtLastInd];
aWnd[IDRESETIND ] = ["BUTTON",  0,       0, 0x50010000, 180, 403, 100,  20, pTxtResetInd];
aWnd[IDCOPYRES  ] = ["BUTTON",  0,       0, 0x50010000, 390, 403, 100,  20, pTxtCopy];
aWnd[IDEDRESULT ] = ["EDIT",    0,   0x200, 0x50310804,  15, 425, 475, 105, ""];
aWnd[IDGLOBPRO  ] = ["BUTTON",  0,       0, 0x50000007,   7, 545, 381, 125, pTxtGlobPro];
aWnd[IDEDGLOBPRO] = ["EDIT",    0,   0x200, 0x50310804,  15, 560, 365, 105, ""];
aWnd[IDTEST     ] = ["BUTTON",  0,       0, 0x50010001, 395, 550, 100,  23, pTxtTest];
aWnd[IDHELP     ] = ["BUTTON",  0,       0, 0x50010000, 395, 575, 100,  23, pTxtHelp];
aWnd[IDOPAQMINUS] = ["BUTTON",  0,       0, 0x50010000, 395, 600, 100,  23, pTxtOpaqMinus];
aWnd[IDOPAQPLUS ] = ["BUTTON",  0,       0, 0x50010000, 395, 625, 100,  23, pTxtOpaqPlus];
aWnd[IDCLOSE    ] = ["BUTTON",  0,       0, 0x50010000, 395, 650, 100,  23, pTxtClose];

aCol[IDNAME     ] = ["BUTTON",  0,       0, 0x50000007,  10,  10, 260,  30, pTxtName];
aCol[IDLIST     ] = ["LISTBOX", 0,       0, 0x50A10003,  10,  30, 260, 270, ""];
aCol[IDVALUE    ] = ["BUTTON",  0,       0, 0x50000007, 280,  40, 225, 235, pTxtValue];
aCol[IDREVAL    ] = ["STATIC",  0,       0, 0x50002000, 285,  60, 215, 210, ""];
aCol[IDADD      ] = ["BUTTON",  0,       0, 0x50010000,  10, 290,  95,  23, pTxtAdd];
aCol[IDRENAME   ] = ["BUTTON",  0,       0, 0x50010000, 110, 290,  95,  23, pTxtRename];
aCol[IDDELETE   ] = ["BUTTON",  0,       0, 0x50010000, 210, 290,  95,  23, pTxtDelete];
aCol[IDOK       ] = ["BUTTON",  0,       0, 0x50010001, 310, 290,  95,  23, pTxtOK];
aCol[IDCOLCLOSE ] = ["BUTTON",  0,       0, 0x50010000, 410, 290,  95,  23, pTxtClose];

if (hEditWnd)
{
  if (lpBuffer = AkelPad.MemAlloc(nBufSize * _TSIZE))
  {
    if (AkelPad.WindowRegisterClass(pClassName))
    {
      //Create dialog
      hWndDlg = oSys.Call("user32::CreateWindowEx" + _TCHAR,
                          0,               //dwExStyle
                          pClassName,      //lpClassName
                          pTxtCaption,     //lpWindowName
                          0x90CA0000,      //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
                          0,               //x
                          0,               //y
                          510,             //nWidth
                          710,             //nHeight
                          hMainWnd,        //hWndParent
                          0,               //ID
                          hInstanceDLL,    //hInstance
                          DialogCallback); //Script function callback. To use it class must be registered by WindowRegisterClass.
      if (hWndDlg)
      {
        //Allow other scripts running
        AkelPad.ScriptNoMutex();

        //Message loop
        AkelPad.WindowGetMessage();
      }
      AkelPad.WindowUnregisterClass(pClassName);
    }
    else if (hWndDlg = oSys.Call("user32::FindWindowEx" + _TCHAR, 0, 0, pClassName, 0))
    {
      AkelPad.SendMessage(hWndDlg, 7 /*WM_SETFOCUS*/, 0, 0);
    }
    AkelPad.MemFree(lpBuffer);
  }
}

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  var i, nLowParam, nHiwParam;

  if (uMsg == 1) //WM_CREATE
  {
    //Create windows
    for (i = 1000; i < aWnd.length; ++i)
    {
      aWnd[i][WND] = oSys.Call("user32::CreateWindowEx" + _TCHAR,
                               aWnd[i][WNDEXSTY], //dwExStyle
                               aWnd[i][WNDTYPE],  //lpClassName
                               0,                 //lpWindowName
                               aWnd[i][WNDSTY],   //dwStyle
                               aWnd[i][WNDX],     //x
                               aWnd[i][WNDY],     //y
                               aWnd[i][WNDW],     //nWidth
                               aWnd[i][WNDH],     //nHeight
                               hWnd,              //hWndParent
                               i,                 //ID
                               hInstanceDLL,      //hInstance
                               0);                //lpParam
      //Set font and text
      SetWndFontAndText(aWnd[i][WND], hGuiFont, aWnd[i][WNDTXT]);
    }

    //Set limit edit text
    AkelPad.SendMessage(aWnd[IDEDSOURCE ][WND], 197 /*EM_SETLIMITTEXT*/, 256, 0);
    AkelPad.SendMessage(aWnd[IDEDRE     ][WND], 197 /*EM_SETLIMITTEXT*/, 256, 0);
    AkelPad.SendMessage(aWnd[IDEDSTRING ][WND], 197 /*EM_SETLIMITTEXT*/, nBufSize - 1, 0);
    AkelPad.SendMessage(aWnd[IDEDWITH   ][WND], 197 /*EM_SETLIMITTEXT*/, 256, 0);
    AkelPad.SendMessage(aWnd[IDEDRESULT ][WND], 197 /*EM_SETLIMITTEXT*/, nBufSize - 1, 0);
    AkelPad.SendMessage(aWnd[IDEDGLOBPRO][WND], 197 /*EM_SETLIMITTEXT*/, nBufSize - 1, 0);
    //Check
    CheckButtons();
    //Set window position
    if ((nWndPosX == undefined) || (nWndPosY == undefined))
      MoveWindow(hMainWnd, hWnd, "RT");
    else
      MoveWindow(hMainWnd, hWnd, [nWndPosX, nWndPosY]);
    //Set opaque
    if (nOpaque < 255)
      SetOpaqueLevel(hWnd, nOpaque);

    hFocus = aWnd[IDEDSOURCE][WND];

    SetLastIndex();
    SetSource();
  }

  else if ((uMsg == 6) /*WM_ACTIVATE*/ && (! wParam))
    hFocus = oSys.Call("user32::GetFocus");

  else if (uMsg == 7) //WM_SETFOCUS
    oSys.Call("user32::SetFocus", hFocus);

  else if ((uMsg == 256) /*WM_KEYDOWN*/ &&
           (! (oSys.Call("user32::GetAsyncKeyState", 0x11 /*VK_CONTROL*/) & 0x80000000)))
  {
    if (wParam == 27) //VK_ESCAPE
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 16 /*WM_CLOSE*/, 0, 0);
    else if (wParam == 13) //VK_RETURN
    {
      if (bIsTest)
        bIsTest = 0;
      else
      {
        hFocus = oSys.Call("user32::GetFocus");
        if ((hFocus != aWnd[IDESCAPE   ][WND]) && (hFocus != aWnd[IDUNESCAPE ][WND]) &&
            (hFocus != aWnd[IDCOPYSOU  ][WND]) && (hFocus != aWnd[IDCOLLECT  ][WND]) &&
            (hFocus != aWnd[IDCOPYRE   ][WND]) && (hFocus != aWnd[IDCOPYSTR  ][WND]) &&
            (hFocus != aWnd[IDRESETIND ][WND]) && (hFocus != aWnd[IDCOPYRES  ][WND]) &&
            (hFocus != aWnd[IDTEST     ][WND]) && (hFocus != aWnd[IDHELP     ][WND]) &&
            (hFocus != aWnd[IDOPAQMINUS][WND]) && (hFocus != aWnd[IDOPAQPLUS ][WND]) &&
            (hFocus != aWnd[IDCLOSE    ][WND]))
          oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDTEST, 0);
      }
    }
    else if (wParam == 112) //VK_F1
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDHELP, 0);
  }

  else if ((uMsg == 258 /*WM_CHAR*/) && (wParam == 9 /*VK_TAB*/))
    oSys.Call("user32::SetFocus",
                oSys.Call("user32::GetNextDlgTabItem", hWnd, oSys.Call("user32::GetFocus"),
                  oSys.Call("user32::GetAsyncKeyState", 0xA0 /*VK_LSHIFT*/) & 0x80000000));

  else if (uMsg == 260) //WM_SYSKEYDOWN
  {
    if (oSys.Call("user32::GetAsyncKeyState", 0xA0 /*VK_LSHIFT*/) & 0x80000000)
    {
      if (wParam == 0x27) //VK_RIGHT
        MoveWindow(hMainWnd, hWnd, "R");
      else if (wParam == 0x25) //VK_LEFT
        MoveWindow(hMainWnd, hWnd, "L");
      else if (wParam == 0x28) //VK_DOWN
        MoveWindow(hMainWnd, hWnd, "D");
      else if (wParam == 0x26) //VK_UP
        MoveWindow(hMainWnd, hWnd, "U");
      else if (wParam == 0x23) //VK_END
        MoveWindow(hMainWnd, hWnd, "E");
      else if (wParam == 0x24) //VK_HOME
        MoveWindow(hMainWnd, hWnd, "H");
      else if (wParam == 0x22) //VK_NEXT
        MoveWindow(hMainWnd, hWnd, "B");
      else if (wParam == 0x21) //VK_PRIOR
        MoveWindow(hMainWnd, hWnd, "T");
    }

    if ((wParam == 109) || (wParam == 189))  //Num- or -
      SetOpaqueLevel(hWnd, -2);
    else if ((wParam == 107) || (wParam == 187))  //Num+ or +
      SetOpaqueLevel(hWnd, -1);
  }

  else if (uMsg == 273) //WM_COMMAND
  {
    nLowParam = LoWord(wParam);
    nHiwParam = HiWord(wParam);

    if (nLowParam == IDEDSOURCE)
    {
      if (nHiwParam == 0x0100 /*EN_SETFOCUS*/)
        AkelPad.SendMessage(aWnd[IDEDSOURCE][WND], 0x00B1 /*EM_SETSEL*/, oSel.Source1, oSel.Source2);
      else if (nHiwParam == 0x0200 /*EN_KILLFOCUS*/)
      {
        oSel.Source1 = LoWord(AkelPad.SendMessage(aWnd[IDEDSOURCE][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
        oSel.Source2 = HiWord(AkelPad.SendMessage(aWnd[IDEDSOURCE][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
      }
      else if (nHiwParam == 0x0300 /*EN_CHANGE*/)
      {
        SetLastIndex(0);
        SetRE();
      }
    }
    else if (nLowParam == IDEDRE)
    {
      if (nHiwParam == 0x0100 /*EN_SETFOCUS*/)
        AkelPad.SendMessage(aWnd[IDEDRE][WND], 0x00B1 /*EM_SETSEL*/, oSel.RE1, oSel.RE2);
      else if (nHiwParam == 0x0200 /*EN_KILLFOCUS*/)
      {
        oSel.RE1 = LoWord(AkelPad.SendMessage(aWnd[IDEDRE][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
        oSel.RE2 = HiWord(AkelPad.SendMessage(aWnd[IDEDRE][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
        SetRE();
      }
      else if (nHiwParam == 0x0300 /*EN_CHANGE*/)
      {
        SetLastIndex(0);
        SetSource();
      }
    }
    else if (nLowParam == IDEDSTRING)
    {
      if (nHiwParam == 0x0100 /*EN_SETFOCUS*/)
        AkelPad.SendMessage(aWnd[IDEDSTRING][WND], 0x00B1 /*EM_SETSEL*/, oSel.String1, oSel.String2);
      else if (nHiwParam == 0x0200 /*EN_KILLFOCUS*/)
      {
        oSel.String1 = LoWord(AkelPad.SendMessage(aWnd[IDEDSTRING][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
        oSel.String2 = HiWord(AkelPad.SendMessage(aWnd[IDEDSTRING][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
      }
      else if (nHiwParam == 0x0300 /*EN_CHANGE*/)
        SetLastIndex(0);
    }
    else if (nLowParam == IDEDWITH)
    {
      if (nHiwParam == 0x0100 /*EN_SETFOCUS*/)
        AkelPad.SendMessage(aWnd[IDEDWITH][WND], 0x00B1 /*EM_SETSEL*/, oSel.With1, oSel.With2);
      else if (nHiwParam == 0x0200 /*EN_KILLFOCUS*/)
      {
        oSel.With1 = LoWord(AkelPad.SendMessage(aWnd[IDEDWITH][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
        oSel.With2 = HiWord(AkelPad.SendMessage(aWnd[IDEDWITH][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
      }
      else if (nHiwParam == 0x0300 /*EN_CHANGE*/)
        SetLastIndex(0);
    }
    else if (nLowParam == IDEDRESULT)
    {
      if (nHiwParam == 0x0100 /*EN_SETFOCUS*/)
        AkelPad.SendMessage(aWnd[IDEDRESULT][WND], 0x00B1 /*EM_SETSEL*/, oSel.Result1, oSel.Result2);
      else if (nHiwParam == 0x0200 /*EN_KILLFOCUS*/)
      {
        oSel.Result1 = LoWord(AkelPad.SendMessage(aWnd[IDEDRESULT][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
        oSel.Result2 = HiWord(AkelPad.SendMessage(aWnd[IDEDRESULT][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
      }
    }
    else if (nLowParam == IDEDGLOBPRO)
    {
      if (nHiwParam == 0x0100 /*EN_SETFOCUS*/)
        AkelPad.SendMessage(aWnd[IDEDGLOBPRO][WND], 0x00B1 /*EM_SETSEL*/, oSel.GlobPro1, oSel.GlobPro2);
      else if (nHiwParam == 0x0200 /*EN_KILLFOCUS*/)
      {
        oSel.GlobPro1 = LoWord(AkelPad.SendMessage(aWnd[IDEDGLOBPRO][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
        oSel.GlobPro2 = HiWord(AkelPad.SendMessage(aWnd[IDEDGLOBPRO][WND], 0x00B0 /*EM_GETSEL*/, 0, 0));
      }
    }
    else if ((nLowParam >= IDIGCASE) && (nLowParam <= IDMULTIL))
    {
      CheckButtons(nLowParam);
      SetLastIndex(0);
      SetRE();
    }
    else if (((nLowParam >= IDNLWIN) && (nLowParam <= IDNLMAC)) ||
            ((nLowParam >= IDMETEST) && (nLowParam <= IDMEREPLACE)))
    {
      CheckButtons(nLowParam);
      SetLastIndex(0);
    }
    else if ((nLowParam == IDESCAPE) || (nLowParam == IDUNESCAPE))
    {
      if (EscapeUnescape(nLowParam == IDESCAPE))
      {
        SetLastIndex(0);
        SetRE();
      }
    }
    else if ((nLowParam == IDCOPYSOU) || (nLowParam == IDCOPYRE) ||
             (nLowParam == IDCOPYSTR) || (nLowParam == IDCOPYRES))
    {
      if (CopyPaste(nLowParam))
      {
        SetLastIndex(0);
        if (nLowParam == IDCOPYSOU)
          SetRE();
        else if (nLowParam == IDCOPYRE)
          SetSource();
      }
    }
    else if (nLowParam == IDCOLLECT)
      Collection();
    else if (nLowParam == IDRESETIND)
      SetLastIndex(0);
    else if (nLowParam == IDTEST)
    {
      bIsTest = (oSys.Call("user32::GetFocus") == aWnd[IDTEST][WND]) ? 1 : 0;
      SetRE();
      TestRE();
    }
    else if (nLowParam == IDHELP)
      Help();
    else if (nLowParam == IDOPAQMINUS)
      SetOpaqueLevel(hWnd, -2);
    else if (nLowParam == IDOPAQPLUS)
      SetOpaqueLevel(hWnd, -1);
    else if (nLowParam == IDCLOSE)
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 16 /*WM_CLOSE*/, 0, 0);
  }

  else if (uMsg == 16) //WM_CLOSE
  {
    WriteIni();
    //Destroy dialog
    oSys.Call("user32::DestroyWindow", hWnd);
  }

  else if (uMsg == 2) //WM_DESTROY
  {
    //Exit message loop
    oSys.Call("user32::PostQuitMessage", 0);
  }

  else
    SetDefID(hWnd);

  return 0;
}

function SetWndFontAndText(hWnd, hFont, pText)
{
  AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);

  AkelPad.MemCopy(lpBuffer, pText.substr(0, nBufSize - 1), _TSTR);
  oSys.Call("user32::SetWindowText" + _TCHAR, hWnd, lpBuffer);
}

function MoveWindow(hWndParent, hWnd, Action)
{
  var rcWndParent;
  var rcWnd;
  var nX;
  var nY;

  if (! hWndParent)
    hWndParent=oSys.Call("user32::GetDesktopWindow");

  rcWndParent = GetWindowPos(hWndParent);
  rcWnd       = GetWindowPos(hWnd);

  nX = rcWnd.left;
  nY = rcWnd.top;

  if (Action == "R") //Move right
    nX = rcWnd.left + ((rcWnd.left < rcWndParent.right - 50) ? 20: 0);
  else if (Action == "L") //Move left
    nX = rcWnd.left - ((rcWnd.right > rcWndParent.left + 50) ? 20: 0);
  else if (Action == "D") //Move down
    nY = rcWnd.top + ((rcWnd.top < rcWndParent.bottom - 50) ? 20: 0);
  else if (Action == "U") //Move up
    nY = rcWnd.top - ((rcWnd.bottom > rcWndParent.top + 50) ? 20: 0);
  else if (Action == "E") //Move end (right)
    nX = rcWnd.left + (rcWndParent.right - rcWnd.right);
  else if (Action == "H") //Move home (left)
    nX = rcWnd.left + (rcWndParent.left - rcWnd.left);
  else if (Action == "B") //Move bottom
    nY = rcWnd.top + (rcWndParent.bottom - rcWnd.bottom);
  else if (Action == "T") //Move top
    nY = rcWnd.top + (rcWndParent.top - rcWnd.top);
  else if (Action == "C") //Center window
  {
    nX = rcWndParent.left + ((rcWndParent.right  - rcWndParent.left) / 2 - (rcWnd.right  - rcWnd.left) / 2);
    nY = rcWndParent.top  + ((rcWndParent.bottom - rcWndParent.top)  / 2 - (rcWnd.bottom - rcWnd.top)  / 2);
  }
  else if (Action == "LT") //Move left top
  {
    nX = rcWndParent.left;
    nY = rcWndParent.top;
  }
  else if (Action == "RT") //Move right top
  {
    nX = rcWnd.left + (rcWndParent.right - rcWnd.right);
    nY = rcWndParent.top;
  }
  else if (Action == "LB") //Move left bottom
  {
    nX = rcWndParent.left;
    nY = rcWnd.top + (rcWndParent.bottom - rcWnd.bottom);
  }
  else if (Action == "RB") //Move right bottom
  {
    nX = rcWnd.left + (rcWndParent.right - rcWnd.right);
    nY = rcWnd.top + (rcWndParent.bottom - rcWnd.bottom);
  }
  else
  {
    nX = Action[0];
    nY = Action[1];
  }

  oSys.Call("user32::SetWindowPos", hWnd, 0, nX, nY, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
}

function GetWindowPos(hWnd)
{
  var lpRect = AkelPad.MemAlloc(16) //sizeof(RECT);
  var rcRect = [];

  oSys.Call("user32::GetWindowRect", hWnd, lpRect);

  rcRect.left   = AkelPad.MemRead(_PtrAdd(lpRect,  0), DT_DWORD);
  rcRect.top    = AkelPad.MemRead(_PtrAdd(lpRect,  4), DT_DWORD);
  rcRect.right  = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD);
  rcRect.bottom = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD);
  AkelPad.MemFree(lpRect);

  return rcRect;
}

function LoWord(nParam)
{
  return (nParam & 0xffff);
}

function HiWord(nParam)
{
  return ((nParam >> 16) & 0xffff);
}

function SetOpaqueLevel(hWnd, nLevel)
{
  var lpAlpha;
  var nStyle;

  if (nLevel < 0)
  {
    lpAlpha = AkelPad.MemAlloc(1);
    if (oSys.Call("user32::GetLayeredWindowAttributes", hWnd, 0, lpAlpha, 0))
    {
      nOpaque = AkelPad.MemRead(lpAlpha, 5 /*DT_BYTE*/);
      nOpaque += (nLevel == -1) ? 20 : -20;
    }
    AkelPad.MemFree(lpAlpha);
  }

  if (nOpaque > 255)
    nOpaque = 255;
  else if (nOpaque < 55)
    nOpaque = 55;

  //WS_EX_LAYERED style
  nStyle = oSys.Call("User32::GetWindowLong" + _TCHAR, hWnd, -20 /*GWL_EXSTYLE*/);

  if (! (nStyle & 0x00080000 /*WS_EX_LAYERED*/))
  {
    nStyle |= 0x00080000 /*WS_EX_LAYERED*/;
    oSys.Call("User32::SetWindowLongW", hWnd, -20 /*GWL_EXSTYLE*/, nStyle);
  }

  oSys.Call("user32::SetLayeredWindowAttributes", hWnd, 0, nOpaque, 2 /*LWA_ALPHA*/);
}

function SetDefID(hWnd)
{
  var nID    = 1000;
  var hFocus = oSys.Call("user32::GetFocus");

  while ((nID < aWnd.length) && (hFocus != aWnd[nID][WND]))
    ++nID;

  if ((nID != IDESCAPE) && (nID != IDUNESCAPE)  && (nID != IDCOPYSOU)  && (nID != IDCOLLECT) &&
      (nID != IDCOPYRE) && (nID != IDCOPYSTR)   && (nID != IDCOPYRES)  && (nID != IDRESETIND) &&
      (nID != IDHELP)   && (nID != IDOPAQMINUS) && (nID != IDOPAQPLUS) && (nID != IDCLOSE))
    nID = IDTEST;

  oSys.Call("user32::DefDlgProc" + _TCHAR, hWnd, 1025 /*DM_SETDEFID*/, nID, 0);
}

function CheckButtons(nButton)
{
  var nID;

  if (nButton)
  {
    bIgCase = AkelPad.SendMessage(aWnd[IDIGCASE][WND], BM_GETCHECK, 0, 0);
    bGlobal = AkelPad.SendMessage(aWnd[IDGLOBAL][WND], BM_GETCHECK, 0, 0);
    bMultiL = AkelPad.SendMessage(aWnd[IDMULTIL][WND], BM_GETCHECK, 0, 0);

    for (nID = IDNLWIN; nID <= IDNLMAC; ++nID)
    {
      if (AkelPad.SendMessage(aWnd[nID][WND], BM_GETCHECK, 0, 0))
      {
        nNL = nID - IDNLWIN + 1;
        break;
      }
    }

    for (nID = IDMETEST; nID <= IDMEREPLACE; ++nID)
    {
      if (AkelPad.SendMessage(aWnd[nID][WND], BM_GETCHECK, 0, 0))
      {
        nAction = nID - IDMETEST + 1;
        break;
      }
    }
  }

  AkelPad.SendMessage(aWnd[IDIGCASE   ][WND], BM_SETCHECK, bIgCase       , 0);
  AkelPad.SendMessage(aWnd[IDGLOBAL   ][WND], BM_SETCHECK, bGlobal       , 0);
  AkelPad.SendMessage(aWnd[IDMULTIL   ][WND], BM_SETCHECK, bMultiL       , 0);
  AkelPad.SendMessage(aWnd[IDNLWIN    ][WND], BM_SETCHECK, (nNL == 1)    , 0);
  AkelPad.SendMessage(aWnd[IDNLUNIX   ][WND], BM_SETCHECK, (nNL == 2)    , 0);
  AkelPad.SendMessage(aWnd[IDNLMAC    ][WND], BM_SETCHECK, (nNL == 3)    , 0);
  AkelPad.SendMessage(aWnd[IDMETEST   ][WND], BM_SETCHECK, (nAction == 1), 0);
  AkelPad.SendMessage(aWnd[IDMEEXEC   ][WND], BM_SETCHECK, (nAction == 2), 0);
  AkelPad.SendMessage(aWnd[IDMESEARCH ][WND], BM_SETCHECK, (nAction == 3), 0);
  AkelPad.SendMessage(aWnd[IDMEMATCH  ][WND], BM_SETCHECK, (nAction == 4), 0);
  AkelPad.SendMessage(aWnd[IDMESPLIT  ][WND], BM_SETCHECK, (nAction == 5), 0);
  AkelPad.SendMessage(aWnd[IDMEREPLACE][WND], BM_SETCHECK, (nAction == 6), 0);

  oSys.Call("user32::EnableWindow", aWnd[IDEDWITH][WND], (nAction == 6));
  oSys.Call("user32::EnableWindow", aWnd[IDCOLLECT][WND], (typeof Collection == "function"));
}

function EscapeUnescape(bEscape)
{
  var bIsChange = 0;
  var pSource;

  oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDSOURCE][WND], lpBuffer, nBufSize);
  pSource = AkelPad.MemRead(lpBuffer, _TSTR);

  if (bEscape)
    pSource = pSource.replace(/[\\\/.^$+*?|()\[\]{}]/g, "\\$&");
  else
    pSource = pSource.replace(/\\([\\\/.^$+*?|()\[\]{}])/g, "$1");

  if (pSource != AkelPad.MemRead(lpBuffer, _TSTR))
  {
    SetWndFontAndText(aWnd[IDEDSOURCE][WND], hGuiFont, pSource);
    bIsChange = 1;
  }
  return bIsChange;
}

function CopyPaste(nID)
{
  var bIsChange = 0;
  var rcWnd;
  var hMenu;
  var nCmd;
  var nIDED;

  if (nID == IDCOPYSOU)
    nIDED = IDEDSOURCE;
  else if (nID == IDCOPYRE)
    nIDED = IDEDRE;
  else if (nID == IDCOPYSTR)
    nIDED = IDEDSTRING;
  else if (nID == IDCOPYRES)
    nIDED = IDEDRESULT;

  oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[nIDED][WND], lpBuffer, nBufSize);

  rcWnd = GetWindowPos(aWnd[nID][WND]);
  hMenu = oSys.Call("user32::CreatePopupMenu");

  oSys.Call("user32::AppendMenu" + _TCHAR, hMenu,
              AkelPad.MemRead(lpBuffer, _TSTR) ? 0x0 /*MF_STRING*/ : 0x1 /*MF_GRAYED*/, 1, pTxtCopyCB);
  oSys.Call("user32::AppendMenu" + _TCHAR, hMenu,
              AkelPad.MemRead(lpBuffer, _TSTR) ? 0x0 /*MF_STRING*/ : 0x1 /*MF_GRAYED*/, 2, pTxtCopyAP);

  if ((nID == IDCOPYSOU) || (nID == IDCOPYRE) || (nID == IDCOPYSTR))
  {
    oSys.Call("user32::AppendMenu" + _TCHAR, hMenu, 0x800 /*MF_SEPARATOR*/, 0, 0);
    oSys.Call("user32::AppendMenu" + _TCHAR, hMenu,
                AkelPad.GetClipboardText() ? 0x0 /*MF_STRING*/ : 0x1 /*MF_GRAYED*/, 3, pTxtPasteCB);
    oSys.Call("user32::AppendMenu" + _TCHAR, hMenu,
                AkelPad.GetSelText() ? 0x0 /*MF_STRING*/ : 0x1 /*MF_GRAYED*/, 4, pTxtPasteAP);
  }

  nCmd = oSys.Call("user32::TrackPopupMenu", hMenu, 0x188 /*TPM_RIGHTALIGN|TPM_NONOTIFY|TPM_RETURNCMD*/,
                    rcWnd.right, rcWnd.bottom, 0, hWndDlg, 0);
  oSys.Call("user32::DestroyMenu", hMenu);

  if (nCmd == 1)
    AkelPad.SetClipboardText(AkelPad.MemRead(lpBuffer, _TSTR));
  else if (nCmd == 2)
    AkelPad.ReplaceSel(AkelPad.MemRead(lpBuffer, _TSTR), -1);
  else if (nCmd == 3)
  {
    if (AkelPad.GetClipboardText() != AkelPad.MemRead(lpBuffer, _TSTR))
    {
      SetWndFontAndText(aWnd[nIDED][WND], hGuiFont, AkelPad.GetClipboardText());
      bIsChange = 1;
    }
  }
  else if (nCmd == 4)
  {
    if (AkelPad.GetSelText(3 /*\r\n*/) != AkelPad.MemRead(lpBuffer, _TSTR))
    {
      SetWndFontAndText(aWnd[nIDED][WND], hGuiFont, AkelPad.GetSelText(3 /*\r\n*/));
      bIsChange = 1;
    }
  }

  return bIsChange;
}

function SetLastIndex(nInd)
{
  if (nInd == undefined)
    nInd = oRE.lastIndex;
  else
    oRE.lastIndex = nInd;

  SetWndFontAndText(aWnd[IDLASTIND][WND], hGuiFont, pTxtLastInd + nInd);
}

function SetRE()
{
  var pModyf = "";
  var pSource;
  var oError;

  if (bIgCase) pModyf += "i";
  if (bGlobal) pModyf += "g";
  if (bMultiL) pModyf += "m";

  oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDSOURCE][WND], lpBuffer, nBufSize);
  pSource = AkelPad.MemRead(lpBuffer, _TSTR);

  try
  {
    pREStr = String(RegExp(pSource, pModyf));
    if (pREStr.length > AkelPad.SendMessage(aWnd[IDEDRE][WND], 213 /*EM_GETLIMITTEXT*/, 0, 0))
      pREStr = "";
  }
  catch (oError)
  {
    pREStr = "";
  }

  SetWndFontAndText(aWnd[IDEDRE][WND], hGuiFont, pREStr);
}

function SetSource()
{
  var pSource = "";
  var nPos;
  var pModyf;
  var oError;

  oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDRE][WND], lpBuffer, nBufSize);
  pREStr = AkelPad.MemRead(lpBuffer, _TSTR).replace(/(^[ \t]+)|([ \t]+$)/g, "");

  if ((pREStr.charAt(0) == "/") && ((nPos = pREStr.lastIndexOf("/")) > 0))
  {
    pModyf = pREStr.substring(nPos + 1);
    if (! (pModyf && /[^igm]/.test(pModyf)))
    {
      pSource = pREStr.substring(1, nPos);

      if (pSource.length > AkelPad.SendMessage(aWnd[IDEDSOURCE][WND], 213 /*EM_GETLIMITTEXT*/, 0, 0))
        pSource = "";
      else
      {
        bIgCase = (pModyf.indexOf("i") < 0) ? 0 : 1;
        bGlobal = (pModyf.indexOf("g") < 0) ? 0 : 1;
        bMultiL = (pModyf.indexOf("m") < 0) ? 0 : 1;
        CheckButtons();
      }
    }
  }

  SetWndFontAndText(aWnd[IDEDSOURCE][WND], hGuiFont, pSource);
}

function TestRE()
{
  var pResult = "";
  var pModyf  = "";
  var pNLWin  = "\r\n";
  var pSource;
  var aTestRes;
  var i;

  oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDRE][WND], lpBuffer, nBufSize);
  pREStr = AkelPad.MemRead(lpBuffer, _TSTR);
  if (! pREStr)
  {
    AkelPad.MessageBox(hWndDlg, pTxtNoRE, pTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    oSys.Call("user32::SetFocus", aWnd[IDEDRE][WND]);
    return;
  }

  oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDSTRING][WND], lpBuffer, nBufSize);
  pString = AkelPad.MemRead(lpBuffer, _TSTR);
  if (! pString)
  {
    AkelPad.MessageBox(hWndDlg, pTxtNoStr, pTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
    oSys.Call("user32::SetFocus", aWnd[IDEDSTRING][WND]);
    return;
  }

  if (nNL == 2)
    pString = pString.replace(/\r\n/g, "\n");
  else if (nNL == 3)
    pString = pString.replace(/\r\n/g, "\r");

  if (oRE.lastIndex == 0)
  {
    oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDSOURCE][WND], lpBuffer, nBufSize);
    pSource = AkelPad.MemRead(lpBuffer, _TSTR);
    if (bIgCase) pModyf += "i";
    if (bGlobal) pModyf += "g";
    if (bMultiL) pModyf += "m";
    oRE = new RegExp(pSource, pModyf);
  }

  if (nAction == 1) //.test
    pResult = oRE.test(pString).toString();

  else if (nAction == 2) //.exec
  {
    aTestRes = oRE.exec(pString);
    if (aTestRes)
    {
      for (i = 0; i < aTestRes.length; ++i)
        pResult += pTxtArray + "[" + i + "]=" + aTestRes[i] + ((i == aTestRes.length - 1) ? "" : pNLWin);
    }
    else
      pResult = String(aTestRes);
  }

  else if (nAction == 3) //.search
    pResult = pString.search(oRE).toString();

  else if (nAction == 4) //.match
  {
    aTestRes = pString.match(oRE);
    if (aTestRes)
    {
      for (i = 0; i < aTestRes.length; ++i)
        pResult += pTxtArray + "[" + i + "]=" + aTestRes[i] + ((i == aTestRes.length - 1) ? "" : pNLWin);
    }
    else
      pResult = String(aTestRes);
  }

  else if (nAction == 5) //.split
  {
    aTestRes = pString.split(oRE);
    if (aTestRes.length)
    {
      for (i = 0; i < aTestRes.length; ++i)
        pResult += pTxtArray + "[" + i + "]=" + aTestRes[i] + ((i == aTestRes.length - 1) ? "" : pNLWin);
    }
    else
      pResult = pTxtEmpArray;
  }

  else if (nAction == 6) //.replace
  {
    oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDWITH][WND], lpBuffer, nBufSize);
    pWith   = AkelPad.MemRead(lpBuffer, _TSTR);
    pResult = pString.replace(oRE, pWith);
  }

  SetWndFontAndText(aWnd[IDEDRESULT][WND], hGuiFont, pResult);
  SetLastIndex();

  pResult  = "RegExp.$1=" + RegExp.$1 + pNLWin;
  pResult += "RegExp.$2=" + RegExp.$2 + pNLWin;
  pResult += "RegExp.$3=" + RegExp.$3 + pNLWin;
  pResult += "RegExp.$4=" + RegExp.$4 + pNLWin;
  pResult += "RegExp.$5=" + RegExp.$5 + pNLWin;
  pResult += "RegExp.$6=" + RegExp.$6 + pNLWin;
  pResult += "RegExp.$7=" + RegExp.$7 + pNLWin;
  pResult += "RegExp.$8=" + RegExp.$8 + pNLWin;
  pResult += "RegExp.$9=" + RegExp.$9 + pNLWin;
  pResult += "RegExp.index=" + RegExp.index + pNLWin;
  pResult += "RegExp.lastIndex=" + RegExp.lastIndex + pNLWin;
  pResult += "RegExp.lastMatch=" + RegExp.lastMatch + pNLWin;
  pResult += "RegExp.lastParen=" + RegExp.lastParen + pNLWin;
  pResult += "RegExp.leftContext=" + RegExp.leftContext + pNLWin;
  pResult += "RegExp.rightContext=" + RegExp.rightContext;

  SetWndFontAndText(aWnd[IDEDGLOBPRO][WND], hGuiFont, pResult);

  oSys.Call("user32::SetFocus", aWnd[IDEDRESULT][WND]);
}

function Help()
{
  var rcWnd   = GetWindowPos(hWndDlg);
  var hWndHlp = oSys.Call("user32::CreateWindowEx" + _TCHAR,
                          0,              //dwExStyle
                          pClassName,     //lpClassName
                          pTxtREHelp,     //lpWindowName
                          0x90C80000,     //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU
                          rcWnd.left+15,  //x
                          rcWnd.top+40,   //y
                          425,            //nWidth
                          500,            //nHeight
                          hWndDlg,        //hWndParent
                          0,              //ID
                          hInstanceDLL,   //hInstance
                          DialogCallbackHelp); //lpParam

  if (hWndHlp)
  {
    oSys.Call("user32::EnableWindow", hMainWnd, 0);
    oSys.Call("user32::EnableWindow", hWndDlg, 0);
    AkelPad.WindowGetMessage();
  }
}

function DialogCallbackHelp(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 1) //WM_CREATE
  {
    hWndEdHlp = oSys.Call("user32::CreateWindowEx" + _TCHAR,
                          0x200,        //dwExStyle
                          "EDIT",       //lpClassName
                          0,            //lpWindowName
                          0x50200804,   //WS_VISIBLE|WS_CHILD|WS_VSCROLL|ES_READONLY|ES_MULTILINE
                          10,           //x
                          10,           //y
                          400,          //nWidth
                          450,          //nHeight
                          hWnd,         //hWndParent
                          0,            //ID
                          hInstanceDLL, //hInstance
                          0);           //lpParam
    SetWndFontAndText(hWndEdHlp, hGuiFont, pTxtHelpText);
  }

  else if (uMsg == 7) //WM_SETFOCUS
    oSys.Call("user32::SetFocus", hWndEdHlp);

  else if (uMsg == 256 /*WM_KEYDOWN*/)
  {
    if ((wParam == 27 /*VK_ESCAPE*/) || (wParam == 112 /*VK_F1*/))
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 16 /*WM_CLOSE*/, 0, 0);
  }

  else if (uMsg == 16) //WM_CLOSE
  {
    oSys.Call("user32::EnableWindow", hMainWnd, 1);
    oSys.Call("user32::EnableWindow", hWndDlg, 1);
    oSys.Call("user32::DestroyWindow", hWnd);
  }

  else if (uMsg == 2) //WM_DESTROY
    oSys.Call("user32::PostQuitMessage", 0);

  return 0;
}

function Collection()
{
  var rcWnd   = GetWindowPos(hWndDlg);
  var hWndCol = oSys.Call("user32::CreateWindowEx" + _TCHAR,
                          0,              //dwExStyle
                          pClassName,     //lpClassName
                          pTxtRECollect,  //lpWindowName
                          0x90C80000,     //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU
                          rcWnd.left-4,   //x
                          rcWnd.top+180,  //y
                          520,            //nWidth
                          350,            //nHeight
                          hWndDlg,        //hWndParent
                          0,              //ID
                          hInstanceDLL,   //hInstance
                          DialogCallbackCol); //lpParam

  if (hWndCol)
  {
    oSys.Call("user32::EnableWindow", hMainWnd, 0);
    oSys.Call("user32::EnableWindow", hWndDlg, 0);
    AkelPad.WindowGetMessage();
  }
}

function DialogCallbackCol(hWnd, uMsg, wParam, lParam)
{
  var i, nPos, nLowParam, nHiwParam;

  if (uMsg == 1) //WM_CREATE
  {
    for (i = 1000; i < aCol.length; ++i)
    {
      aCol[i][WND] = oSys.Call("user32::CreateWindowEx" + _TCHAR,
                               aCol[i][WNDEXSTY], //dwExStyle
                               aCol[i][WNDTYPE],  //lpClassName
                               0,                 //lpWindowName
                               aCol[i][WNDSTY],   //dwStyle
                               aCol[i][WNDX],     //x
                               aCol[i][WNDY],     //y
                               aCol[i][WNDW],     //nWidth
                               aCol[i][WNDH],     //nHeight
                               hWnd,              //hWndParent
                               i,                 //ID
                               hInstanceDLL,      //hInstance
                               0);                //lpParam
      SetWndFontAndText(aCol[i][WND], hGuiFont, aCol[i][WNDTXT]);
    }

    //Fill listbox
    for (i = 0; i < aRECol.length; ++i)
    {
      AkelPad.MemCopy(lpBuffer, aRECol[i][0], _TSTR);
      nPos = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0180 /*LB_ADDSTRING*/, 0, lpBuffer);
      if (nPos >= 0)
      {
        AkelPad.SendMessage(aCol[IDLIST][WND], 0x019A /*LB_SETITEMDATA*/, nPos, i);
        if (aRECol[i][1] == pREStr)
          AkelPad.SendMessage(aCol[IDLIST][WND], 0x0186 /*LB_SETCURSEL*/, nPos, 0);
      }
    }

    CheckButtonsCollection();
  }

  else if (uMsg == 7) //WM_SETFOCUS
  {
    oSys.Call("user32::SetFocus", aCol[IDLIST][WND]);
    SetSelRE();
  }

  else if (uMsg == 256 /*WM_KEYDOWN*/)
  {
    if (wParam == 27 /*VK_ESCAPE*/)
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 16 /*WM_CLOSE*/, 0, 0);
    else if (wParam == 13 /*VK_RETURN*/)
    {
      if (! bIsReturn)
        oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDOK, 0);
    }
    else if (wParam == 45 /*VK_INSERT*/)
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDADD, 0);
    else if (wParam == 46 /*VK_DELETE*/)
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDDELETE, 0);
    else if (wParam == 113 /*VK_F2*/)
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDRENAME, 0);
  }

  else if (uMsg == 257 /*WM_KEYUP*/)
    bIsReturn = 0;

  else if (uMsg == 258 /*WM_CHAR*/)
    FindRE(wParam);

  else if (uMsg == 273) //WM_COMMAND
  {
    nLowParam = LoWord(wParam);
    nHiwParam = HiWord(wParam);

    if (nLowParam == IDLIST)
    {
      if (nHiwParam == 1 /*LBN_SELCHANGE*/)
        SetSelRE();
      else if (nHiwParam == 2 /*LBN_DBLCLK*/)
        oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDOK, 0);
    }
    else if (nLowParam == IDADD)
    {
      bIsReturn = 1;
      AddRE(hWnd);
    }
    else if (nLowParam == IDRENAME)
    {
      bIsReturn = 1;
      RenameRE(hWnd);
    }
    else if (nLowParam == IDDELETE)
    {
      bIsReturn = 1;
      DeleteRE();
    }
    else if (nLowParam == IDOK)
    {
      nPos = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0188 /*LB_GETCURSEL*/, 0, 0);
      if (nPos >= 0)
      {
        i = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0199 /*LB_GETITEMDATA*/, nPos, 0);
        SetWndFontAndText(aWnd[IDEDRE][WND], hGuiFont, aRECol[i][1]);
        SetLastIndex(0);
        SetSource();
      }
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 16 /*WM_CLOSE*/, 0, 0);
    }
    else if (nLowParam == IDCOLCLOSE)
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 16 /*WM_CLOSE*/, 0, 0);
  }

  else if (uMsg == 16) //WM_CLOSE
  {
    for (i = aRECol.length - 1; i >= 0; --i)
    {
      if (! aRECol[i][0])
        aRECol.splice(i, 1);
    }
    oSys.Call("user32::EnableWindow", hMainWnd, 1);
    oSys.Call("user32::EnableWindow", hWndDlg, 1);
    oSys.Call("user32::DestroyWindow", hWnd);
  }

  else if (uMsg == 2) //WM_DESTROY
    oSys.Call("user32::PostQuitMessage", 0);

  else
    SetDefIDCollection(hWnd);

  return 0;
}

function SetDefIDCollection(hWnd)
{
  var nID    = 1000;
  var hFocus = oSys.Call("user32::GetFocus");

  while ((nID < aCol.length) && (hFocus != aCol[nID][WND]))
    ++nID;

  if (nID == IDLIST)
    nID = IDOK;

  oSys.Call("user32::DefDlgProc" + _TCHAR, hWnd, 1025 /*DM_SETDEFID*/, nID, 0);
}

function CheckButtonsCollection()
{
  var bEnable;

  oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDRE][WND], lpBuffer, nBufSize);
  if (AkelPad.MemRead(lpBuffer, _TSTR))
    bEnable = 1;
  else
    bEnable = 0;
  oSys.Call("user32::EnableWindow", aCol[IDADD][WND], bEnable);

  if (AkelPad.SendMessage(aCol[IDLIST][WND], 0x018B /*LB_GETCOUNT*/, 0, 0) > 0)
    bEnable = 1;
  else
  {
    bEnable = 0;
    oSys.Call("user32::SetFocus", aCol[IDLIST][WND]);
  }

  oSys.Call("user32::EnableWindow", aCol[IDRENAME][WND], bEnable);
  oSys.Call("user32::EnableWindow", aCol[IDDELETE][WND], bEnable);
  oSys.Call("user32::EnableWindow", aCol[IDOK    ][WND], bEnable);
}

function SetSelRE(nPos)
{
  var pVal = "";
  var i;

  if (nPos == undefined)
    nPos = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0188 /*LB_GETCURSEL*/, 0, 0);
  if (nPos < 0)
    nPos = 0;

  nPos = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0186 /*LB_SETCURSEL*/, nPos, 0);

  if (nPos >= 0)
  {
    i    = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0199 /*LB_GETITEMDATA*/, nPos, 0);
    pVal = aRECol[i][1];
  }

  SetWndFontAndText(aCol[IDREVAL][WND], hGuiFont, pVal);
}

function AddRE(hWnd)
{
  var bNameExist = 1;
  var pName = "";
  var nPos;
  var i;

  oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDRE][WND], lpBuffer, nBufSize);
  pREStr = AkelPad.MemRead(lpBuffer, _TSTR);

  if (pREStr)
  {
    for (i = 0; i < aRECol.length; ++i)
    {
      if (aRECol[i][1] == pREStr)
      {
        for (nPos = 0; nPos < AkelPad.SendMessage(aCol[IDLIST][WND], 0x018B /*LB_GETCOUNT*/, 0, 0); ++nPos)
        {
          if (AkelPad.SendMessage(aCol[IDLIST][WND], 0x0199 /*LB_GETITEMDATA*/, nPos, 0) == i)
            break;
        }
        SetSelRE(nPos);
        AkelPad.MessageBox(hWnd, pTxtREExist + aRECol[i][0], pTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
        return;
      }
    }

    nPos = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0188 /*LB_GETCURSEL*/, 0, 0);
    if (nPos >= 0)
    {
      i = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0199 /*LB_GETITEMDATA*/, nPos, 0);
      pName = aRECol[i][0];
    }

    while (bNameExist)
    {
      bNameExist = 0;
      pName = AkelPad.InputBox(hWnd, pTxtAddRE, pTxtName, pName);

      if (pName != undefined)
        pName = pName.replace(/ +$/, "");
  
      if (pName)
      {
        for (i = 0; i < aRECol.length; ++i)
        {
          if (aRECol[i][0] == pName)
          {
            for (nPos = 0; nPos < AkelPad.SendMessage(aCol[IDLIST][WND], 0x018B /*LB_GETCOUNT*/, 0, 0); ++nPos)
            {
              if (AkelPad.SendMessage(aCol[IDLIST][WND], 0x0199 /*LB_GETITEMDATA*/, nPos, 0) == i)
                break;
            }
            SetSelRE(nPos);
            AkelPad.MessageBox(hWnd, pTxtNameExist + pName, pTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
            bNameExist = 1;
            break;
          }
        }

        if (! bNameExist)
        {
          AkelPad.MemCopy(lpBuffer, pName, _TSTR);
          nPos = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0180 /*LB_ADDSTRING*/, 0, lpBuffer);
          if (nPos >= 0)
          {
            i = aRECol.push([pName, pREStr]) - 1;
            AkelPad.SendMessage(aCol[IDLIST][WND], 0x019A /*LB_SETITEMDATA*/, nPos, i);
            SetSelRE(nPos);
            CheckButtonsCollection();
          }
        }
      }
    }
  }
  else
    AkelPad.MessageBox(hWnd, pTxtNoRE, pTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
}

function RenameRE(hWnd)
{
  var nPos = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0188 /*LB_GETCURSEL*/, 0, 0);
  var bNameExist = 1;
  var nPos1;
  var i;
  var n;
  var pName;

  if (nPos >= 0)
  {
    n = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0199 /*LB_GETITEMDATA*/, nPos, 0);
    pName = aRECol[n][0];

    while (bNameExist)
    {
      bNameExist = 0;
      pName = AkelPad.InputBox(hWnd, pTxtRenRE, pTxtNewName, pName);

      if (pName != undefined)
        pName = pName.replace(/ +$/, "");
  
      if (pName)
      {
        for (i = 0; i < aRECol.length; ++i)
        {
          if ((aRECol[i][0] == pName) && (i != n))
          {
            for (nPos1 = 0; nPos1 < AkelPad.SendMessage(aCol[IDLIST][WND], 0x018B /*LB_GETCOUNT*/, 0, 0); ++nPos1)
            {
              if (AkelPad.SendMessage(aCol[IDLIST][WND], 0x0199 /*LB_GETITEMDATA*/, nPos1, 0) == i)
                break;
            }
            SetSelRE(nPos1);
            AkelPad.MessageBox(hWnd, pTxtNameExist + pName, pTxtCaption, 48 /*MB_ICONEXCLAMATION*/);
            SetSelRE(nPos);
            bNameExist = 1;
            break;
          }
        }

        if (! bNameExist)
        {
          aRECol[n][0] = pName;
          AkelPad.MemCopy(lpBuffer, pName, _TSTR);
          AkelPad.SendMessage(aCol[IDLIST][WND], 0x0182 /*LB_DELETESTRING*/, nPos, lpBuffer);
          nPos = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0180 /*LB_ADDSTRING*/, 0, lpBuffer);
          AkelPad.SendMessage(aCol[IDLIST][WND], 0x019A /*LB_SETITEMDATA*/, nPos, n);
          SetSelRE(nPos);
        }
      }
    }
  }
}

function DeleteRE()
{
  var nPos = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0188 /*LB_GETCURSEL*/, 0, 0);
  var i;

  if (nPos >= 0)
  {
    i = AkelPad.SendMessage(aCol[IDLIST][WND], 0x0199 /*LB_GETITEMDATA*/, nPos, 0);
    aRECol[i] = ["", ""];

    if (nPos == AkelPad.SendMessage(aCol[IDLIST][WND], 0x0182 /*LB_DELETESTRING*/, nPos, 0))
      --nPos;

    SetSelRE(nPos);
    CheckButtonsCollection();
  }
}

function FindRE(nChar)
{
  var pChar = String.fromCharCode(nChar).toUpperCase();
  var nPos;

  for (nPos = 0; nPos < AkelPad.SendMessage(aCol[IDLIST][WND], 0x018B /*LB_GETCOUNT*/, 0, 0); ++nPos)
  {
    AkelPad.SendMessage(aCol[IDLIST][WND], 0x0189 /*LB_GETTEXT*/, nPos, lpBuffer);
    pName = AkelPad.MemRead(lpBuffer, _TSTR);
    if (pChar == pName.charAt(0).toUpperCase())
    {
      AkelPad.SendMessage(aCol[IDLIST][WND], 0x0186 /*LB_SETCURSEL*/, nPos, 0);
      SetSelRE(nPos);
      break;
    }
  }
}

function ReadIni()
{
  var oFSO     = new ActiveXObject("Scripting.FileSystemObject");
  var pIniName = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini";
  var pLngName = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + "_" + AkelPad.GetLangId(0 /*LANGID_FULL*/).toString() + ".lng";
  var oError;

  if (oFSO.FileExists(pLngName))
  {
    try
    {
      eval(AkelPad.ReadFile(pLngName));
    }
    catch (oError)
    {
    }
  }
  else
  {
    pTxtCaption   = "JavaScript 正则表达式测试工具";
    pTxtRegExp    = "正则表达式 (RE)";
    pTxtSource    = "RE.source";
    pTxtEscape    = "转义(&E)";
    pTxtUnEscape  = "反转义(&U)";
    pTxtRE        = "RE";
    pTxtIgCase    = "忽略大小写(&I)";
    pTxtGlobal    = "全局(&G)";
    pTxtMultiL    = "多行(&M)";
    pTxtNewLine   = "换行符:";
    pTxtCollect   = "收集(&C)";
    pTxtNLWin     = "Win (\\r\\n)";
    pTxtNLUnix    = "Unix (\\n)";
    pTxtNLMac     = "Mac (\\r)";
    pTxtString    = "待测字串 (Str)";
    pTxtAction    = "行为";
    pTxtMeTest    = "RE.test(Str)";
    pTxtMeExec    = "RE.exec(Str)";
    pTxtMeSearch  = "Str.search(RE)";
    pTxtMeMatch   = "Str.match(RE)";
    pTxtMeSplit   = "Str.split(RE)";
    pTxtMeReplace = "Str.replace(RE,With):";
    pTxtResult    = "结果";
    pTxtLastInd   = "RE.lastIndex=";
    pTxtResetInd  = "重置 lastIndex(&R)";
    pTxtArray     = "数组";
    pTxtEmpArray  = "空数组";
    pTxtGlobPro   = "全局 RegExp 对象属性";
    pTxtTest      = "测试";
    pTxtHelp      = "帮助";
    pTxtOpaqMinus = "透明 +";
    pTxtOpaqPlus  = "透明 -";
    pTxtClose     = "关闭";
    pTxtCopyPaste = "复制/粘贴";
    pTxtCopy      = "复制";
    pTxtCopyCB    = "复制到剪贴板";
    pTxtCopyAP    = "复制到 AkelPad";
    pTxtPasteCB   = "从剪贴板粘贴";
    pTxtPasteAP   = "从 AkelPad 粘贴";
    pTxtNoRE      = "无正则表达式。"
    pTxtNoStr     = "无待测字串。";
    pTxtRECollect = "RegExp 收集";
    pTxtName      = "名称";
    pTxtValue     = "值";
    pTxtAdd       = "添加 (Ins)";
    pTxtRename    = "重命名 (F2)";
    pTxtDelete    = "删除 (Del)";
    pTxtOK        = "确定 (Enter)";
    pTxtAddRE     = "添加 RegExp";
    pTxtRenRE     = "重命名 RegExp";
    pTxtNewName   = "新名称";
    pTxtREExist   = "本 RegExp 已经存在于名下: ";
    pTxtNameExist = "此名称已存在: ";
    pTxtREHelp    = "RegExp 帮助";
    pTxtHelpText  = "	修饰符\r\n============\r\n修饰符用于执行不区分大小写和全局的搜索:\r\n------------\r\n修饰符	说明\r\n------------\r\ni	执行不区分大小写匹配\r\ng	执行全局匹配 (查找所有匹配，而不是在第一个匹配之后停止)\r\nm	执行多行匹配\r\n\r\n	括号\r\n============\r\n括号用于查找一定范围的字符:\r\n------------\r\n表达式		说明\r\n------------\r\n[abc]		查找括号内的任一字符\r\n[^abc]		查找非括号内的任一字符\r\n[0-9]		查找任一从 0 到 9 的数字\r\n[A-Z]		查找任一大写字母 A 到 大写字母 Z\r\n[a-z]		查找任一小写字母 a 到 小写字母 z\r\n[A-z]		查找任一大写字母 A 到 小写字母 z\r\n[adgk]		查找已给集合中的任一字符\r\n[^adgk]		查找除已给集合外的任一字符\r\n(red|blue|green)	查找任何指定的选择\r\n\r\n	元字符\r\n============\r\n元字符是一种指定含义的字符:\r\n------------\r\n元字符	说明\r\n------------\r\n.	查找任一字符，换行符、行终止符除外\r\n\\w	查找单词字符\r\n\\W	查找非单词字符\r\n\\d	查找数字\r\n\\D	查找非数字字符\r\n\\s	查找空白字符\r\n\\S	查找非空白字符\r\n\\b	查找匹配在单词的开始/结束\r\n\\B	查找匹配不在单词的开始/结束\r\n\\0	查找 NUL 字符\r\n\\n	查找换行符\r\n\\f	查找换页符\r\n\\r	查找回车符\r\n\\t	查找制表符\r\n\\v	查找垂直制表符\r\n\\xxx	查找由一个八进制数字 xxx 指定的字符\r\n\\xdd	查找由一个16进制数字 dd 指定的字符\r\n\\uxxxx	查找由一个16进制数字 xxxx 指定的 Unicode 字符\r\n\r\n	数量符\r\n============\r\n数量符	说明\r\n------------\r\nn+	匹配大于等于一个 n\r\nn*	匹配大于等于零个 n\r\nn?	匹配小于等于一个 n\r\nn{X}	匹配 X 个 n\r\nn{X,Y}	匹配 在 X 和 Y 之间个 n\r\nn{X,}	匹配大于等于 X 个 n\r\nn$	匹配任何以 n 结束的字串\r\n^n	匹配任何以 n 开始的字串\r\n?=n	在任何匹配 n 的字符串开始处匹配查找字符串。\r\n?!n	在任何不匹配 n 的字符串开始处匹配查找字符串。\r\n\r\n	RegExp 对象属性\r\n============\r\n属性		说明\r\n------------\r\nglobal		如果修饰符 \"g\" 使用时指定\r\nignoreCase	如果修饰符 \"i\" 使用时指定\r\nlastIndex	该索引便于开始下一个匹配\r\nmultiline	如果修饰符 \"m\" 使用时指定\r\nsource		RegExp 模式的文字\r\n\r\n	RegExp 对象方法\r\n============\r\n方法		说明\r\n------------\r\ncompile()	编译正则表达式\r\nexec()		测试在字串中的匹配。返回第一个匹配\r\ntest()		测试在字串中的匹配。返回 true 或 false\r\n\r\n				_____________________________\r\n				来自: http://www.w3schools.com";
  }

  if (oFSO.FileExists(pIniName))
  {
    try
    {
      eval(AkelPad.ReadFile(pIniName));
    }
    catch (oError)
    {
    }
  }
}

function WriteIni()
{
  var oFSO = new ActiveXObject("Scripting.FileSystemObject");
  var rcWnd;
  var oFile;
  var pTxtIni;
  var i;

  rcWnd = GetWindowPos(hWndDlg);

  oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDRE][WND], lpBuffer, nBufSize);
  pREStr = AkelPad.MemRead(lpBuffer, _TSTR).replace(/[\\"]/g, "\\$&");
  oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDSTRING][WND], lpBuffer, nBufSize);
  pString = AkelPad.MemRead(lpBuffer, _TSTR).replace(/[\\"]/g, "\\$&").replace(/\r/g, "\\r").replace(/\n/g, "\\n");
  oSys.Call("user32::GetWindowText" + _TCHAR, aWnd[IDEDWITH][WND], lpBuffer, nBufSize);
  pWith = AkelPad.MemRead(lpBuffer, _TSTR).replace(/[\\"]/g, "\\$&");

  pTxtIni = 'nWndPosX=' + rcWnd.left + ';\r\n'  +
            'nWndPosY=' + rcWnd.top  + ';\r\n'  +
            'nOpaque='  + nOpaque    + ';\r\n'  +
            'nNL='      + nNL        + ';\r\n'  +
            'nAction='  + nAction    + ';\r\n'  +
            'pREStr="'  + pREStr     + '";\r\n' +
            'pString="' + pString    + '";\r\n' +
            'pWith="'   + pWith      + '";\r\n';

  pTxtIni += 'aRECol=[\r\n';
  for (i = 0; i < aRECol.length; ++i)
  {
    pTxtIni += '["' + 
                aRECol[i][0].replace(/[\\"]/g, "\\$&") + '","' + 
                aRECol[i][1].replace(/[\\"]/g, "\\$&") + '"]' +
                ((i < aRECol.length - 1) ? ',' : '') + '\r\n';
  }
  pTxtIni += '];';

  oFile = oFSO.OpenTextFile(WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini", 2, true, -1);
  oFile.Write(pTxtIni);
  oFile.Close();
}
