// http://akelpad.sourceforge.net/forum/viewtopic.php?p=9672#9672
// Version: 2015-08-29
// Author: KDJ
//
// *** Select range of text ***
//
// Usage:
//   Call("Scripts::Main", 1, "SelectRangeText.js")
//
// Shortcut keys in dialog box:
//   Enter - Apply
//   Esc   - Close
//   Alt+End, Home, PgDn, PgUp - set caret position
//   Shift+Alt+Right(Left,Down,Up,End,Home,PgDn,PgUp) - move dialog box
//   Shift+Alt+Del(Ins) - center dialog box
//
// Note:
//   The script should be saved in Unicode format

var oSys   = AkelPad.SystemFunction();
var sClass = "AkelPad::Scripts::" + WScript.ScriptName + "::" + AkelPad.GetInstanceDll();
var hDlg   = oSys.Call("User32::FindWindowExW", 0, 0, sClass, 0);

if (hDlg)
{
  if (! oSys.Call("User32::IsWindowVisible", hDlg))
    oSys.Call("User32::ShowWindow", hDlg, 8 /*SW_SHOWNA*/);
  if (oSys.Call("User32::IsIconic", hDlg))
    oSys.Call("User32::ShowWindow", hDlg, 9 /*SW_RESTORE*/);

  oSys.Call("User32::SetForegroundWindow", hDlg);
  WScript.Quit();
}

var AEGI_FIRSTSELCHAR     = 3;
var AEM_GETSEL            = 3125;
var AEM_SETSEL            = 3126;
var AEM_GETCOLUMNSEL      = 3127;
var AEM_GETINDEX          = 3130;
var AEM_INDEXUPDATE       = 3132;
var AEM_INDEXCOMPARE      = 3133;
var AEM_INDEXTORICHOFFSET = 3136;
var AEM_RICHOFFSETTOINDEX = 3137;

var hMainWnd  = AkelPad.GetMainWnd();
var bOffset   = 0;
var lpFirstC  = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
var lpCaret   = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
var lpSelect  = AkelPad.MemAlloc(_X64 ? 56 : 32 /*sizeof(AESELECTION)*/);
var lpBegSel  = lpSelect;
var lpEndSel  = _PtrAdd(lpSelect, _X64 ? 24 : 12);
var lpSelFlag = _PtrAdd(lpSelect, _X64 ? 48 : 24);
var lpBegL    = lpBegSel;
var lpBegC    = _PtrAdd(lpBegSel, _X64 ? 16 : 8);
var lpEndL    = lpEndSel;
var lpEndC    = _PtrAdd(lpEndSel, _X64 ? 16 : 8);
var lpCarL    = lpCaret;
var lpCarC    = _PtrAdd(lpCaret, _X64 ? 16 : 8);
var nBegOf;
var nEndOf;
var nCarOf;
var hEditWnd;
var bColSel;
var nDlgX;
var nDlgY;

ReadIni();
GetLangStrings();

var IDCOORDIN = 1000;
var IDTXTBEG  = 1001;
var IDTXTEND  = 1002;
var IDTXTCAR  = 1003;
var IDTXTLIN  = 1004;
var IDTXTCOL  = 1005;
var IDBEGL    = 1006;
var IDBEGC    = 1007;
var IDENDL    = 1008;
var IDENDC    = 1009;
var IDCARL    = 1010;
var IDCARC    = 1011;
var IDTXTOF   = 1012;
var IDBEGOF   = 1013;
var IDENDOF   = 1014;
var IDCAROF   = 1015;
var IDOFFSET  = 1016;
var IDCOLSEL  = 1017;
var IDCARPOS  = 1018;
var IDCARPOSB = 1019;
var IDCARPOSE = 1020;
var IDCARPOS0 = 1021;
var IDCARPOS1 = 1022;
var IDCARPOS2 = 1023;
var IDCARPOS3 = 1024;
var IDAPPLY   = 1025;
var IDCLOSE   = 1026;

AkelPad.WindowRegisterClass(sClass);

