// CreateDialog.js - ver. 2014-05-11 (x86/x64)
//
// Example of create dialog boxes by using CreateDialogWindow() and CreateDialogBox() functions
//
// Usage:
// Call("Scripts::Main", 1, "CreateDialog.js")
// Required to include: CreateDialog_functions.js

var oSys   = AkelPad.SystemFunction();
var sClass = "AkelPad::Scripts::" + WScript.ScriptName + "::" + AkelPad.GetInstanceDll();
var hDlg   = oSys.Call("User32::FindWindowW", 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);
}
else if (AkelPad.Include("CreateDialog_functions.js"))
{
  var hRichEdLib = oSys.Call("Kernel32::LoadLibraryW", "Msftedit.dll");
  var hIcon      = oSys.Call("User32::LoadImageW", AkelPad.GetInstanceDll(), 101, 1 /*uType=IMAGE_ICON*/, 0, 0, 0x40 /*LR_DEFAULTSIZE*/);
  var nCounter   = 0;
  var IDCANCEL   = 2;
  var IDMENU11   = 1011;
  var IDMENU12   = 1012;
  var IDMENU13   = 1013;
  var IDMENU14   = 1014;
  var IDMENU21   = 1021;
  var IDMENU22   = 1022;
  var IDMENU23   = 1023;
  var IDMENU24   = 1024;
  var IDGROUPB   = 2000;
  var IDCHECKB   = 2001;
  var IDRADIO1   = 2002;
  var IDRADIO2   = 2003;
  var IDBUTTON   = 2004;
  var IDGROUPCB  = 2005;
  var IDCBS1     = 2006;
  var IDCBS2     = 2007;
  var IDCBS3     = 2008;
  var IDCB1      = 2009;
  var IDCB2      = 2010;
  var IDCB3      = 2011;
  var IDGROUPDT  = 2012;
  var IDDT1      = 2013;
  var IDDT2      = 2014;
  var IDDT3      = 2015;
  var IDGROUPE   = 2016;
  var IDE        = 2017;
  var IDRE       = 2018;
  var IDAE       = 2019;
  var IDGROUPLB  = 2020;
  var IDLB       = 2021;
  var IDGROUPLV  = 2022;
  var IDLV       = 2023;
  var IDGROUPMC  = 2024;
  var IDMC       = 2025;
  var IDGROUPTV  = 2026;
  var IDTV       = 2027;
  var IDGROUPLW  = 2028;
  var IDLW       = 2029;
  var IDGROUPTB  = 2030;
  var IDTB       = 2031;
  var IDGROUPUD  = 2032;
  var IDBUDDYUD  = 2033;
  var IDUD       = 2034;
  var IDTC       = 2035;
  var IDGROUPPB  = 2036;
  var IDPB       = 2037;
  var IDSBAR     = 2038;

  if (AkelPad.WindowRegisterClass(sClass))
  {
    //Allow other scripts running
    AkelPad.ScriptNoMutex();

    CreateDialog(false, true, AkelPad.GetMainWnd());
    AkelPad.WindowUnregisterClass(sClass);
  }

  oSys.Call("Kernel32::FreeLibrary", hRichEdLib);
  oSys.Call("user32::DestroyIcon", hIcon);
}