//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
//0x50012080 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL|ES_NUMBER
//0x90CA0040 = WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|DS_SETFONT
AkelPad.CreateDialog(0, sClass, sTxtCaption, 0x90CA0040, nDlgX, nDlgY, 355, 156, hMainWnd, DialogCallback, 0x2 /*CDF_PIXELS*/, 0, 0, "MS Shell Dlg", 1, 8, "|",
  //ExSt, Class,      Title,                       Style,        X,   Y,   W,   H, ID,      lParam,
  0x0000, "BUTTON",   sTxtCoordin,                 0x50000007,  10,  10, 185, 135, IDCOORDIN,    0, "|",
  0x0000, "STATIC",   sTxtBegin,                   0x50000000,  20,  48,  50,  13, IDTXTBEG,     0, "|",
  0x0000, "STATIC",   sTxtEnd,                     0x50000000,  20,  73,  50,  13, IDTXTEND,     0, "|",
  0x0000, "STATIC",   sTxtCaret,                   0x50000000,  20,  98,  50,  13, IDTXTCAR,     0, "|",
  0x0000, "STATIC",   sTxtLine,                    0x50000000,  70,  30,  50,  13, IDTXTLIN,     0, "|",
  0x0000, "STATIC",   sTxtColumn,                  0x50000000, 130,  30,  50,  13, IDTXTCOL,     0, "|",
  0x0200, "EDIT",     "",                          0x50012080,  70,  45,  55,  20, IDBEGL,       0, "|",
  0x0200, "EDIT",     "",                          0x50012080, 130,  45,  55,  20, IDBEGC,       0, "|",
  0x0200, "EDIT",     "",                          0x50012080,  70,  70,  55,  20, IDENDL,       0, "|",
  0x0200, "EDIT",     "",                          0x50012080, 130,  70,  55,  20, IDENDC,       0, "|",
  0x0200, "STATIC",   "",                          0x50000000,  70,  95,  55,  20, IDCARL,       0, "|",
  0x0200, "STATIC",   "",                          0x50000000, 130,  95,  55,  20, IDCARC,       0, "|",
  0x0000, "STATIC",   sTxtOffset.replace("&", ""), 0x50000000,  70,  30,  50,  13, IDTXTOF,      0, "|",
  0x0200, "EDIT",     "",                          0x50012080,  70,  45, 115,  20, IDBEGOF,      0, "|",
  0x0200, "EDIT",     "",                          0x50012080,  70,  70, 115,  20, IDENDOF,      0, "|",
  0x0200, "STATIC",   "",                          0x50000000,  70,  95, 115,  20, IDCAROF,      0, "|",
  0x0000, "BUTTON",   sTxtOffset,                  0x50010003,  70, 122, 120,  16, IDOFFSET,     0, "|",
  0x0000, "BUTTON",   sTxtColSel,                  0x50010003, 225,  15, 120,  16, IDCOLSEL,     0, "|",
  0x0000, "BUTTON",   sTxtCarPos,                  0x50000007, 205,  45, 140,  65, IDCARPOS,     0, "|",
  0x0000, "BUTTON",   sTxtBegin,                   0x50000009, 215,  65,  60,  16, IDCARPOSB,    0, "|",
  0x0000, "BUTTON",   sTxtEnd,                     0x50000009, 280,  85,  60,  16, IDCARPOSE,    0, "|",
  0x0000, "BUTTON",   sTxtCarPos0,                 0x50000009, 215,  65,  60,  16, IDCARPOS0,    0, "|",
  0x0000, "BUTTON",   sTxtCarPos1,                 0x50000009, 280,  65,  60,  16, IDCARPOS1,    0, "|",
  0x0000, "BUTTON",   sTxtCarPos2,                 0x50000009, 280,  85,  60,  16, IDCARPOS2,    0, "|",
  0x0000, "BUTTON",   sTxtCarPos3,                 0x50000009, 215,  85,  60,  16, IDCARPOS3,    0, "|",
  0x0000, "BUTTON",   sTxtApply,                   0x50010001, 205, 123,  67,  23, IDAPPLY,      0, "|",
  0x0000, "BUTTON",   sTxtClose,                   0x50010000, 278, 123,  67,  23, IDCLOSE,      0);

if (hDlg)
{
  AkelPad.ScriptNoMutex();
  AkelPad.WindowGetMessage();
}

AkelPad.WindowUnregisterClass(sClass);

AkelPad.MemFree(lpFirstC);
AkelPad.MemFree(lpCaret);
AkelPad.MemFree(lpSelect);

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

  if (uMsg == 272 /*WM_INITDIALOG*/)
  {
    hDlg = hWnd;

    //Set limit edit text
    for (i = IDBEGL; i <= IDENDC; ++i)
      SendDlgItemMessage(i, 197 /*EM_LIMITTEXT*/, 9, 0);
    for (i = IDBEGOF; i <= IDENDOF; ++i)
      SendDlgItemMessage(i, 197 /*EM_LIMITTEXT*/, 9, 0);

    //Set dialog position
    if ((typeof nDlgX != "number") || (typeof nDlgY != "number"))
      MoveDialog("RT");
  }

  else if (uMsg == 6 /*WM_ACTIVATE*/)
  {
    if (LoWord(wParam))
    {
      hEditWnd = AkelPad.GetEditWnd();
      bColSel  = SendMessage(hEditWnd, AEM_GETCOLUMNSEL, 0, 0);

      GetSelection();
      CheckButtons();
      ShowHideWindows();
    }
  }

  else if (uMsg == 260 /*WM_SYSKEYDOWN*/)
  {
    if (oSys.Call("User32::GetAsyncKeyState", 0xA0 /*VK_LSHIFT*/))
    {
      if (wParam == 0x27) //VK_RIGHT
        MoveDialog("R");
      else if (wParam == 0x25) //VK_LEFT
        MoveDialog("L");
      else if (wParam == 0x28) //VK_DOWN
        MoveDialog("D");
      else if (wParam == 0x26) //VK_UP
        MoveDialog("U");
      else if (wParam == 0x23) //VK_END
        MoveDialog("E");
      else if (wParam == 0x24) //VK_HOME
        MoveDialog("H");
      else if (wParam == 0x22) //VK_NEXT
        MoveDialog("B");
      else if (wParam == 0x21) //VK_PRIOR
        MoveDialog("T");
      else if ((wParam == 0x2D /*VK_INSERT*/) || (wParam == 0x2E /*VK_DELETE*/))
        MoveDialog("C");
    }
    else
    {
      if (wParam == 0x24) //VK_HOME
        CheckRadiobutton(bColSel ? IDCARPOS0 : IDCARPOSB);
      else if (wParam == 0x21) //VK_PRIOR
        CheckRadiobutton(bColSel ? IDCARPOS1 : IDCARPOSB);
      else if (wParam == 0x22) //VK_NEXT
        CheckRadiobutton(bColSel ? IDCARPOS2 : IDCARPOSE);
      else if (wParam == 0x23) //VK_END
        CheckRadiobutton(bColSel ? IDCARPOS3 : IDCARPOSE);
    }
  }

  else if (uMsg == 273 /*WM_COMMAND*/)
  {
    nID = LoWord(wParam);

    if (nID == IDOFFSET)
    {
      bOffset = SendDlgItemMessage(IDOFFSET, 240 /*BM_GETCHECK*/, 0, 0);
      ShowHideWindows();
      SendDlgItemMessage(bOffset ? IDBEGOF : IDBEGL, 177 /*EM_SETSEL*/, 0, -1);
      oSys.Call("User32::SetFocus", GetDlgItem(bOffset ? IDBEGOF : IDBEGL));
    }

    else if (nID == IDCOLSEL)
    {
      bColSel = SendDlgItemMessage(IDCOLSEL, 240 /*BM_GETCHECK*/, 0, 0);
      CheckButtons();
      ShowHideWindows();
    }

    else if (nID == IDAPPLY)
    {
      SetSelection();
      GetSelection();
    }

    else if ((nID == IDCLOSE) || (nID == 2 /*IDCANCEL*/))
      oSys.Call("User32::PostMessageW", hDlg, 16 /*WM_CLOSE*/, 0, 0);
  }

  else if (uMsg == 16 /*WM_CLOSE*/)
  {
    WriteIni();
    oSys.Call("User32::PostQuitMessage", 0);
    oSys.Call("User32::DestroyWindow", hDlg);
  }

  return 0;
}

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