function CreateDialog(bBox, bModeless, hParent)
{
  var nTimerID = ++nCounter;
  var aDlg     = [];
  var nResult;
  var hFocus;

  aDlg.Modeless = bModeless;
  aDlg.Title    = "[" + nTimerID + "] " + (bBox ? "Dialog box " : "Dialog window ") + (bModeless ? "modeless" : "modal");
  aDlg.Style    = WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
  aDlg.Parent   = hParent;
  aDlg.Menu     = CreateMainMenu();
  aDlg.Callback = DialogCallback;
  aDlg.Icon     = hIcon;
  aDlg.X        = 20;
  aDlg.W        = 650;
  aDlg.H        = 432;
  aDlg.PosPar   = 3;
  aDlg.CtlFirst = IDGROUPB;
  aDlg.CtlStyle = WS_VISIBLE;

  if (bBox)
  {
    aDlg.PosPix   = true;
    aDlg.CtlFontN = "MS Shell Dlg";
  }
  else
  {
    aDlg.Class   = sClass;
    aDlg.SizeClt = true;
    aDlg.CtlFont = oSys.Call("Gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
  }

  aDlg[IDGROUPB]  = {X:  10, Y:  10, W: 100, H: 125, Title: "Button",     Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDCHECKB]  = {X:  20, Y:  30, W:  80, H:  16, Title: "CheckBox",   Style: WS_TABSTOP | BS_AUTOCHECKBOX};
  aDlg[IDRADIO1]  = {X:  20, Y:  57, W:  80, H:  16, Title: "Radio1",     Style: WS_TABSTOP | BS_AUTORADIOBUTTON};
  aDlg[IDRADIO2]  = {X:  20, Y:  73, W:  80, H:  16, Title: "Radio2",     Style: WS_TABSTOP | BS_AUTORADIOBUTTON};
  aDlg[IDBUTTON]  = {X:  20, Y: 102, W:  80, H:  23, Title: "PushButton", Style: WS_TABSTOP | BS_PUSHBUTTON};

  aDlg[IDGROUPCB] = {X: 120, Y:  10, W: 190, H: 125, Title: "ComboBox", Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDCBS1]    = {X: 130, Y:  30, W:  80, H:  13, Title: "Simple",         Class: "STATIC"};
  aDlg[IDCBS2]    = {X: 220, Y:  30, W:  80, H:  13, Title: "Drop-down",      Class: "STATIC"};
  aDlg[IDCBS3]    = {X: 220, Y:  87, W:  80, H:  13, Title: "Drop-down list", Class: "STATIC"};
  aDlg[IDCB1]     = {X: 130, Y:  45, W:  80, H:  82,                         Class: "COMBOBOX", Style: WS_TABSTOP | WS_VSCROLL | CBS_SIMPLE | CBS_NOINTEGRALHEIGHT};
  aDlg[IDCB2]     = {X: 220, Y:  45, W:  80, H: 120,                         Class: "COMBOBOX", Style: WS_TABSTOP | CBS_DROPDOWN};
  aDlg[IDCB3]     = {X: 220, Y: 102, W:  80, H: 120,                         Class: "COMBOBOX", Style: WS_TABSTOP | CBS_DROPDOWNLIST};

  aDlg[IDGROUPDT] = {X: 320, Y:  10, W: 100, H: 125, Title: "DateTimePicker", Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDDT1]     = {X: 330, Y:  30, W:  80, H:  23, Title: "Edit", Class: "SysDateTimePick32", Style: WS_TABSTOP};
  aDlg[IDDT2]     = {X: 330, Y:  66, W:  80, H:  23, Title: "Edit", Class: "SysDateTimePick32", Style: WS_TABSTOP | DTS_UPDOWN};
  aDlg[IDDT3]     = {X: 330, Y: 102, W:  80, H:  23, Title: "Edit", Class: "SysDateTimePick32", Style: WS_TABSTOP};

  aDlg[IDGROUPE]  = {X: 430, Y:  10, W: 100, H: 125, Title: "Edit", Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDE]       = {X: 440, Y:  30, W:  80, H:  20, Title: "Edit",     Class: "EDIT",        Style: WS_TABSTOP | WS_BORDER};
  aDlg[IDRE]      = {X: 440, Y:  60, W:  80, H:  20, Title: "RichEdit", Class: "RichEdit50W", Style: WS_TABSTOP | WS_BORDER};
  aDlg[IDAE]      = {X: 440, Y:  90, W:  80, H:  35,                   Class: "AkelEditW",   Style: WS_TABSTOP | WS_BORDER | ES_MULTILINE | ES_WANTRETURN};

  aDlg[IDGROUPLB] = {X: 540, Y:  10, W: 100, H: 125, Title: "ListBox", Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDLB]      = {X: 550, Y:  30, W:  80, H:  95, Class: "LISTBOX", Style: WS_TABSTOP | WS_VSCROLL | WS_BORDER | LBS_NOINTEGRALHEIGHT};

  aDlg[IDGROUPLV] = {X:  10, Y: 145, W: 130, H: 185, Title: "ListView", Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDLV]      = {X:  20, Y: 165, W: 110, H: 155, Class: "SysListView32", Style: WS_TABSTOP | WS_BORDER | LVS_REPORT | LVS_SHOWSELALWAYS};

  aDlg[IDGROUPMC] = {X: 150, Y: 145, W: 190, H: 185, Title: "MonthCalendar", Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDMC]      = {X: 160, Y: 165, W: 170, H: 155, Class: "SysMonthCal32", Style: WS_TABSTOP | WS_BORDER};

  aDlg[IDGROUPTV] = {X: 350, Y: 145, W: 150, H: 185, Title: "TreeView", Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDTV]      = {X: 360, Y: 165, W: 130, H: 155, Class: "SysTreeView32", Style: WS_TABSTOP | WS_BORDER | TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT};

  aDlg[IDGROUPLW] = {X: 510, Y: 145, W: 130, H:  45, Title: "SysLink", Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDLW]      = {X: 520, Y: 165, W: 110, H:  16, Title: "<a>Show/hide main menu</a>", Class: "SysLink"};

  aDlg[IDGROUPTB] = {X: 510, Y: 200, W: 130, H:  60, Title: "TrackBar", Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDTB]      = {X: 520, Y: 220, W: 110, H:  30, Class: "msctls_trackbar32", Style: WS_TABSTOP | TBS_AUTOTICKS};

  aDlg[IDGROUPUD] = {X: 510, Y: 270, W: 130, H:  60, Title: "Up-Down", Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDBUDDYUD] = {X: 550, Y: 295, W:  50, H:  20, Class: "EDIT", Style: WS_TABSTOP | ES_NUMBER, ExStyle: WS_EX_CLIENTEDGE};
  aDlg[IDUD]      = {                                Class: "msctls_updown32", Style: UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_SETBUDDYINT};

  aDlg[IDTC]      = {X:  10, Y: 345, W: 490, H:  55, Class: "SysTabControl32", Style: WS_TABSTOP | TCS_FIXEDWIDTH | TCS_FOCUSONBUTTONDOWN};

  aDlg[IDGROUPPB] = {X: 510, Y: 340, W: 130, H:  60, Title: "ProgressBar", Style: BS_GROUPBOX | BS_CENTER};
  aDlg[IDPB]      = {X: 520, Y: 365, W: 110, H:  20, Class: "msctls_progress32"};

  aDlg[IDSBAR]    = {Class: "msctls_statusbar32"};

  if (bBox)
  {
    if (bModeless)
    {
      if (CreateDialogBox(aDlg))
      {
        if (nTimerID == 1)
          AkelPad.WindowGetMessage(0x2 /*WGM_NOKEYSEND*/);
      }
      else
        oSys.Call("User32::DestroyMenu", aDlg.Menu);
    }
    else
    {
      nResult = CreateDialogBox(aDlg);
      if (nResult == -1)
        oSys.Call("User32::DestroyMenu", aDlg.Menu);
    }
  }
  else
  {
    if (CreateDialogWindow(aDlg, 1))
    {
      if (! bModeless)
        oSys.Call("user32::EnableWindow", aDlg.Parent, 0);
      if (nTimerID == 1)
        AkelPad.WindowGetMessage(0x2 /*WGM_NOKEYSEND*/);
    }
    else
      oSys.Call("User32::DestroyMenu", aDlg.Menu);
  }

  function DialogCallback(hWnd, uMsg, wParam, lParam)
  {
    if (uMsg == 1 /*WM_CREATE*/)
    {
      aDlg.HWND = hWnd;
      CreateDialogWindow(aDlg, 2, hWnd);
      InitDialog();
      hFocus = aDlg[IDCHECKB].HWND;
    }

    else if (uMsg == 272 /*WM_INITDIALOG*/)
      InitDialog();

    else if ((uMsg == 6 /*WM_ACTIVATE*/) && (wParam == 0 /*WA_INACTIVE*/) && (! bBox))
      hFocus = oSys.Call("User32::GetFocus");
  
    else if ((uMsg == 7 /*WM_SETFOCUS*/) && (! bBox))
      oSys.Call("User32::SetFocus", hFocus);

    else if (uMsg == 5 /*WM_SIZE*/)
      AkelPad.SendMessage(aDlg[IDSBAR].HWND, 5 /*WM_SIZE*/, 0, 0);

    if (uMsg == 78 /*WM_NOTIFY*/)
    {
      if (AkelPad.MemRead(lParam + (_X64 ? 16 : 8), 3 /*DT_DWORD*/) == -2 /*NM_CLICK*/)
      {
        if (wParam == IDLW)
        {
          oSys.Call("User32::SetMenu", hWnd, oSys.Call("User32::GetMenu", hWnd) ? 0 : aDlg.Menu);
          AkelPad.SendMessage(aDlg[IDSBAR].HWND, 5 /*WM_SIZE*/, 0, 0);
        }
      }
    }

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

      if (nLowParam == IDBUTTON)
        AkelPad.MessageBox(hWnd, '"PushButton" has been pressed.', aDlg.Title, 0x40 /*MB_ICONINFORMATION*/);
      else if (nLowParam == IDMENU11)
        CreateDialog(false, false, hWnd);
      else if (nLowParam == IDMENU12)
        CreateDialog(false, true, hWnd);
      else if (nLowParam == IDMENU13)
        CreateDialog(true, false, hWnd);
      else if (nLowParam == IDMENU14)
        CreateDialog(true, true, hWnd);
      else if ((nLowParam >= IDMENU21) && (nLowParam <= IDMENU24))
        AkelPad.MessageBox(hWnd, "Command: " + nLowParam, aDlg.Title, 0x40 /*MB_ICONINFORMATION*/);
      else if (nLowParam == IDCANCEL)
        oSys.Call("User32::PostMessageW", hWnd, 16 /*WM_CLOSE*/, nLowParam, 0);
    }

    else if (uMsg == 275 /*WM_TIMER*/)
    {
      AkelPad.SendMessage(aDlg[IDPB].HWND, 1029 /*PBM_STEPIT*/, 0, 0);
      SetTextSBAR(AkelPad.SendMessage(aDlg[IDPB].HWND, 1032 /*PBM_GETPOS*/, 0, 0));
    }

    else if (uMsg == 16 /*WM_CLOSE*/)
    {
      if ((! bBox) && (! bModeless))
      {
        oSys.Call("user32::EnableWindow", aDlg.Parent, 1);
        oSys.Call("User32::SetForegroundWindow", aDlg.Parent);
      }

      AkelPad.WindowUnsubClass(aDlg[IDRE].HWND);
      oSys.Call("User32::KillTimer", hWnd, nTimerID);

      if (bBox && (! bModeless))
        oSys.Call("User32::EndDialog", hWnd, wParam);
      else
        oSys.Call("User32::DestroyWindow", hWnd);
    }

    else if (uMsg == 2 /*WM_DESTROY*/)
    {
      oSys.Call("User32::DestroyMenu", aDlg.Menu);
      if (nTimerID == 1)
        oSys.Call("User32::PostQuitMessage", 0);
    }

    return 0;
  }

  function InitDialog()
  {
    var i;

    //Button
    AkelPad.SendMessage(aDlg[IDCHECKB].HWND, 241 /*BM_SETCHECK*/, 1 /*BST_CHECKED*/, 0);
    AkelPad.SendMessage(aDlg[IDRADIO1].HWND, 241 /*BM_SETCHECK*/, 0 /*BST_UNCHECKED*/, 0);
    AkelPad.SendMessage(aDlg[IDRADIO2].HWND, 241 /*BM_SETCHECK*/, 1 /*BST_CHECKED*/, 0);

    //ComboBox
    for (i = 0; i < 15; ++i) AkelPad.SendMessage(aDlg[IDCB1].HWND, 323 /*CB_ADDSTRING*/, 0, "Item " + i);
    for (i = 0; i < 15; ++i) AkelPad.SendMessage(aDlg[IDCB2].HWND, 323 /*CB_ADDSTRING*/, 0, "Item " + i);
    for (i = 0; i < 15; ++i) AkelPad.SendMessage(aDlg[IDCB3].HWND, 323 /*CB_ADDSTRING*/, 0, "Item " + i);
    AkelPad.SendMessage(aDlg[IDCB1].HWND, 334 /*CB_SETCURSEL*/, 4, 0);
    AkelPad.SendMessage(aDlg[IDCB2].HWND, 334 /*CB_SETCURSEL*/, 2, 0);
    AkelPad.SendMessage(aDlg[IDCB3].HWND, 334 /*CB_SETCURSEL*/, 6, 0);

    //DateTimePicker
    AkelPad.SendMessage(aDlg[IDDT3].HWND, 4146 /*DTM_SETFORMATW*/, 0, "ddd HH:mm");

    //Edit
    AkelPad.WindowSubClass(aDlg[IDRE].HWND, RichEditCallback, 258 /*WM_CHAR*/);
    oSys.Call("User32::SetWindowTextW", aDlg[IDAE].HWND, "AkelEdit\nmultiline");

    //ListBox
    for (i = 0; i < 20; ++i) AkelPad.SendMessage(aDlg[IDLB].HWND, 384 /*LB_ADDSTRING*/, 0, "Item " + i);
    AkelPad.SendMessage(aDlg[IDLB].HWND, 390 /*LB_SETCURSEL*/, 9, 0);

    //ListView
    FillLV();

    //TreeView
    FillTV();

    //TrackBar
    AkelPad.SendMessage(aDlg[IDTB].HWND, 1044 /*TBM_SETTICFREQE*/, 10, 0);

    //Up-Down
    AkelPad.SendMessage(aDlg[IDUD].HWND, 1129 /*UDM_SETBUDDY*/, aDlg[IDBUDDYUD].HWND, 0);
    AkelPad.SendMessage(aDlg[IDUD].HWND, 1135 /*UDM_SETRANGE32*/, 1, 100);
    AkelPad.SendMessage(aDlg[IDUD].HWND, 1137 /*UDM_SETPOS32*/, 0, 50);

    //Tab
    FillTC();

    //ProgressBar
    AkelPad.SendMessage(aDlg[IDPB].HWND, 1028 /*PBM_SETSTEP*/, 1, 0);
    oSys.Call("User32::SetTimer", aDlg.HWND, nTimerID, 200, 0);

    //StatusBar
    SetPartsSBAR();
    SetTextSBAR(0);
  }

  function RichEditCallback(hWnd, uMsg, wParam, lParam)
  {
    if (uMsg == 258) //WM_CHAR
    {
      if (wParam == 0x09 /*VK_TAB*/)
        oSys.Call("User32::SetFocus", oSys.Call("User32::GetNextDlgTabItem", aDlg.HWND, hWnd, Shift()));
    }

    return 0;
  }

  function FillLV()
  {
    var nBufSize   = 64;
    var lpText     = AkelPad.MemAlloc(nBufSize);
    var lpLVITEM   = AkelPad.MemAlloc(_X64 ? 72 : 60 /*sizeof(LVITEM)*/);
    var lpLVCOLUMN = AkelPad.MemAlloc(_X64 ? 56 : 44 /*sizeof(LVCOLUMN)*/);
    var i;

    AkelPad.MemCopy(lpText, "Name", 1 /*DT_UNICODE*/);
    AkelPad.MemCopy(lpLVCOLUMN, 5 /*LVCF_FMT|LVCF_TEXT*/, 3 /*DT_DWORD*/);  //mask
    AkelPad.MemCopy(lpLVCOLUMN + (_X64 ? 16 : 12), lpText, 2 /*DT_QWORD*/); //pszText
    AkelPad.SendMessage(aDlg[IDLV].HWND, 4193 /*LVM_INSERTCOLUMNW*/, 0, lpLVCOLUMN);

    AkelPad.MemCopy(lpText, "Value", 1 /*DT_UNICODE*/);
    AkelPad.MemCopy(lpLVCOLUMN + 4, 1 /*LVCFMT_RIGHT*/, 3 /*DT_DWORD*/); //fmt
    AkelPad.SendMessage(aDlg[IDLV].HWND, 4193 /*LVM_INSERTCOLUMNW*/, 1, lpLVCOLUMN);

    AkelPad.MemCopy(lpLVITEM, 1 /*LVIF_TEXT*/, 3 /*DT_DWORD*/);             //mask
    AkelPad.MemCopy(lpLVITEM + (_X64 ? 24 : 20), lpText, 2 /*DT_QWORD*/);   //pszText
    AkelPad.MemCopy(lpLVITEM + (_X64 ? 32 : 24), nBufSize, 3 /*DT_DWORD*/); //cchTextMax

    for (i = 0; i < 25; ++i)
    {
      AkelPad.MemCopy(lpText, "Item " + i, 1 /*DT_UNICODE*/);
      AkelPad.MemCopy(lpLVITEM + 4, i, 3 /*DT_DWORD*/); //iItem
      AkelPad.MemCopy(lpLVITEM + 8, 0, 3 /*DT_DWORD*/); //iSubItem
      AkelPad.SendMessage(aDlg[IDLV].HWND, 4173 /*LVM_INSERTITEMW*/, 0, lpLVITEM);

      AkelPad.MemCopy(lpText, (i * i + 99).toString(), 1 /*DT_UNICODE*/);
      AkelPad.MemCopy(lpLVITEM + 8, 1, 3 /*DT_DWORD*/); //iSubItem
      AkelPad.SendMessage(aDlg[IDLV].HWND, 4212 /*LVM_SETITEMTEXTW*/, i, lpLVITEM);
    }

    AkelPad.SendMessage(aDlg[IDLV].HWND, 4126 /*LVM_SETCOLUMNWIDTH*/, 0, -2 /*LVSCW_AUTOSIZE_USEHEADER*/);
    AkelPad.SendMessage(aDlg[IDLV].HWND, 4126 /*LVM_SETCOLUMNWIDTH*/, 1, -2 /*LVSCW_AUTOSIZE_USEHEADER*/);
    AkelPad.SendMessage(aDlg[IDLV].HWND, 4150 /*LVM_SETEXTENDEDLISTVIEWSTYLE*/, 0x20 /*LVS_EX_FULLROWSELECT*/, 0x20);

    AkelPad.MemCopy(lpLVITEM + 12, 3 /*LVIS_SELECTED|LVIS_FOCUSED*/, 3 /*DT_DWORD*/); //state
    AkelPad.MemCopy(lpLVITEM + 16, 3 /*LVIS_SELECTED|LVIS_FOCUSED*/, 3 /*DT_DWORD*/); //stateMask
    AkelPad.SendMessage(aDlg[IDLV].HWND, 4139 /*LVM_SETITEMSTATE*/, 7, lpLVITEM);
    AkelPad.SendMessage(aDlg[IDLV].HWND, 4115 /*LVM_ENSUREVISIBLE*/, 7, false);

    AkelPad.MemFree(lpText);
    AkelPad.MemFree(lpLVITEM);
    AkelPad.MemFree(lpLVCOLUMN);
  }

  function FillTV()
  {
    var nBufSize   = 64;
    var lpText     = AkelPad.MemAlloc(nBufSize);
    var lpTVINSERT = AkelPad.MemAlloc(_X64 ? 72 : 48 /*sizeof(TVINSERTSTRUCT)*/);
    var hRoot;
    var hChild;
    var i, n;

    AkelPad.MemCopy(lpText, "Root", 1 /*DT_UNICODE*/);
    AkelPad.MemCopy(lpTVINSERT + (_X64 ? 16 :  8), 0x41 /*TVIF_CHILDREN|TVIF_TEXT*/, 3 /*DT_DWORD*/); //mask
    AkelPad.MemCopy(lpTVINSERT + (_X64 ? 40 : 24), lpText, 2 /*DT_QWORD*/);                           //pszText
    AkelPad.MemCopy(lpTVINSERT + (_X64 ? 48 : 28), nBufSize, 3 /*DT_DWORD*/);                         //cchTextMax
    AkelPad.MemCopy(lpTVINSERT + (_X64 ? 60 : 40), 1, 3 /*DT_DWORD*/);                                //cChildren
    hRoot = AkelPad.SendMessage(aDlg[IDTV].HWND, 4402 /*TVM_INSERTITEMW*/, 0, lpTVINSERT);

    for (i = 1; i < 10; ++i)
    {
      AkelPad.MemCopy(lpText, "Child-" + i, 1 /*DT_UNICODE*/);
      AkelPad.MemCopy(lpTVINSERT, hRoot, 2 /*DT_QWORD*/);                                    //hParent
      AkelPad.MemCopy(lpTVINSERT + (_X64 ? 8 : 4), 0xFFFF0002 /*TVI_LAST*/, 2 /*DT_QWORD*/); //hInsertAfter
      AkelPad.MemCopy(lpTVINSERT + (_X64 ? 60 : 40), 1, 3 /*DT_DWORD*/);                     //cChildren
      hChild = AkelPad.SendMessage(aDlg[IDTV].HWND, 4402 /*TVM_INSERTITEMW*/, 0, lpTVINSERT);

      for (n = 1; n < 4; ++n)
      {
        AkelPad.MemCopy(lpText, "Child-" + i + "-" + n, 1 /*DT_UNICODE*/);
        AkelPad.MemCopy(lpTVINSERT, hChild, 2 /*DT_QWORD*/);                                   //hParent
        AkelPad.MemCopy(lpTVINSERT + (_X64 ? 8 : 4), 0xFFFF0002 /*TVI_LAST*/, 2 /*DT_QWORD*/); //hInsertAfter
        AkelPad.MemCopy(lpTVINSERT + (_X64 ? 60 : 40), 0, 3 /*DT_DWORD*/);                     //cChildren
        AkelPad.SendMessage(aDlg[IDTV].HWND, 4402 /*TVM_INSERTITEMW*/, 0, lpTVINSERT);
      }
    }

    AkelPad.SendMessage(aDlg[IDTV].HWND, 4354 /*TVM_EXPAND*/, 2 /*TVE_EXPAND*/, hRoot);

    AkelPad.MemFree(lpText);
    AkelPad.MemFree(lpTVINSERT);
  }

  function FillTC()
  {
    var lpText   = AkelPad.MemAlloc(64);
    var lpTCITEM = AkelPad.MemAlloc(_X64 ? 40 : 28 /*sizeof(TCITEM)*/);
    var i;

    AkelPad.MemCopy(lpTCITEM, 1 /*TCIF_TEXT*/, 3 /*DT_DWORD*/); //mask
    AkelPad.MemCopy(lpTCITEM + (_X64 ? 16 : 12), lpText, 2 /*DT_QWORD*/); //pszText

    for (i = 0; i <= 7; ++i)
    {
      AkelPad.MemCopy(lpText, "Tab " + i, 1 /*DT_UNICODE*/);
      AkelPad.SendMessage(aDlg[IDTC].HWND, 4926 /*TCM_INSERTITEMW*/, i, lpTCITEM);
    }

    AkelPad.SendMessage(aDlg[IDTC].HWND, 4905 /*TCM_SETITEMSIZE*/, 0, MkLong(60, 20));
    AkelPad.SendMessage(aDlg[IDTC].HWND, 4876 /*TCM_SETCURSEL*/, 1, 0);

    AkelPad.MemFree(lpText);
    AkelPad.MemFree(lpTCITEM);
  }

  function SetPartsSBAR()
  {
    var lpParts = AkelPad.MemAlloc(3 * 4 /*sizeof(int)*/);

    AkelPad.MemCopy(lpParts,      Scale.X(80), 3 /*DT_DWORD*/);
    AkelPad.MemCopy(lpParts + 4, Scale.X(160), 3 /*DT_DWORD*/);
    AkelPad.MemCopy(lpParts + 8,           -1, 3 /*DT_DWORD*/);

    AkelPad.SendMessage(aDlg[IDSBAR].HWND, 1028 /*SB_SETPARTS*/, 3, lpParts);
    AkelPad.SendMessage(aDlg[IDSBAR].HWND, 5 /*WM_SIZE*/, 0, 0);

    AkelPad.MemFree(lpParts);
  }

  function SetTextSBAR(nProgress)
  {
    AkelPad.SendMessage(aDlg[IDSBAR].HWND, 1035 /*SB_SETTEXTW*/, 0, "\tStatusBar");
    AkelPad.SendMessage(aDlg[IDSBAR].HWND, 1035 /*SB_SETTEXTW*/, 1, "Progress: " + nProgress + "%");
    AkelPad.SendMessage(aDlg[IDSBAR].HWND, 1035 /*SB_SETTEXTW*/, 2, "\t\t" + (new Date()).toLocaleString());
  }
}

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