function SendMessage(hWnd, uMsg, wParam, lParam)
{
  return AkelPad.SendMessage(hWnd, uMsg, wParam, lParam);
}

function SendDlgItemMessage(nID, uMsg, wParam, lParam)
{
  return oSys.Call("User32::SendDlgItemMessageW", hDlg, nID, uMsg, wParam, lParam);
}

function GetDlgItem(nID)
{
  return oSys.Call("User32::GetDlgItem", hDlg, nID);
}

function GetDlgItemText(nID)
{
  var nTextLen = SendDlgItemMessage(nID, 14 /*WM_GETTEXTLENGTH*/, 0, 0);
  var sText    = "";
  var lpText;

  if (nTextLen)
  {
    lpText = AkelPad.MemAlloc(nTextLen * 2 + 2);
    SendDlgItemMessage(nID, 13 /*WM_GETTEXT*/, nTextLen + 1, lpText);
    sText = AkelPad.MemRead(lpText, 1 /*DT_UNICODE*/);
    AkelPad.MemFree(lpText);
  }

  return sText;
}

function SetDlgItemText(nID, vText)
{
  SendDlgItemMessage(nID, 12 /*WM_SETTEXT*/, 0, vText.toString());
}

function CheckRadiobutton(nButton)
{
  oSys.Call("User32::CheckRadioButton", hDlg, IDCARPOSB, IDCARPOS3, nButton);
}

function MoveDialog(sAction)
{
  var lpRect    = AkelPad.MemAlloc(16); //sizeof(RECT)
  var oRectMain = {};
  var oRectDlg  = {};
  var nX;
  var nY;

  oSys.Call("User32::GetWindowRect", hMainWnd, lpRect);
  RectToObject(lpRect, oRectMain);

  oSys.Call("User32::GetWindowRect", hDlg, lpRect);
  RectToObject(lpRect, oRectDlg);

  nX = oRectDlg.left;
  nY = oRectDlg.top;

  if (sAction == "R") //Move right
    nX = oRectDlg.left + ((oRectDlg.right < oRectMain.right) ? 10 : 0);
  else if (sAction == "L") //Move left
    nX = oRectDlg.left - ((oRectDlg.left > oRectMain.left) ? 10 : 0);
  else if (sAction == "D") //Move down
    nY = oRectDlg.top + ((oRectDlg.bottom < oRectMain.bottom) ? 10 : 0);
  else if (sAction == "U") //Move up
    nY = oRectDlg.top - ((oRectDlg.top > oRectMain.top) ? 10 : 0);
  else if (sAction == "E") //Move end (right)
    nX = oRectDlg.left + (oRectMain.right - oRectDlg.right);
  else if (sAction == "H") //Move home (left)
    nX = oRectDlg.left + (oRectMain.left - oRectDlg.left);
  else if (sAction == "B") //Move bottom
    nY = oRectDlg.top + (oRectMain.bottom - oRectDlg.bottom);
  else if (sAction == "T") //Move top
    nY = oRectDlg.top + (oRectMain.top - oRectDlg.top);
  else if (sAction == "C") //Center window
  {
    nX = oRectMain.left + ((oRectMain.right  - oRectMain.left) / 2 - (oRectDlg.right  - oRectDlg.left) / 2);
    nY = oRectMain.top  + ((oRectMain.bottom - oRectMain.top)  / 2 - (oRectDlg.bottom - oRectDlg.top)  / 2);
  }
  else if (sAction == "LT") //Move left top
  {
    nX = oRectMain.left;
    nY = oRectMain.top;
  }
  else if (sAction == "RT") //Move right top
  {
    nX = oRectDlg.left + (oRectMain.right - oRectDlg.right);
    nY = oRectMain.top;
  }
  else if (sAction == "LB") //Move left bottom
  {
    nX = oRectMain.left;
    nY = oRectDlg.top + (oRectMain.bottom - oRectDlg.bottom);
  }
  else if (sAction == "RB") //Move right bottom
  {
    nX = oRectDlg.left + (oRectMain.right - oRectDlg.right);
    nY = oRectDlg.top + (oRectMain.bottom - oRectDlg.bottom);
  }

  oSys.Call("User32::SetWindowPos", hDlg, 0, nX, nY, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
  AkelPad.MemFree(lpRect);
}

function RectToObject(lpRect, oRect)
{
  oRect.left   = AkelPad.MemRead(_PtrAdd(lpRect,  0), 3 /*DT_DWORD*/);
  oRect.top    = AkelPad.MemRead(_PtrAdd(lpRect,  4), 3 /*DT_DWORD*/);
  oRect.right  = AkelPad.MemRead(_PtrAdd(lpRect,  8), 3 /*DT_DWORD*/);
  oRect.bottom = AkelPad.MemRead(_PtrAdd(lpRect, 12), 3 /*DT_DWORD*/);
}

function CheckButtons()
{
  SendDlgItemMessage(IDOFFSET, 241 /*BM_SETCHECK*/, bOffset, 0);
  SendDlgItemMessage(IDCOLSEL, 241 /*BM_SETCHECK*/, bColSel, 0);

  if (SendMessage(hEditWnd, AEM_INDEXCOMPARE, lpCaret, lpEndSel) == -1)
  {
    if (bColSel)
    {
      if (SendMessage(hEditWnd, AEM_INDEXCOMPARE, lpBegSel, lpFirstC) == 0)
        CheckRadiobutton(IDCARPOS0);
      else
        CheckRadiobutton(IDCARPOS1);
    }
    else
      CheckRadiobutton(IDCARPOSB);
  }
  else
  {
    if (bColSel)
    {
      if (SendMessage(hEditWnd, AEM_INDEXCOMPARE, lpBegSel, lpFirstC) == 0)
        CheckRadiobutton(IDCARPOS2);
      else
        CheckRadiobutton(IDCARPOS3);
    }
    else
      CheckRadiobutton(IDCARPOSE);
  }
}

function ShowHideWindows()
{
  var i;

  for (i = IDTXTLIN; i <= IDCARC; ++i)
    oSys.Call("User32::ShowWindow", GetDlgItem(i), ! bOffset);
  for (i = IDTXTOF; i <= IDCAROF; ++i)
    oSys.Call("User32::ShowWindow", GetDlgItem(i), bOffset);

  for (i = IDCARPOSB; i <= IDCARPOSE; ++i)
    oSys.Call("User32::ShowWindow", GetDlgItem(i), ! bColSel);
  for (i = IDCARPOS0; i <= IDCARPOS3; ++i)
    oSys.Call("User32::ShowWindow", GetDlgItem(i), bColSel);
}

function GetSelection()
{
  var i;

  SendMessage(hEditWnd, AEM_GETINDEX, AEGI_FIRSTSELCHAR, lpFirstC);
  SendMessage(hEditWnd, AEM_GETSEL, lpCaret, lpSelect);

  nBegOf = SendMessage(hEditWnd, AEM_INDEXTORICHOFFSET, 0, lpBegSel);
  nEndOf = SendMessage(hEditWnd, AEM_INDEXTORICHOFFSET, 0, lpEndSel);
  nCarOf = SendMessage(hEditWnd, AEM_INDEXTORICHOFFSET, 0, lpCaret);

  SetDlgItemText(IDBEGL, AkelPad.MemRead(lpBegL, 3 /*DT_DWORD*/) + 1);
  SetDlgItemText(IDBEGC, AkelPad.MemRead(lpBegC, 3 /*DT_DWORD*/) + 1);
  SetDlgItemText(IDENDL, AkelPad.MemRead(lpEndL, 3 /*DT_DWORD*/) + 1);
  SetDlgItemText(IDENDC, AkelPad.MemRead(lpEndC, 3 /*DT_DWORD*/) + 1);
  SetDlgItemText(IDCARL, AkelPad.MemRead(lpCarL, 3 /*DT_DWORD*/) + 1);
  SetDlgItemText(IDCARC, AkelPad.MemRead(lpCarC, 3 /*DT_DWORD*/) + 1);

  SetDlgItemText(IDBEGOF, nBegOf);
  SetDlgItemText(IDENDOF, nEndOf);
  SetDlgItemText(IDCAROF, nCarOf);

  for (i = IDBEGL; i <= IDENDC; ++i)
    SendDlgItemMessage(i, 177 /*EM_SETSEL*/, 0, -1);
  for (i = IDBEGOF; i <= IDENDOF; ++i)
    SendDlgItemMessage(i, 177 /*EM_SETSEL*/, 0, -1);
}

function SetSelection()
{
  var aCoord = new Array(4);
  var nBegL;
  var nBegC;
  var nEndL;
  var nEndC;
  var nOffset;
  var lpIndex;
  var i;

  if (bOffset)
  {
    lpIndex = AkelPad.MemAlloc(_X64 ? 24 : 12 /*sizeof(AECHARINDEX)*/);
    for (i = 0; i < 2; ++i)
    {
      nOffset = parseInt(GetDlgItemText(i + IDBEGOF));
      SendMessage(hEditWnd, AEM_RICHOFFSETTOINDEX, nOffset, lpIndex);
      aCoord[i*2]   = AkelPad.MemRead(lpIndex, 3 /*DT_DWORD*/);
      aCoord[i*2+1] = AkelPad.MemRead(_PtrAdd(lpIndex, _X64 ? 16 : 8), 3 /*DT_DWORD*/);
    }
    AkelPad.MemFree(lpIndex);
  }
  else
  {
    for (i = 0; i < 4; ++i)
    {
      aCoord[i] = parseInt(GetDlgItemText(i + IDBEGL));

      if (aCoord[i] > 0)
        --aCoord[i];
    }
  }

  if ((aCoord[0] > aCoord[2]) || ((aCoord[0] == aCoord[2]) && (aCoord[1] > aCoord[3])))
  {
    nBegL = aCoord[2];
    nBegC = aCoord[3];
    nEndL = aCoord[0];
    nEndC = aCoord[1];
  }
  else
  {
    nBegL = aCoord[0];
    nBegC = aCoord[1];
    nEndL = aCoord[2];
    nEndC = aCoord[3];
  }

  if (bColSel)
  {
    if (SendDlgItemMessage(IDCARPOS0, 240 /*BM_GETCHECK*/, 0, 0))
    {
      if (nBegC < nEndC)
        CopyCoordinatesToIndex(nBegL, nBegC, nEndL, nEndC, nBegL, nBegC);
      else
        CopyCoordinatesToIndex(nBegL, nEndC, nEndL, nBegC, nBegL, nEndC);
    }
    else if (SendDlgItemMessage(IDCARPOS1, 240 /*BM_GETCHECK*/, 0, 0))
    {
      if (nBegC < nEndC)
        CopyCoordinatesToIndex(nBegL, nEndC, nEndL, nBegC, nBegL, nEndC);
      else
        CopyCoordinatesToIndex(nBegL, nBegC, nEndL, nEndC, nBegL, nBegC);
    }
    else if (SendDlgItemMessage(IDCARPOS2, 240 /*BM_GETCHECK*/, 0, 0))
    {
      if (nBegC < nEndC)
        CopyCoordinatesToIndex(nBegL, nBegC, nEndL, nEndC, nEndL, nEndC);
      else
        CopyCoordinatesToIndex(nBegL, nEndC, nEndL, nBegC, nEndL, nBegC);
    }
    else
    {
      if (nBegC < nEndC)
        CopyCoordinatesToIndex(nBegL, nEndC, nEndL, nBegC, nEndL, nBegC);
      else
        CopyCoordinatesToIndex(nBegL, nBegC, nEndL, nEndC, nEndL, nEndC);
    }
  }
  else
  {
    if (SendDlgItemMessage(IDCARPOSB, 240 /*BM_GETCHECK*/, 0, 0))
      CopyCoordinatesToIndex(nBegL, nBegC, nEndL, nEndC, nBegL, nBegC);
    else
      CopyCoordinatesToIndex(nBegL, nBegC, nEndL, nEndC, nEndL, nEndC);
  }

  SendMessage(hEditWnd, AEM_INDEXUPDATE, 0, lpBegSel);
  SendMessage(hEditWnd, AEM_INDEXUPDATE, 0, lpEndSel);
  SendMessage(hEditWnd, AEM_INDEXUPDATE, 0, lpCaret);

  AkelPad.MemCopy(lpSelFlag, bColSel, 3 /*DT_DWORD*/);
  SendMessage(hEditWnd, AEM_SETSEL, lpCaret, lpSelect);

  oSys.Call("User32::InvalidateRect", hEditWnd, 0, true);
}

function CopyCoordinatesToIndex(n1, n2, n3, n4, n5, n6)
{
  AkelPad.MemCopy(lpBegL, n1, 3 /*DT_DWORD*/);
  AkelPad.MemCopy(lpBegC, n2, 3 /*DT_DWORD*/);
  AkelPad.MemCopy(lpEndL, n3, 3 /*DT_DWORD*/);
  AkelPad.MemCopy(lpEndC, n4, 3 /*DT_DWORD*/);
  AkelPad.MemCopy(lpCarL, n5, 3 /*DT_DWORD*/);
  AkelPad.MemCopy(lpCarC, n6, 3 /*DT_DWORD*/);
}

function ReadIni()
{
  try
  {
    eval(ReadIni.Text = AkelPad.ReadFile(WScript.ScriptFullName.replace(/\.js$/i, ".ini"), 0x1D /*OD_ADT_BINARY_ERROR|OD_ADT_DETECT_CODEPAGE|OD_ADT_DETECT_BOM|OD_ADT_NOMESSAGES*/));
  }
  catch (oError)
  {}
}

function WriteIni()
{
  var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
  var sText;

  oSys.Call("User32::GetWindowRect", hDlg, lpRect);
  oSys.Call("User32::ScreenToClient", hMainWnd, lpRect);
  nDlgX = AkelPad.MemRead(_PtrAdd(lpRect, 0), 3 /*DT_DWORD*/);
  nDlgY = AkelPad.MemRead(_PtrAdd(lpRect, 4), 3 /*DT_DWORD*/);
  AkelPad.MemFree(lpRect);

  sText = 'nDlgX='   + nDlgX + ';\r\n' + 
          'nDlgY='   + nDlgY + ';\r\n' + 
          'bOffset=' + bOffset + ';\r\n';

  if (sText != ReadIni.Text) 
    AkelPad.WriteFile(WScript.ScriptFullName.replace(/\.js$/i, ".ini"), sText, sText.length, 1200 /*UTF-16LE*/, true);
}

function GetLangStrings()
{
  sTxtCaption = "选择文本范围";
  sTxtCoordin = "坐标";
  sTxtLine    = "行";
  sTxtColumn  = "列";
  sTxtBegin   = "开始";
  sTxtEnd     = "结束";
  sTxtCaret   = "插入点";
  sTxtOffset  = "偏移量(&O)";
  sTxtColSel  = "列选(&C)";
  sTxtCarPos  = "插入点位置";
  sTxtCarPos0 = "左上";
  sTxtCarPos1 = "右上";
  sTxtCarPos2 = "右下";
  sTxtCarPos3 = "左下";
  sTxtApply   = "应用";
  sTxtClose   = "关闭";
}