function MkLong(nLoWord, nHiWord)
{
  return (nLoWord & 0xFFFF) | (nHiWord << 16);
}

function Shift()
{
  return Boolean(oSys.Call("User32::GetKeyState", 0x10 /*VK_SHIFT*/) & 0x8000);
}

function CreateMainMenu()
{
  var MF_STRING = 0x0000;
  var MF_POPUP  = 0x0010;
  var hMenu  = oSys.Call("User32::CreateMenu");
  var hMenu1 = oSys.Call("User32::CreatePopupMenu");
  var hMenu2 = oSys.Call("User32::CreatePopupMenu");
  var i;

  oSys.Call("User32::AppendMenuW", hMenu, MF_POPUP, hMenu1, "&New");
  oSys.Call("User32::AppendMenuW", hMenu, MF_POPUP, hMenu2, "&Other");
  oSys.Call("User32::AppendMenuW", hMenu, MF_STRING, IDCANCEL, "E&xit");

  oSys.Call("User32::AppendMenuW", hMenu1, MF_STRING, IDMENU11, "&1 - Dialog window modal");
  oSys.Call("User32::AppendMenuW", hMenu1, MF_STRING, IDMENU12, "&2 - Dialog window modeless");
  oSys.Call("User32::AppendMenuW", hMenu1, MF_STRING, IDMENU13, "&3 - Dialog box modal");
  oSys.Call("User32::AppendMenuW", hMenu1, MF_STRING, IDMENU14, "&4 - Dialog box modeless");

  for (i = IDMENU21; i <= IDMENU24; ++i)
    oSys.Call("User32::AppendMenuW", hMenu2, MF_STRING, i, "Command " + i);

  return hMenu;
}
