Scripts collection

Discuss and announce AkelPad plugins
  • Author
  • Message
Offline
Posts: 874
Joined: Sat Jan 16, 2010 2:03 pm

Post by opk44 »

Декодер макросов по словарю Surveyor-а (из AkelPad Plugins Manual)

Code: Select all

' (c) opk44 2011
' version 0.1.0 - 2011-10-20
' Использовано "Appendix A - Virtual Key codes" AkelPad Plugins Manual (Surveyor)
' 
' Usage:
' Call("Scripts::Main", 1, "MacroDecoder.vbs")

' Known BUGS: 
' 1) Работает только на Win2000/WinXP (на Vista/Win7 не проверялось, но, по-видимому, работать не будет)
' 2) Инициализация директории в диалоге выбора файла-макроса иногда не срабатывает (вместо указанной 
'    стартовой папки макросов можем оказаться в папке, указанной в LastDirectory (см. "AkelPad.ini")
'
' Примеч.: 1) Для разбора результатов предпочтительнее моноширинный шрифт и отключенный режим переноса слов; 
' 2) Макрос содержит информацию о нажатой клавише, а не о букве, поэтому и "Ы" и "S", кодируются одинаково.
'    (отслеживается по комбинациям переключения раскладки)

Option Explicit

 Const ForReading = 1, ForWriting = 2, ForAppending = 8

 Dim dic_f, dic_k
 Dim WM_COMMAND, IDM_FILE_NEW, hMainWnd
 Dim i, fn_macro, fsi, fi_size, fi, VbCrLf
 Dim objDialog, intResult, pAkelDir
 Dim keyword, flag_key, myitem, myflag

'--------- СЛОВАРИ флагов и ключей ----------
' Словарь флагов (состояний нажато/отпущено)
Set dic_f = CreateObject("Scripting.Dictionary")
dic_f.add &H00, "{0x00}-{normal key was press    (down)}"
dic_f.add &H01, "{0x01}-{extended key was press  (down)}"
dic_f.add &H02, "{0x02}-{normal key was released   (up)}"
dic_f.add &H03, "{0x03}-{extended key was released (up)}"

' Словарь ключей
Set dic_k = CreateObject("Scripting.Dictionary")
dic_k.add &H00, "{0x00}-{Undefined}"
dic_k.add &H01, "{0x01}-{Left mouse button}"
dic_k.add &H02, "{0x02}-{Right mouse button}"
dic_k.add &H03, "{0x03}-{Control-break processing}"
dic_k.add &H04, "{0x04}-{Middle mouse button (three-button mouse)}"
dic_k.add &H05, "{0x05}-{X1 mouse button}"
dic_k.add &H06, "{0x06}-{X2 mouse button}"
dic_k.add &H07, "{0x07}-{Undefined}"
dic_k.add &H08, "{0x08}-{BACKSPACE key}"
dic_k.add &H09, "{0x09}-{TAB key}"
dic_k.add &H0A, "{0x0A}-{Reserved}"
dic_k.add &H0B, "{0x0B}-{Reserved}"
dic_k.add &H0C, "{0x0C}-{CLEAR key}"
dic_k.add &H0D, "{0x0D}-{ENTER key}"
dic_k.add &H0E, "{0x0E}-{Undefined}"
dic_k.add &H0F, "{0x0F}-{Undefined}"
dic_k.add &H10, "{0x10}-{SHIFT key}"
dic_k.add &H11, "{0x11}-{CTRL key}"
dic_k.add &H12, "{0x12}-{ALT key}"
dic_k.add &H13, "{0x13}-{PAUSE key}"
dic_k.add &H14, "{0x14}-{CAPS LOCK key}"
dic_k.add &H15, "{0x15}-{IME Kana mode | IME Hanguel mode (maintained for compatibility; use VK_HANGUL) | IME Hangul mode}"
dic_k.add &H16, "{0x16}-{Undefined}"
dic_k.add &H17, "{0x17}-{IME Junja mode}"
dic_k.add &H18, "{0x18}-{IME final mode}"
dic_k.add &H19, "{0x19}-{IME Hanja mode | IME Kanji mode}"
dic_k.add &H1A, "{0x1A}-{Undefined}"
dic_k.add &H1B, "{0x1B}-{ESC key}"
dic_k.add &H1C, "{0x1C}-{IME convert}"
dic_k.add &H1D, "{0x1D}-{IME nonconvert}"
dic_k.add &H1E, "{0x1E}-{IME accept}"
dic_k.add &H1F, "{0x1F}-{IME mode change request}"
dic_k.add &H20, "{0x20}-{SPACEBAR}"
dic_k.add &H21, "{0x21}-{PAGE UP key}"
dic_k.add &H22, "{0x22}-{PAGE DOWN key}"
dic_k.add &H23, "{0x23}-{END key}"
dic_k.add &H24, "{0x24}-{HOME key}"
dic_k.add &H25, "{0x25}-{LEFT ARROW key}"
dic_k.add &H26, "{0x26}-{UP ARROW key}"
dic_k.add &H27, "{0x27}-{RIGHT ARROW key}"
dic_k.add &H28, "{0x28}-{DOWN ARROW key}"
dic_k.add &H29, "{0x29}-{SELECT key}"
dic_k.add &H2A, "{0x2A}-{PRINT key}"
dic_k.add &H2B, "{0x2B}-{EXECUTE key}"
dic_k.add &H2C, "{0x2C}-{PRINT SCREEN key}"
dic_k.add &H2D, "{0x2D}-{INS key}"
dic_k.add &H2E, "{0x2E}-{DEL key}"
dic_k.add &H2F, "{0x2F}-{HELP key}"
dic_k.add &H30, "{0x30}-{0 key}"
dic_k.add &H31, "{0x31}-{1 key}"
dic_k.add &H32, "{0x32}-{2 key}"
dic_k.add &H33, "{0x33}-{3 key}"
dic_k.add &H34, "{0x34}-{4 key}"
dic_k.add &H35, "{0x35}-{5 key}"
dic_k.add &H36, "{0x36}-{6 key}"
dic_k.add &H37, "{0x37}-{7 key}"
dic_k.add &H38, "{0x38}-{8 key}"
dic_k.add &H39, "{0x39}-{9 key}"
dic_k.add &H3A, "{0x3A}-{Undefined}"
dic_k.add &H3B, "{0x3B}-{Undefined}"
dic_k.add &H3C, "{0x3C}-{Undefined}"
dic_k.add &H3D, "{0x3D}-{Undefined}"
dic_k.add &H3E, "{0x3E}-{Undefined}"
dic_k.add &H3F, "{0x3F}-{Undefined}"
dic_k.add &H40, "{0x40}-{Undefined}"
dic_k.add &H41, "{0x41}-{A key}"
dic_k.add &H42, "{0x42}-{B key}"
dic_k.add &H43, "{0x43}-{C key}"
dic_k.add &H44, "{0x44}-{D key}"
dic_k.add &H45, "{0x45}-{E key}"
dic_k.add &H46, "{0x46}-{F key}"
dic_k.add &H47, "{0x47}-{G key}"
dic_k.add &H48, "{0x48}-{H key}"
dic_k.add &H49, "{0x49}-{I key}"
dic_k.add &H4A, "{0x4A}-{J key}"
dic_k.add &H4B, "{0x4B}-{K key}"
dic_k.add &H4C, "{0x4C}-{L key}"
dic_k.add &H4D, "{0x4D}-{M key}"
dic_k.add &H4E, "{0x4E}-{N key}"
dic_k.add &H4F, "{0x4F}-{O key}"
dic_k.add &H50, "{0x50}-{P key}"
dic_k.add &H51, "{0x51}-{Q key}"
dic_k.add &H52, "{0x52}-{R key}"
dic_k.add &H53, "{0x53}-{S key}"
dic_k.add &H54, "{0x54}-{T key}"
dic_k.add &H55, "{0x55}-{U key}"
dic_k.add &H56, "{0x56}-{V key}"
dic_k.add &H57, "{0x57}-{W key}"
dic_k.add &H58, "{0x58}-{X key}"
dic_k.add &H59, "{0x59}-{Y key}"
dic_k.add &H5A, "{0x5A}-{Z key}"
dic_k.add &H5B, "{0x5B}-{Left Windows key (Microsoft® Natural® keyboard)}"
dic_k.add &H5C, "{0x5C}-{Right Windows key (Natural keyboard)}"
dic_k.add &H5D, "{0x5D}-{Applications key (Natural keyboard)}"
dic_k.add &H5E, "{0x5E}-{Reserved}"
dic_k.add &H5F, "{0x5F}-{Computer Sleep key}"
dic_k.add &H60, "{0x60}-{Numeric keypad 0 key}"
dic_k.add &H61, "{0x61}-{Numeric keypad 1 key}"
dic_k.add &H62, "{0x62}-{Numeric keypad 2 key}"
dic_k.add &H63, "{0x63}-{Numeric keypad 3 key}"
dic_k.add &H64, "{0x64}-{Numeric keypad 4 key}"
dic_k.add &H65, "{0x65}-{Numeric keypad 5 key}"
dic_k.add &H66, "{0x66}-{Numeric keypad 6 key}"
dic_k.add &H67, "{0x67}-{Numeric keypad 7 key}"
dic_k.add &H68, "{0x68}-{Numeric keypad 8 key}"
dic_k.add &H69, "{0x69}-{Numeric keypad 9 key}"
dic_k.add &H6A, "{0x6A}-{Multiply key}"
dic_k.add &H6B, "{0x6B}-{Add key}"
dic_k.add &H6C, "{0x6C}-{Separator key}"
dic_k.add &H6D, "{0x6D}-{Subtract key}"
dic_k.add &H6E, "{0x6E}-{Decimal key}"
dic_k.add &H6F, "{0x6F}-{Divide key}"
dic_k.add &H70, "{0x70}-{F1 key}"
dic_k.add &H71, "{0x71}-{F2 key}"
dic_k.add &H72, "{0x72}-{F3 key}"
dic_k.add &H73, "{0x73}-{F4 key}"
dic_k.add &H74, "{0x74}-{F5 key}"
dic_k.add &H75, "{0x75}-{F6 key}"
dic_k.add &H76, "{0x76}-{F7 key}"
dic_k.add &H77, "{0x77}-{F8 key}"
dic_k.add &H78, "{0x78}-{F9 key}"
dic_k.add &H79, "{0x79}-{F10 key}"
dic_k.add &H7A, "{0x7A}-{F11 key}"
dic_k.add &H7B, "{0x7B}-{F12 key}"
dic_k.add &H7C, "{0x7C}-{F13 key}"
dic_k.add &H7D, "{0x7D}-{F14 key}"
dic_k.add &H7E, "{0x7E}-{F15 key}"
dic_k.add &H7F, "{0x7F}-{F16 key}"
dic_k.add &H80, "{0x80}-{F17 key}"
dic_k.add &H81, "{0x81}-{F18 key}"
dic_k.add &H82, "{0x82}-{F19 key}"
dic_k.add &H83, "{0x83}-{F20 key}"
dic_k.add &H84, "{0x84}-{F21 key}"
dic_k.add &H85, "{0x85}-{F22 key}"
dic_k.add &H86, "{0x86}-{F23 key}"
dic_k.add &H87, "{0x87}-{F24 key}"
dic_k.add &H88, "{0x88}-{Unassigned}"
dic_k.add &H89, "{0x89}-{Unassigned}"
dic_k.add &H8A, "{0x8A}-{Unassigned}"
dic_k.add &H8B, "{0x8B}-{Unassigned}"
dic_k.add &H8C, "{0x8C}-{Unassigned}"
dic_k.add &H8D, "{0x8D}-{Unassigned}"
dic_k.add &H8E, "{0x8E}-{Unassigned}"
dic_k.add &H8F, "{0x8F}-{Unassigned}"
dic_k.add &H90, "{0x90}-{NUM LOCK key}"
dic_k.add &H91, "{0x91}-{SCROLL LOCK key}"
dic_k.add &H92, "{0x92}-{OEM specific}"
dic_k.add &H93, "{0x93}-{OEM specific}"
dic_k.add &H94, "{0x94}-{OEM specific}"
dic_k.add &H95, "{0x95}-{OEM specific}"
dic_k.add &H96, "{0x96}-{OEM specific}"
dic_k.add &H97, "{0x97}-{Unassigned}"
dic_k.add &H98, "{0x98}-{Unassigned}"
dic_k.add &H99, "{0x99}-{Unassigned}"
dic_k.add &H9A, "{0x9A}-{Unassigned}"
dic_k.add &H9B, "{0x9B}-{Unassigned}"
dic_k.add &H9C, "{0x9C}-{Unassigned}"
dic_k.add &H9D, "{0x9D}-{Unassigned}"
dic_k.add &H9E, "{0x9E}-{Unassigned}"
dic_k.add &H9F, "{0x9F}-{Unassigned}"
dic_k.add &HA0, "{0xA0}-{Left SHIFT key}"
dic_k.add &HA1, "{0xA1}-{Right SHIFT key}"
dic_k.add &HA2, "{0xA2}-{Left CONTROL key}"
dic_k.add &HA3, "{0xA3}-{Right CONTROL key}"
dic_k.add &HA4, "{0xA4}-{Left MENU key}"
dic_k.add &HA5, "{0xA5}-{Right MENU key}"
dic_k.add &HA6, "{0xA6}-{Browser Back key}"
dic_k.add &HA7, "{0xA7}-{Browser Forward key}"
dic_k.add &HA8, "{0xA8}-{Browser Refresh key}"
dic_k.add &HA9, "{0xA9}-{Browser Stop key}"
dic_k.add &HAA, "{0xAA}-{Browser Search key}"
dic_k.add &HAB, "{0xAB}-{Browser Favorites key}"
dic_k.add &HAC, "{0xAC}-{Browser Start and Home key}"
dic_k.add &HAD, "{0xAD}-{Volume Mute key}"
dic_k.add &HAE, "{0xAE}-{Volume Down key}"
dic_k.add &HAF, "{0xAF}-{Volume Up key}"
dic_k.add &HB0, "{0xB0}-{Next Track key}"
dic_k.add &HB1, "{0xB1}-{Previous Track key}"
dic_k.add &HB2, "{0xB2}-{Stop Media key}"
dic_k.add &HB3, "{0xB3}-{Play/Pause Media key}"
dic_k.add &HB4, "{0xB4}-{Start Mail key}"
dic_k.add &HB5, "{0xB5}-{Select Media key}"
dic_k.add &HB6, "{0xB6}-{Start Application 1 key}"
dic_k.add &HB7, "{0xB7}-{Start Application 2 key}"
dic_k.add &HB8, "{0xB8}-{Reserved}"
dic_k.add &HB9, "{0xB9}-{Reserved}"
dic_k.add &HBA, "{0xBA}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ';:' key}"
dic_k.add &HBB, "{0xBB}-{For any country/region, the '+' key}"
dic_k.add &HBC, "{0xBC}-{For any country/region, the ',' key}"
dic_k.add &HBD, "{0xBD}-{For any country/region, the '-' key}"
dic_k.add &HBE, "{0xBE}-{For any country/region, the '.' key}"
dic_k.add &HBF, "{0xBF}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '/?' key}"
dic_k.add &HC0, "{0xC0}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '`~' key}"
dic_k.add &HC1, "{0xC1}-{Reserved}"
dic_k.add &HC2, "{0xC2}-{Reserved}"
dic_k.add &HC3, "{0xC3}-{Reserved}"
dic_k.add &HC4, "{0xC4}-{Reserved}"
dic_k.add &HC5, "{0xC5}-{Reserved}"
dic_k.add &HC6, "{0xC6}-{Reserved}"
dic_k.add &HC7, "{0xC7}-{Reserved}"
dic_k.add &HC8, "{0xC8}-{Reserved}"
dic_k.add &HC9, "{0xC9}-{Reserved}"
dic_k.add &HCA, "{0xCA}-{Reserved}"
dic_k.add &HCB, "{0xCB}-{Reserved}"
dic_k.add &HCC, "{0xCC}-{Reserved}"
dic_k.add &HCD, "{0xCD}-{Reserved}"
dic_k.add &HCE, "{0xCE}-{Reserved}"
dic_k.add &HCF, "{0xCF}-{Reserved}"
dic_k.add &HD0, "{0xD0}-{Reserved}"
dic_k.add &HD1, "{0xD1}-{Reserved}"
dic_k.add &HD2, "{0xD2}-{Reserved}"
dic_k.add &HD3, "{0xD3}-{Reserved}"
dic_k.add &HD4, "{0xD4}-{Reserved}"
dic_k.add &HD5, "{0xD5}-{Reserved}"
dic_k.add &HD6, "{0xD6}-{Reserved}"
dic_k.add &HD7, "{0xD7}-{Reserved}"
dic_k.add &HD8, "{0xD8}-{Unassigned}"
dic_k.add &HD9, "{0xD9}-{Unassigned}"
dic_k.add &HDA, "{0xDA}-{Unassigned}"
dic_k.add &HDB, "{0xDB}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '[{' key}"
dic_k.add &HDC, "{0xDC}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '\|' key}"
dic_k.add &HDD, "{0xDD}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ']}' key}"
dic_k.add &HDE, "{0xDE}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the 'single-quote/double-quote' key}"
dic_k.add &HDF, "{0xDF}-{Used for miscellaneous characters; it can vary by keyboard.}"
dic_k.add &HE0, "{0xE0}-{Reserved}"
dic_k.add &HE1, "{0xE1}-{OEM specific}"
dic_k.add &HE2, "{0xE2}-{Either the angle bracket key or the backslash key on the RT 102-key keyboard}"
dic_k.add &HE3, "{0xE3}-{OEM specific}"
dic_k.add &HE4, "{0xE4}-{OEM specific}"
dic_k.add &HE5, "{0xE5}-{IME PROCESS key}"
dic_k.add &HE6, "{0xE6}-{OEM specific}"
dic_k.add &HE7, "{0xE7}-{Used to pass Unicode characters as if they were keystrokes.}"
dic_k.add &HE8, "{0xE8}-{Unassigned}"
dic_k.add &HE9, "{0xE9}-{OEM specific}"
dic_k.add &HEA, "{0xEA}-{OEM specific}"
dic_k.add &HEB, "{0xEB}-{OEM specific}"
dic_k.add &HEC, "{0xEC}-{OEM specific}"
dic_k.add &HED, "{0xED}-{OEM specific}"
dic_k.add &HEE, "{0xEE}-{OEM specific}"
dic_k.add &HEF, "{0xEF}-{OEM specific}"
dic_k.add &HF0, "{0xF0}-{OEM specific}"
dic_k.add &HF1, "{0xF1}-{OEM specific}"
dic_k.add &HF2, "{0xF2}-{OEM specific}"
dic_k.add &HF3, "{0xF3}-{OEM specific}"
dic_k.add &HF4, "{0xF4}-{OEM specific}"
dic_k.add &HF5, "{0xF5}-{OEM specific}"
dic_k.add &HF6, "{0xF6}-{Attn key}"
dic_k.add &HF7, "{0xF7}-{CrSel key}"
dic_k.add &HF8, "{0xF8}-{ExSel key}"
dic_k.add &HF9, "{0xF9}-{Erase EOF key}"
dic_k.add &HFA, "{0xFA}-{Play key}"
dic_k.add &HFB, "{0xFB}-{Zoom key}"
dic_k.add &HFC, "{0xFC}-{Reserved for future use}"
dic_k.add &HFD, "{0xFD}-{PA1 key}"
dic_k.add &HFE, "{0xFE}-{Clear key}"
'--------------------------------------

' Формируем путь к папке с макросами 
  pAkelDir = AkelPad.GetAkelDir(4)
  pAkelDir = """" & pAkelDir & "\Macros\" & """"

' Диалог выбора файла-макроса для декодирования
 Set objDialog = CreateObject("UserAccounts.CommonDialog")
 objDialog.InitialDir = pAkelDir
 objDialog.Filter = "Файлы macro (*.macro)|*.macro|Все файлы (*.*)|*.*"
 objDialog.FilterIndex = 1
 intResult = objDialog.ShowOpen
 If intResult = 0 Then
  Wscript.Quit      ' если файл-макрос не выбран, то выходим
 Else
  WM_COMMAND=273 
  IDM_FILE_NEW=4101      ' команда на создание нового файла
  hMainWnd=AkelPad.GetMainWnd()
  AkelPad.SendMessage hMainWnd, WM_COMMAND, IDM_FILE_NEW, 0
  VbCrLf = Chr(13) & Chr(10)
  fn_macro = objDialog.FileName
  Set fsi = CreateObject("Scripting.FileSystemObject")
  fi_size = fsi.GetFile(fn_macro).Size    ' получить размер файла-макроса
  AkelPad.ReplaceSel(fn_macro & VbCrLf & "Size: " & fi_size & " bytes (" & fi_size/8 & " keys)" & VbCrLf & String(40, "-") & VbCrLf)
  Set fi = fsi.OpenTextFile(fn_macro, ForReading, True)
  For i = 1 To fi_size Step 8     ' перебираем 8-байтные цепочки "XX-00-00-00-YY-00-00-00"
    keyword = Asc(fi.Read(1))
    fi.Skip(3)
    flag_key = Asc(fi.Read(1))
    myitem = dic_k.Item(keyword)
    myflag = dic_f.Item(flag_key)
    AkelPad.ReplaceSel "{" & myflag & myitem & "}" & VbCrLf
    fi.Skip(3)
  Next
  fi.Close()
  AkelPad.ReplaceSel(String(40, "-") & VbCrLf)
 End If

Offline
Posts: 267
Joined: Mon Mar 12, 2007 3:45 pm

Post by [Yustas.NeO] »

Набросал тут небольшой скриптик, который вычленяет в выделенном тексте (в том числе и в вертикальном выделении) все числа и подсчитывает их колличество и сумму.
Может кому пригодится... Если еще нет аналогов...


Code: Select all

	eval(AkelPad.ReadFile(AkelPad.GetAkelDir() + "\\AkelFiles\\Plugs\\Scripts\\" + "Neo!Common.JS"));	
//----------------------------------------------------------------------------




//	1 - 1 -2
//	1  -1              1.1 -1.                 -.1 .1                 -,1    1.1      ....

	sText = " " + GetSelectedOrAll() + " ";

	sText = sText.replace(/[^1234567890\-,.]/ig, " ");

	sText = sText.replace(/,/ig, ".");

	sText = sText.replace(/--/ig, "");
	sText = sText.replace(/- /ig, "");

	sText = sText.replace(/\.\./ig, "");
	sText = sText.replace(/ \. /ig, "");

	sText = sText.replace(/-\. /ig, "");
	sText = sText.replace(/-\./ig, "-0.");

	sText = sText.replace(/ - /ig, "");
	sText = sText.replace(/ \. /ig, "");


	sText = sText.replace(/  /ig, " ");

	sText = " " + sText + " ";


	aNumbers=sText.split(" ")

	iSum = 0;
	iCount = 0;
	for (iii=1;   iii < aNumbers.length;   ++iii)
	{
		if (aNumbers[iii] != "")
		{
			++iCount
			iSum = iSum + aNumbers[iii] * 1;
		}
	}
	AkelPad.MessageBox(AkelPad.GetMainWnd(), "Количество чисел: " + iCount + "\n" + "Сумма: " + iSum, "заголовок", 64 /*MB_ICONINFORMATION*/);



Скачать можно тут: ftp :// akelscripts:akelscripts @ ftp .hosting-rabbit .ru / NeO.Numbers.js



Использует "библиотеку" ftp :// akelscripts:akelscripts @ ftp .hosting-rabbit .ru / NeO!Common.js
Last edited by [Yustas.NeO] on Wed Jan 11, 2012 12:25 pm, edited 1 time in total.

Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

Извлечение русских\английских слов\цифр из выделенного текста

Code: Select all

' getWords.vbs
'========================   Описание   =====================================
' Извлечение русских\английских слов\цифр из выделенного текста
' (если ничего не выделено слова извлекаются из всего текста)
'=======================   Параметры  ======================================
' 1-й параметр
'    0 - или без параметров извлекаются русские слова
'    1 -  извлекаются английские слова
'    2 -  извлекаются цифры
' 2-й параметр - длина , меньше которой слова извлекаться не будут
'    0 - извлекаются все слова
'    3 - не будут извлекаться слова меньше 3-х символов
' 3-й параметр:
'    0 - не удалять дубликаты слов
'    1 - удалять дубликаты слов
' 4-й параметр:
'    0 - не переводить в нижний регистр
'    1 - переводить в нижний регистр
' 5-й параметр:
'    сортировать по убыванию (любой 5-й параметр)
'========================   Примеры   ======================================
' -"Извлечение русских слов в выделенном" Call("Scripts::Main", 1, "getWords.vbs")
' -"Извлечение английских слов в выделенном" Call("Scripts::Main", 1, "getWords.vbs",`"1"`)

' используется Functions.vbs, который следует положить в ...AkelFiles\Plugs\Scripts\Include\

' Автор:           Аверин Андрей
' Версия:          1.5 (14.05.2011 - 08.09.2012)
' Mail:            Averin-And@yandex.ru
' Site:            http://tc-image.3dn.ru/forum/9-372-1138-16-1333628985
' Site:            http://akelpad.sourceforge.net/forum/viewtopic.php?p=15206#p15206
'===========================================================================
N = 0 : K = 0 : Del = 0 : Ign = 0 : Abc = 0
With WScript
  Cnt = .Arguments.Count
  If Cnt > 0 Then
    N = .Arguments(0)
    If Cnt > 1 Then
      K = CInt(.Arguments(1))
      If Cnt > 2 Then
        Del = .Arguments(2)
        If Cnt > 3 Then
          Ign = .Arguments(3) : If Cnt > 4 Then Abc  = 1
        End If
      End If
    End If
  End If
End With

With AkelPad
  Text = .GetSelText()
  If Len(Text) = 0 Then Text = .GetTextRange(0, -1)
  If Len(Text) = 0 Then Wscript.Quit
  Call .Include("Functions.vbs")
  Select Case N
    Case 0 Text = RegExpReplace(Text, "[^а-яё\n]", Chr(32), 0, 1, 1)
    Case 1 Text = RegExpReplace(Text, "[^a-z\n]", Chr(32), 0, 1, 1)
    Case 2 Text = RegExpReplace(Text, "[\D]", Chr(32), 0, 1, 1)
  End Select
  Text = RegExpReplace(Text & Chr(32), "(" & Chr(32) & ")+", Chr(32) & Chr(32), 0, 1, 1)
  If Ign = 1 Then Text = LCase(Text)
  If K > 0 Then
    For ii = 1 To K
      point = String(ii, ".")
      Text = RegExpReplace(Text, "(" & Chr(32) & point & Chr(32) & ")+", "", 0, 1, 1)
    Next
  End If

  If Del = 1 Or Abc = 1 Then
    tArr = Split(Text, Chr(32))
    If Del = 1 Then tArr = DelDublicateArr(tArr)
    If Abc = 1 Then tArr = SelectingArrUp(tArr)
    Text = Join(tArr, Chr(13))
  Else
    Text = RegExpReplace(Text, "(" & Chr(32) & ")+", "\n", 0, 1, 1)
  End If

  If Len(Text) > 0 Then
    Call CreateNewTab
    Call SetRedraw(.GetEditWnd(), False)
    Call .ReplaceSel(Text)
    Call .SendMessage(.GetEditWnd(), 3087, False, 0)
    Call .SendMessage(.GetEditWnd(), 3079, 0, 0)
    Call .SetSel(0, 0)
    Call SetRedraw(.GetEditWnd(), True)
  Else
    CreateObject("WScript.Shell").Popup "Искомых слов не найдено!", 1, "Результат", 64
  End If
End With



Code: Select all

 "Извлечь слова из выделенного текста"
  {
  -"Извлечь все русские слова" Call("Scripts::Main", 1, "getWords.vbs") Icon("%a\AkelPadImage.dll",551)
  -"Извлечь все русские слова -дубликаты" Call("Scripts::Main", 1, "getWords.vbs", `"0" "0" "1"`) Icon("%a\AkelPadImage.dll",551)
  -"Извлечь все русские слова -дубл.+нижн регистр." Call("Scripts::Main", 1, "getWords.vbs", `"0" "0" "1" "1"`) Icon("%a\AkelPadImage.dll",551)
  SEPARATOR
  -"Извлечение русских слов >2 символов" Call("Scripts::Main", 1, "getWords.vbs", `"0" "2"`) Icon("%a\AkelPadImage.dll",551)
  -"Извлечь русские слова >2 симв.-дубл." Call("Scripts::Main", 1, "getWords.vbs", `"0" "2" "1"`) Icon("%a\AkelPadImage.dll",551)
  -"Извлечь русские слова >2 симв.-дубл.+нижн регистр." Call("Scripts::Main", 1, "getWords.vbs", `"0" "2" "1" "1" "1"`) Icon("%a\AkelPadImage.dll",551)
  SEPARATOR
  SEPARATOR
    -"Извлечь все англ. слова" Call("Scripts::Main", 1, "getWords.vbs", "1") Icon("%a\AkelPadImage.dll",550)
  -"Извлечь все англ. слова -дубликаты" Call("Scripts::Main", 1, "getWords.vbs", `"1" "0" "1"`) Icon("%a\AkelPadImage.dll",550)
  -"Извлечь все англ. слова -дубл.+нижн регистр." Call("Scripts::Main", 1, "getWords.vbs", `"1" "0" "1" "1"`) Icon("%a\AkelPadImage.dll",550)
  SEPARATOR
  -"Извлечь англ. слова >2 символов" Call("Scripts::Main", 1, "getWords.vbs", `"1" "2"`) Icon("%a\AkelPadImage.dll",550)
  -"Извлечь англ. слова >2 симв.-дубл." Call("Scripts::Main", 1, "getWords.vbs", `"1" "2" "1"`) Icon("%a\AkelPadImage.dll",550)
  -"Извлечь англ. слова >2 симв.-дубл.+нижн регистр." Call("Scripts::Main", 1, "getWords.vbs", `"1" "2" "1" "1" "1"`) Icon("%a\AkelPadImage.dll",550)
  SEPARATOR
  SEPARATOR
  -"Извлечь все цифры" Call("Scripts::Main", 1, "getWords.vbs",`"2"`) Icon("%a\AkelPadImage.dll",917)
  -"Извлечь все цифры +сорт.-дубликаты" Call("Scripts::Main", 1, "getWords.vbs",`"2" "0" "1" "0" "1"`) Icon("%a\AkelPadImage.dll",917)
  }


Используется: Functions.vbs
Last edited by Andrey_A_A on Thu Sep 13, 2012 2:26 am, edited 2 times in total.

Offline
Posts: 2247
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

Merges list of words defined in Coder's syntax files with SpellCheck's whitelists.

Code: Select all

// === [coder2wl.js] ===
// Panych Y.W. AKA FeyFre(c) 2011-2012
// Parses all existing Coder syntax files, merging context of Words:
// section with correspondent whitelist of SpellCheck plugin.
// 
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=15212#p15212
//	v0.99.2 2012.15.01
//	v0.99.1
//
// Example:
//	Call("Scripts::Main", 1, "coder2wl.js")
//

var ADTYPE_PLUGS	= 4;

var plugs = AkelPad.GetAkelDir(ADTYPE_PLUGS);
var coder = plugs+"\\coder";
var white = ";;\n;;\n;; Generated by coder2wl.js\n;;\n;;\n"

var fso = new ActiveXObject("Scripting.FileSystemObject");
var fcoder = fso.GetFolder(coder);
var coders = new Enumerator(fcoder.files);
var files = 0;
for(;!coders.atEnd();coders.moveNext())
{
	var name = ""+coders.item();
	if(name.match(/(\.coder)$/gi))
	{
		var temp = parse_coder_file(name);
		if(temp != "")
		{
			white += temp;
			files++;
		}
	}
	
}
if(files>0)
{
	//! Breed new data to spellcheck
	AkelPad.Call("SpellCheck::Background",1,white);
	//! Or copy to clipboard to be inserted to permanent storage(.spellcheck file)
	//AkelPad.SetClipboardText(white);
}


function parse_coder_file(file)
{
	var text = AkelPad.ReadFile(file);
	{
		var arr = file.split("\\");
		if(arr.length>0)
			file = arr[arr.length-1];
	}
	if(!text) return "";
	var exts=[];
	var words=[];
	var lines = text.split("\r\n");
	var pos = 0, cnt = lines.length;
	var	st_find_extensions=1,
		st_find_font=2,
		st_find_words=3,
		st_find_foldpanel=4;
	var st = st_find_extensions;
	var n=0;
	while(pos<cnt)
	{
		var line = ""+lines[pos]+"";
		if(st == st_find_extensions)
		{
			var m = line.match(/^Files:$/gi);
			if(m)
			{
				st = st_find_font;
			}
		}
		else if(st == st_find_font)
		{
			var m = line.match(/^font:$/i);
			if(m)
			{
				st = st_find_words;
				if(exts.length ==0) break;
			}
			else
			{
				if(!line.match(/^((;.*)|(\s*))$/gi))
				{
					var ttt = line.split("*.");
					if(ttt.length>0)
					{
						var e = ttt[ttt.length-1];
						if(	e.indexOf('.')==-1 &&
							e.indexOf('*')==-1 &&
							e.indexOf('?')==-1)
							exts.push(e);
					}
				}
			}
		}
		else if(st == st_find_words)
		{
			var m = line.match(/^words:$/gi);
			if(m)
			{
				st = st_find_foldpanel;
			}
		}
		else if(st == st_find_foldpanel)
		{
			if(line.match(/^foldpanel:$/gi))
			{
				break;
			}
			else if(!line.match(/^((;.*)|(\s*))$/gi))
			{
				var mm = line.match(/^\s*(\$\{[^}]+\}|\d+)\s+(\$\{[^}]+\}|\d+)\s+(\$\{[^}]+\}|\d+)\s+(\$\{[^}]+\}|\d+)\s+(.*)\s*$/gi);
				if(mm)
				{
					var splits = mm[0].split("\t");
					var opt=[];
					for(var spl in splits)
						opt = opt.concat(splits[spl].split(' '));
					if(!isNaN(opt[0]))
					{
						if(parseInt(opt[0])%2==1)
							words.push({ignorecase:false,word:opt[4]});
						else
							words.push({ignorecase:true,word:opt[4]});
					}
					else
					{
						words.push({ignorecase:true,word:opt[4]});
					}
				}
			}
		} else {"not reached";}
		pos++;
	}
	if(exts.length ==0) return "";
	if(words.length ==0) return "";
	result = ";; Generated from "+file+"\n";
	result += "+"+exts.join("\n+")+"\n";
	var pind,pair;
	for(pind in words)
	{
		pair = words[pind];
		if(pair.ignorecase==true) {result +="|";}
		result+=pair.word+"\n";
	}
	result += "-"+exts.join("\n-")+"\n";
	result += ";;End of "+file+"\n";
	return result;
}

Updated for coder 7.3
Last edited by FeyFre on Sun Jan 15, 2012 1:59 pm, edited 2 times in total.

Offline
Posts: 2247
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

Validates selected XML fragment or entire text. <<DOWNLOAD>>

Code: Select all

///Validates selected XML fragment or whole document, pointing potential error place 
// https://github.com/FeyFre/akelpad-customisations/blob/scripts/XMLValidator.js 
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=15256#p15256 
// Version: 2.0 (2016.02.28) by VladSh 
// Version: 1.9 (2016.02.24) by Skif_off 
// Version: 1.8 (2015.04.10) by VladSh 
// Version: 1.7 (2014.12.01) by VladSh 
// Version: 1.6 (2012.10.24) by VladSh 
// Version: 1.0 (2011.10.25) (c) Panych Y.W. aka FeyFre 
// 
// Arguments: 
//   keep: 
//      • [0 | без параметра] - не сохранять исходное выделение, устанавливая курсор в место ошибки 
//      • 1 - сохранять исходное выделение; если выделения нет, то курсор также будет установлен в место ошибки 
//   msgOpts - параметры вывода сообщений: 
//      • [0 | без параметра] - в диалоговое окно; 
//      • перечень кодов сообщений через запятую, которые выводить в панели вывода Log-плагина: 
//         1 - все сообщения/ошибки; 
//         16 - критическая ошибка xml-парсера; 
//         48 - ошибка xml-синтаксиса (можно выводить только её, т.к. можно переходить на место ошибки); 
//         64 - сообщение об успешной проверке валидации 
//   lClose - параметры закрытия панели Log-плагина (при msgOpts=1 игнорируется): 
//      • [0 | без параметра] - не закрывать (в панели может остаться нужный текст, в т.ч. и от других вкладок программы); 
//      • 1 - закрывать только при успешной проверке валидации; 
//      • 2 - закрывать всегда (только при msgOpts=0) 
//   append - параметры вывода в панель Log-плагина: 
//      • [0 | без параметра] - очищать содержимое панели перед записью 
//      • 1, 2 - не очищать (см. Log-Rus.txt -> вызов с кодом 4 -> пареметр "APPEND") 
// 
// Examples: 
//    Call("Scripts::Main", 1, "XMLValidator.js")                - вывод в обычное диалоговое сообщение 
//    Call("Scripts::Main", 1, "XMLValidator.js", `-msgOpts=1`) - вывод всех сообщений в панель Log-плагина 
//    Call("Scripts::Main", 1, "XMLValidator.js", `-msgOpts=48 -lClose=1`) - вывод в панель Log-плагина только сообщений об ошибках xml-синтаксиса с закрытием панели при успешной проверке валидации 
//    Call("Scripts::Main", 1, "XMLValidator.js", `-msgOpts=48 -append=1`) - вывод в панель Log-плагина только сообщений об ошибках xml-синтаксиса с добавлением их к уже существующим в панели сообщениям 

var parserName = "msxml2.DOMDocument"; 
var xml = new ActiveXObject(parserName); 
try { 
   xml.async = false; 
   xml.validateOnParse = true; 
   xml.resolveExternals = false; 
} catch (e) { 
   output("Internal parser " + parserName + " error: " + e.description, 16 /*MB_ICONSTOP*/); 
   WScript.Quit(); 
} 

var text = AkelPad.GetSelText(); 
var selection; 
if (!text) { 
   text = AkelPad.GetTextRange(0, -1); 
   selection = false; 
} else { 
   selection = true; 
} 

var t = new Date(); 
var extInfo = t.toLocaleTimeString() + " " + (AkelPad.GetEditFile(0) || "*") + " -> "; 

xml.loadXML(text); 
if (xml.parseError.errorCode !== 0) { 
   var err = xml.parseError; 
   if (!selection || !AkelPad.GetArgValue("keep", 0)) { 
      var np = Math.min(AkelPad.GetSelStart(), AkelPad.GetSelEnd()); 
      if (selection) 
         np += err.filepos; 
      else 
         np = err.filepos; 
      AkelPad.SetSel(np, np); 
   } 
   var errInfo = extInfo + "XML validation error:\r(" + err.line + "," + err.linepos + ")\t\t" + err.reason; 
   output(errInfo, 48 /*MB_ICONEXCLAMATION*/); 
} else { 
   output(extInfo + "XML fragment is valid.\r", 64 /*MB_ICONINFORMATION*/); 
} 

function output(msg, nIcon /*MB_ICON...*/) { 
   var slog = AkelPad.GetArgValue("msgOpts", "0"); 
   if (slog == "1" || (slog != "0" && slog.indexOf(nIcon.toString()) != -1)) { 
      var fLogOutput = "Log::Output"; 
      if (AkelPad.Call(fLogOutput, 1, "", "", "^\\((\\d+),(\\d+)\\)", "/GOTOLINE=\\1:\\2") != -1) { 
         var nAppend = AkelPad.GetArgValue("append", 0); 
         AkelPad.Call(fLogOutput, 4, msg, -1, nAppend); 
      } 
   } 
   else { 
      var lClose = AkelPad.GetArgValue("lClose", 0); 
      if ((lClose == 1 && nIcon == 64) || lClose == 2) 
         AkelPad.Call("Log::Output", 6); 
      AkelPad.MessageBox(AkelPad.GetEditWnd(), msg, WScript.ScriptName, nIcon); 
   } 
}
Last edited by FeyFre on Sun Feb 28, 2016 9:41 am, edited 7 times in total.

Offline
Posts: 874
Joined: Sat Jan 16, 2010 2:03 pm

Post by opk44 »

ENG: converter, that migrate macro to a script (with limitations!).
РУС: скрипт преобразующий ранее записанные макросы в последовательности SendKeys (с ограничениями!) для использования в скриптах.

Code: Select all

' (c) opk44 2011
' version 0.1.4 - 2011-11-11
' http://akelpad.sourceforge.net/forum/viewtopic.php?p=15365#p15365
'
' Использовано "Appendix A - Virtual Key codes" AkelPad Plugins Manual (Surveyor)
' 
' Usage:
' Call("Scripts::Main", 1, "Macro2SendKeys.vbs")

' Known BUGS & LIMITATIONS: 
' 1) Не умеет отслеживать переключения раскладки RUS/LAT (комбинация только модификаторов
'   {Ctrl}+{Shift} или {Alt}+{Shift})
' 2) Диалог выбора файлов работает только в Win2000/WinXP (на Vista/Win7 не проверялось, 
'    но, по-видимому, работать не будет)
' 3) Инициализация директории в диалоге выбора файла-макроса иногда не срабатывает 
'    (вместо указанной  стартовой папки макросов можем оказаться в папке, указанной 
'    в LastDirectory (см. "AkelPad.ini")

Option Explicit

' режимы открытия файла (используется только "для чтения")
Const ForReading = 1, ForWriting = 2, ForAppending = 8
' индексы колонок хранения текущего состояния клавиш (массив "myarr")
Const alt_key_status = 0, ctrl_key_status = 1, shift_key_status = 2, other_key_status = 3

Dim myarr(999, 3)  ' массив для SendKeys-последовательностей (<= 1000, если нужно - увеличьте!).
Dim allkeys  ' для предварительной грубой оценки размера макроса
Dim first_index, CountKeyDown
Dim dic_f, dic_k  ' Словари флагов и ключей
Dim WM_COMMAND, IDM_FILE_NEW, hMainWnd
Dim i, j, k  ' Счетчики
Dim fn_macro, fsi, fi_size, fi, VbCrLf
Dim objDialog, intResult, pAkelDir
Dim keyword, flag_key, myitem
Dim shbl_head_vbs, shbl_head_js, shbl_sk
Dim strMsg

'--------- Словари флагов и ключей ----------
' Словарь флагов (состояний нажато/отпущено)
Set dic_f = CreateObject("Scripting.Dictionary")
dic_f.add &H00, "{0x00}-{normal key was press    (down)}"
dic_f.add &H01, "{0x01}-{extended key was press  (down)}"
dic_f.add &H02, "{0x02}-{normal key was released   (up)}"
dic_f.add &H03, "{0x03}-{extended key was released (up)}"

' Словарь ключей
Set dic_k = CreateObject("Scripting.Dictionary")
dic_k.add &H00, "x00" '"{0x00}-{Undefined}"
dic_k.add &H01, "x01" '"{0x01}-{Left mouse button}"
dic_k.add &H02, "x02" '"{0x02}-{Right mouse button}"
dic_k.add &H03, "x03" '"{0x03}-{Control-break processing}"
dic_k.add &H04, "x04" '"{0x04}-{Middle mouse button (three-button mouse)}"
dic_k.add &H05, "x05" '"{0x05}-{X1 mouse button}"
dic_k.add &H06, "x06" '"{0x06}-{X2 mouse button}"
dic_k.add &H07, "x07" '"{0x07}-{Undefined}"
dic_k.add &H08, "{BACKSPACE}" '"{0x08}-{BACKSPACE key}"
dic_k.add &H09, "{TAB}" '"{0x09}-{TAB key}"
dic_k.add &H0A, "x0A" '"{0x0A}-{Reserved}"
dic_k.add &H0B, "x0B" '"{0x0B}-{Reserved}"
dic_k.add &H0C, "CLEAR" '"{0x0C}-{CLEAR key}"
dic_k.add &H0D, "{ENTER}" '"{0x0D}-{ENTER key}"
dic_k.add &H0E, "x0E" '"{0x0E}-{Undefined}"
dic_k.add &H0F, "x0F" '"{0x0F}-{Undefined}"
dic_k.add &H10, "+" '"{0x10}-{SHIFT key}"
dic_k.add &H11, "^" '"{0x11}-{CTRL key}"
dic_k.add &H12, "%" '"{0x12}-{ALT key}"
dic_k.add &H13, "PAUSE" '"{0x13}-{PAUSE key}"
dic_k.add &H14, "{CAPSLOCK}" '"{0x14}-{CAPS LOCK key}"
dic_k.add &H15, "x15" '"{0x15}-{IME Kana mode | IME Hanguel mode (maintained for compatibility; use VK_HANGUL) | IME Hangul mode}"
dic_k.add &H16, "x16" '"{0x16}-{Undefined}"
dic_k.add &H17, "x17" '"{0x17}-{IME Junja mode}"
dic_k.add &H18, "x18" '"{0x18}-{IME final mode}"
dic_k.add &H19, "x19" '"{0x19}-{IME Hanja mode | IME Kanji mode}"
dic_k.add &H1A, "x1A" '"{0x1A}-{Undefined}"
dic_k.add &H1B, "{ESC}" '"{0x1B}-{ESC key}"
dic_k.add &H1C, "x1C" '"{0x1C}-{IME convert}"
dic_k.add &H1D, "x1D" '"{0x1D}-{IME nonconvert}"
dic_k.add &H1E, "x1E" '"{0x1E}-{IME accept}"
dic_k.add &H1F, "x1F" '"{0x1F}-{IME mode change request}"
dic_k.add &H20, " " '"{0x20}-{SPACEBAR}"
dic_k.add &H21, "{PGUP}" '"{0x21}-{PAGE UP key}"
dic_k.add &H22, "{PGDN}" '"{0x22}-{PAGE DOWN key}"
dic_k.add &H23, "{END}" '"{0x23}-{END key}"
dic_k.add &H24, "{HOME}" '"{0x24}-{HOME key}"
dic_k.add &H25, "{LEFT}" '"{0x25}-{LEFT ARROW key}"
dic_k.add &H26, "{UP}" '"{0x26}-{UP ARROW key}"
dic_k.add &H27, "{RIGHT}" '"{0x27}-{RIGHT ARROW key}"
dic_k.add &H28, "{DOWN}" '"{0x28}-{DOWN ARROW key}"
dic_k.add &H29, "SELECT" '"{0x29}-{SELECT key}"
dic_k.add &H2A, "PRINT" '"{0x2A}-{PRINT key}"
dic_k.add &H2B, "EXECUTE" '"{0x2B}-{EXECUTE key}"
dic_k.add &H2C, "{PRTSC}" '"{0x2C}-{PRINT SCREEN key}"
dic_k.add &H2D, "{INS}" '"{0x2D}-{INS key}"
dic_k.add &H2E, "{DEL}" '"{0x2E}-{DEL key}"
dic_k.add &H2F, "{HELP}" '"{0x2F}-{HELP key}"
dic_k.add &H30, "0" '"{0x30}-{0 key}"
dic_k.add &H31, "1" '"{0x31}-{1 key}"
dic_k.add &H32, "2" '"{0x32}-{2 key}"
dic_k.add &H33, "3" '"{0x33}-{3 key}"
dic_k.add &H34, "4" '"{0x34}-{4 key}"
dic_k.add &H35, "5" '"{0x35}-{5 key}"
dic_k.add &H36, "6" '"{0x36}-{6 key}"
dic_k.add &H37, "7" '"{0x37}-{7 key}"
dic_k.add &H38, "8" '"{0x38}-{8 key}"
dic_k.add &H39, "9" '"{0x39}-{9 key}"
dic_k.add &H3A, "x3A" '"{0x3A}-{Undefined}"
dic_k.add &H3B, "x3B" '"{0x3B}-{Undefined}"
dic_k.add &H3C, "x3C" '"{0x3C}-{Undefined}"
dic_k.add &H3D, "x3D" '"{0x3D}-{Undefined}"
dic_k.add &H3E, "x3E" '"{0x3E}-{Undefined}"
dic_k.add &H3F, "x3F" '"{0x3F}-{Undefined}"
dic_k.add &H40, "x40" '"{0x40}-{Undefined}"
dic_k.add &H41, "a" '"{0x41}-{A key}"
dic_k.add &H42, "b" '"{0x42}-{B key}"
dic_k.add &H43, "c" '"{0x43}-{C key}"
dic_k.add &H44, "d" '"{0x44}-{D key}"
dic_k.add &H45, "e" '"{0x45}-{E key}"
dic_k.add &H46, "f" '"{0x46}-{F key}"
dic_k.add &H47, "g" '"{0x47}-{G key}"
dic_k.add &H48, "h" '"{0x48}-{H key}"
dic_k.add &H49, "i" '"{0x49}-{I key}"
dic_k.add &H4A, "j" '"{0x4A}-{J key}"
dic_k.add &H4B, "k" '"{0x4B}-{K key}"
dic_k.add &H4C, "l" '"{0x4C}-{L key}"
dic_k.add &H4D, "m" '"{0x4D}-{M key}"
dic_k.add &H4E, "n" '"{0x4E}-{N key}"
dic_k.add &H4F, "o" '"{0x4F}-{O key}"
dic_k.add &H50, "p" '"{0x50}-{P key}"
dic_k.add &H51, "q" '"{0x51}-{Q key}"
dic_k.add &H52, "r" '"{0x52}-{R key}"
dic_k.add &H53, "s" '"{0x53}-{S key}"
dic_k.add &H54, "t" '"{0x54}-{T key}"
dic_k.add &H55, "u" '"{0x55}-{U key}"
dic_k.add &H56, "v" '"{0x56}-{V key}"
dic_k.add &H57, "w" '"{0x57}-{W key}"
dic_k.add &H58, "x" '"{0x58}-{X key}"
dic_k.add &H59, "y" '"{0x59}-{Y key}"
dic_k.add &H5A, "z" '"{0x5A}-{Z key}"
dic_k.add &H5B, "x5B" '"{0x5B}-{Left Windows key (Microsoft® Natural® keyboard)}"
dic_k.add &H5C, "x5C" '"{0x5C}-{Right Windows key (Natural keyboard)}"
dic_k.add &H5D, "x5D" '"{0x5D}-{Applications key (Natural keyboard)}"
dic_k.add &H5E, "x5E" '"{0x5E}-{Reserved}"
dic_k.add &H5F, "x5F" '"{0x5F}-{Computer Sleep key}"
dic_k.add &H60, "x60" '"{0x60}-{Numeric keypad 0 key}"
dic_k.add &H61, "x61" '"{0x61}-{Numeric keypad 1 key}"
dic_k.add &H62, "x62" '"{0x62}-{Numeric keypad 2 key}"
dic_k.add &H63, "x63" '"{0x63}-{Numeric keypad 3 key}"
dic_k.add &H64, "x64" '"{0x64}-{Numeric keypad 4 key}"
dic_k.add &H65, "x65" '"{0x65}-{Numeric keypad 5 key}"
dic_k.add &H66, "x66" '"{0x66}-{Numeric keypad 6 key}"
dic_k.add &H67, "x67" '"{0x67}-{Numeric keypad 7 key}"
dic_k.add &H68, "x68" '"{0x68}-{Numeric keypad 8 key}"
dic_k.add &H69, "x69" '"{0x69}-{Numeric keypad 9 key}"
dic_k.add &H6A, "x6A" '"{0x6A}-{Multiply key}"
dic_k.add &H6B, "{+}" '"{0x6B}-{Add key}"
dic_k.add &H6C, "x6C" '"{0x6C}-{Separator key}"
dic_k.add &H6D, "-" '"{0x6D}-{Subtract key}"
dic_k.add &H6E, "x6E" '"{0x6E}-{Decimal key}"
dic_k.add &H6F, "x6F" '"{0x6F}-{Divide key}"
dic_k.add &H70, "{F1}" '"{0x70}-{F1 key}"
dic_k.add &H71, "{F2}" '"{0x71}-{F2 key}"
dic_k.add &H72, "{F3}" '"{0x72}-{F3 key}"
dic_k.add &H73, "{F4}" '"{0x73}-{F4 key}"
dic_k.add &H74, "{F5}" '"{0x74}-{F5 key}"
dic_k.add &H75, "{F6}" '"{0x75}-{F6 key}"
dic_k.add &H76, "{F7}" '"{0x76}-{F7 key}"
dic_k.add &H77, "{F8}" '"{0x77}-{F8 key}"
dic_k.add &H78, "{F9}" '"{0x78}-{F9 key}"
dic_k.add &H79, "{F10}" '"{0x79}-{F10 key}"
dic_k.add &H7A, "{F11}" '"{0x7A}-{F11 key}"
dic_k.add &H7B, "{F12}" '"{0x7B}-{F12 key}"
dic_k.add &H7C, "{F13}" '"{0x7C}-{F13 key}"
dic_k.add &H7D, "{F14}" '"{0x7D}-{F14 key}"
dic_k.add &H7E, "{F15}" '"{0x7E}-{F15 key}"
dic_k.add &H7F, "{F16}" '"{0x7F}-{F16 key}"
dic_k.add &H80, "{F17}" '"{0x80}-{F17 key}"
dic_k.add &H81, "{F18}" '"{0x81}-{F18 key}"
dic_k.add &H82, "{F19}" '"{0x82}-{F19 key}"
dic_k.add &H83, "{F20}" '"{0x83}-{F20 key}"
dic_k.add &H84, "{F21}" '"{0x84}-{F21 key}"
dic_k.add &H85, "{F22}" '"{0x85}-{F22 key}"
dic_k.add &H86, "{F23}" '"{0x86}-{F23 key}"
dic_k.add &H87, "{F24}" '"{0x87}-{F24 key}"
dic_k.add &H88, "x88" '"{0x88}-{Unassigned}"
dic_k.add &H89, "x89" '"{0x89}-{Unassigned}"
dic_k.add &H8A, "x8A" '"{0x8A}-{Unassigned}"
dic_k.add &H8B, "x8B" '"{0x8B}-{Unassigned}"
dic_k.add &H8C, "x8C" '"{0x8C}-{Unassigned}"
dic_k.add &H8D, "x8D" '"{0x8D}-{Unassigned}"
dic_k.add &H8E, "x8E" '"{0x8E}-{Unassigned}"
dic_k.add &H8F, "x8F" '"{0x8F}-{Unassigned}"
dic_k.add &H90, "{NUMLOCK}" '"{0x90}-{NUM LOCK key}"
dic_k.add &H91, "{SCROLLLOCK}" '"{0x91}-{SCROLL LOCK key}"
dic_k.add &H92, "x92" '"{0x92}-{OEM specific}"
dic_k.add &H93, "x93" '"{0x93}-{OEM specific}"
dic_k.add &H94, "x94" '"{0x94}-{OEM specific}"
dic_k.add &H95, "x95" '"{0x95}-{OEM specific}"
dic_k.add &H96, "x96" '"{0x96}-{OEM specific}"
dic_k.add &H97, "x97" '"{0x97}-{Unassigned}"
dic_k.add &H98, "x98" '"{0x98}-{Unassigned}"
dic_k.add &H99, "x99" '"{0x99}-{Unassigned}"
dic_k.add &H9A, "x9A" '"{0x9A}-{Unassigned}"
dic_k.add &H9B, "x9B" '"{0x9B}-{Unassigned}"
dic_k.add &H9C, "x9C" '"{0x9C}-{Unassigned}"
dic_k.add &H9D, "x9D" '"{0x9D}-{Unassigned}"
dic_k.add &H9E, "x9E" '"{0x9E}-{Unassigned}"
dic_k.add &H9F, "x9F" '"{0x9F}-{Unassigned}"
dic_k.add &HA0, "Left_SHIFT" '"{0xA0}-{Left SHIFT key}"
dic_k.add &HA1, "Right_SHIFT" '"{0xA1}-{Right SHIFT key}"
dic_k.add &HA2, "Left_CONTROL" '"{0xA2}-{Left CONTROL key}"
dic_k.add &HA3, "Right_CONTROL" '"{0xA3}-{Right CONTROL key}"
dic_k.add &HA4, "Left_MENU" '"{0xA4}-{Left MENU key}"
dic_k.add &HA5, "Right_MENU" '"{0xA5}-{Right MENU key}"
dic_k.add &HA6, "xA6" '"{0xA6}-{Browser Back key}"
dic_k.add &HA7, "xA7" '"{0xA7}-{Browser Forward key}"
dic_k.add &HA8, "xA8" '"{0xA8}-{Browser Refresh key}"
dic_k.add &HA9, "xA9" '"{0xA9}-{Browser Stop key}"
dic_k.add &HAA, "xAA" '"{0xAA}-{Browser Search key}"
dic_k.add &HAB, "xAB" '"{0xAB}-{Browser Favorites key}"
dic_k.add &HAC, "xAC" '"{0xAC}-{Browser Start and Home key}"
dic_k.add &HAD, "xAD" '"{0xAD}-{Volume Mute key}"
dic_k.add &HAE, "xAE" '"{0xAE}-{Volume Down key}"
dic_k.add &HAF, "xAF" '"{0xAF}-{Volume Up key}"
dic_k.add &HB0, "xB0" '"{0xB0}-{Next Track key}"
dic_k.add &HB1, "xB1" '"{0xB1}-{Previous Track key}"
dic_k.add &HB2, "xB2" '"{0xB2}-{Stop Media key}"
dic_k.add &HB3, "xB3" '"{0xB3}-{Play/Pause Media key}"
dic_k.add &HB4, "xB4" '"{0xB4}-{Start Mail key}"
dic_k.add &HB5, "xB5" '"{0xB5}-{Select Media key}"
dic_k.add &HB6, "xB6" '"{0xB6}-{Start Application 1 key}"
dic_k.add &HB7, "xB7" '"{0xB7}-{Start Application 2 key}"
dic_k.add &HB8, "xB8" '"{0xB8}-{Reserved}"
dic_k.add &HB9, "xB9" '"{0xB9}-{Reserved}"
dic_k.add &HBA, ";" '"{0xBA}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ';:' key}"
dic_k.add &HBB, "{+}" '"{0xBB}-{For any country/region, the '+' key}"
dic_k.add &HBC, "," '"{0xBC}-{For any country/region, the ',' key}"
dic_k.add &HBD, "-" '"{0xBD}-{For any country/region, the '-' key}"
dic_k.add &HBE, "." '"{0xBE}-{For any country/region, the '.' key}"
dic_k.add &HBF, "/" '"{0xBF}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '/?' key}"
dic_k.add &HC0, "{~}" '"{0xC0}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '`~' key}"
dic_k.add &HC1, "xC1" '"{0xC1}-{Reserved}"
dic_k.add &HC2, "xC2" '"{0xC2}-{Reserved}"
dic_k.add &HC3, "xC3" '"{0xC3}-{Reserved}"
dic_k.add &HC4, "xC4" '"{0xC4}-{Reserved}"
dic_k.add &HC5, "xC5" '"{0xC5}-{Reserved}"
dic_k.add &HC6, "xC6" '"{0xC6}-{Reserved}"
dic_k.add &HC7, "xC7" '"{0xC7}-{Reserved}"
dic_k.add &HC8, "xC8" '"{0xC8}-{Reserved}"
dic_k.add &HC9, "xC9" '"{0xC9}-{Reserved}"
dic_k.add &HCA, "xCA" '"{0xCA}-{Reserved}"
dic_k.add &HCB, "xCB" '"{0xCB}-{Reserved}"
dic_k.add &HCC, "xCC" '"{0xCC}-{Reserved}"
dic_k.add &HCD, "xCD" '"{0xCD}-{Reserved}"
dic_k.add &HCE, "xCE" '"{0xCE}-{Reserved}"
dic_k.add &HCF, "xCF" '"{0xCF}-{Reserved}"
dic_k.add &HD0, "xD0" '"{0xD0}-{Reserved}"
dic_k.add &HD1, "xD1" '"{0xD1}-{Reserved}"
dic_k.add &HD2, "xD2" '"{0xD2}-{Reserved}"
dic_k.add &HD3, "xD3" '"{0xD3}-{Reserved}"
dic_k.add &HD4, "xD4" '"{0xD4}-{Reserved}"
dic_k.add &HD5, "xD5" '"{0xD5}-{Reserved}"
dic_k.add &HD6, "xD6" '"{0xD6}-{Reserved}"
dic_k.add &HD7, "xD7" '"{0xD7}-{Reserved}"
dic_k.add &HD8, "xD8" '"{0xD8}-{Unassigned}"
dic_k.add &HD9, "xD9" '"{0xD9}-{Unassigned}"
dic_k.add &HDA, "xDA" '"{0xDA}-{Unassigned}"
dic_k.add &HDB, "{[}" '"{0xDB}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '[{' key}"
dic_k.add &HDC, "\" '"{0xDC}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the '\|' key}"
dic_k.add &HDD, "{]}" '"{0xDD}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the ']}' key}"
dic_k.add &HDE, "'" '"{0xDE}-{Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the 'single-quote/double-quote' key}"
dic_k.add &HDF, "xDF" '"{0xDF}-{Used for miscellaneous characters; it can vary by keyboard.}"
dic_k.add &HE0, "xE0" '"{0xE0}-{Reserved}"
dic_k.add &HE1, "xE1" '"{0xE1}-{OEM specific}"
dic_k.add &HE2, "xE2" '"{0xE2}-{Either the angle bracket key or the backslash key on the RT 102-key keyboard}"
dic_k.add &HE3, "xE3" '"{0xE3}-{OEM specific}"
dic_k.add &HE4, "xE4" '"{0xE4}-{OEM specific}"
dic_k.add &HE5, "xE5" '"{0xE5}-{IME PROCESS key}"
dic_k.add &HE6, "xE6" '"{0xE6}-{OEM specific}"
dic_k.add &HE7, "xE7" '"{0xE7}-{Used to pass Unicode characters as if they were keystrokes.}"
dic_k.add &HE8, "xE8" '"{0xE8}-{Unassigned}"
dic_k.add &HE9, "xE9" '"{0xE9}-{OEM specific}"
dic_k.add &HEA, "xEA" '"{0xEA}-{OEM specific}"
dic_k.add &HEB, "xEB" '"{0xEB}-{OEM specific}"
dic_k.add &HEC, "xEC" '"{0xEC}-{OEM specific}"
dic_k.add &HED, "xED" '"{0xED}-{OEM specific}"
dic_k.add &HEE, "xEE" '"{0xEE}-{OEM specific}"
dic_k.add &HEF, "xEF" '"{0xEF}-{OEM specific}"
dic_k.add &HF0, "xF0" '"{0xF0}-{OEM specific}"
dic_k.add &HF1, "xF1" '"{0xF1}-{OEM specific}"
dic_k.add &HF2, "xF2" '"{0xF2}-{OEM specific}"
dic_k.add &HF3, "xF3" '"{0xF3}-{OEM specific}"
dic_k.add &HF4, "xF4" '"{0xF4}-{OEM specific}"
dic_k.add &HF5, "xF5" '"{0xF5}-{OEM specific}"
dic_k.add &HF6, "xF6" '"{0xF6}-{Attn key}"
dic_k.add &HF7, "xF7" '"{0xF7}-{CrSel key}"
dic_k.add &HF8, "xF8" '"{0xF8}-{ExSel key}"
dic_k.add &HF9, "xF9" '"{0xF9}-{Erase EOF key}"
dic_k.add &HFA, "xFA" '"{0xFA}-{Play key}"
dic_k.add &HFB, "xFB" '"{0xFB}-{Zoom key}"
dic_k.add &HFC, "xFC" '"{0xFC}-{Reserved for future use}"
dic_k.add &HFD, "xFD" '"{0xFD}-{PA1 key}"
dic_k.add &HFE, "xFE" '"{0xFE}-{Clear key}"
'--------------------------------------

' Формируем путь к папке с макросами 
  pAkelDir = AkelPad.GetAkelDir(4)
  pAkelDir = """" & pAkelDir & "\Macros\" & """"

' Диалог выбора файла-макроса для декодирования (не работает на Vista/Win7)
 Set objDialog = CreateObject("UserAccounts.CommonDialog")
 objDialog.InitialDir = pAkelDir
 objDialog.Filter = "Файлы macro (*.macro)|*.macro|Все файлы (*.*)|*.*"
 objDialog.FilterIndex = 1
 intResult = objDialog.ShowOpen
 If intResult = 0 Then
  Wscript.Quit      ' если файл-макрос не выбран, то выходим
 Else               ' основная обработка
  WM_COMMAND=273 
  IDM_FILE_NEW=4101      ' команда на создание нового файла
  hMainWnd=AkelPad.GetMainWnd()
  AkelPad.SendMessage hMainWnd, WM_COMMAND, IDM_FILE_NEW, 0
  VbCrLf = Chr(13) & Chr(10)
  shbl_sk = "  WshShell.SendKeys "
  fn_macro = objDialog.FileName
  Set fsi = CreateObject("Scripting.FileSystemObject")
  fi_size = fsi.GetFile(fn_macro).Size    ' получить размер файла-макроса
  AkelPad.ReplaceSel(fn_macro & VbCrLf & "Size: " & fi_size & " bytes (" & _
                     fi_size/8 & " keys)" & VbCrLf & String(40, "-") & VbCrLf)

  allkeys = fi_size\8
  If allkeys > 1000 Then
    MsgBox "Too many keys! Only first 1000 will be converted. "
  End If

  first_index = 0
  CountKeyDown = 0
  Set fi = fsi.OpenTextFile(fn_macro, ForReading, True)
'
  myarr(first_index, alt_key_status) = ""
  myarr(first_index, ctrl_key_status) = ""
  myarr(first_index, shift_key_status) = ""
  myarr(first_index, other_key_status) = ""

  For i = 1 To fi_size Step 8     ' перебираем 8-байтные цепочки "KL-00-00-00-FL-00-00-00"
    keyword = Asc(fi.Read(1))
    fi.Skip(3)
    flag_key = Asc(fi.Read(1))
    myitem = dic_k.Item(keyword)
    fi.Skip(3)
    If flag_key <= &H01 Then  ' клавиша нажата...
        CountKeyDown = CountKeyDown + 1
        Select Case keyword
          Case &H10     ' Shift "on"
            myarr(first_index, shift_key_status) = "+"
          Case &H11     ' Ctrl "on"
            myarr(first_index, ctrl_key_status) = "^"
          Case &H12      ' Alt "on"
            myarr(first_index, alt_key_status) = "%"
          Case Else
            myarr(first_index, other_key_status) = myitem
            first_index = first_index + 1 
        End Select
    ElseIf flag_key > &H01 Then  ' клавиша отпущена...
        CountKeyDown = CountKeyDown - 1
        Select Case keyword
          Case &H10
            myarr(first_index, shift_key_status) = ""
          Case &H11
            myarr(first_index, ctrl_key_status) = ""
          Case &H12
            myarr(first_index, alt_key_status) = ""
          Case Else
            If CountKeyDown > 0 Then            ' копирование статуса модификаторов
              myarr(first_index, shift_key_status) = myarr(first_index-1, shift_key_status)
              myarr(first_index, ctrl_key_status) = myarr(first_index-1, ctrl_key_status)
              myarr(first_index, alt_key_status) = myarr(first_index-1, alt_key_status)
              myarr(first_index, other_key_status) = myitem
            End If
        End Select
      End If
  Next
  fi.Close()
 End If

' ---------- вывод содержимого массива (шаблон VBScript)
  shbl_head_vbs = "VBScript template" & VbCrLf & String(40, "-") & VbCrLf & "Dim WshShell" & _
                   VbCrLf & "  Set WshShell = CreateObject(""WScript.Shell"")" & VbCrLf
  AkelPad.ReplaceSel shbl_head_vbs
For j = 0 To first_index ' UBound(myarr, 1)
  strMsg = ""
  For k = 0 To 3
    strMsg = strMsg & myarr(j, k)
  Next
    If Len(strMsg) > 0 Then
      AkelPad.ReplaceSel shbl_sk & """" & strMsg & """" & VbCrLf
    End If
Next
  AkelPad.ReplaceSel(String(40, "-") & VbCrLf)
' ---------- вывод содержимого массива (шаблон JScript)
  shbl_head_js = "JScript template" & VbCrLf & String(40, "-") & VbCrLf & _
                 "  var WshShell = new ActiveXObject(""WScript.Shell"");" & VbCrLf
  AkelPad.ReplaceSel shbl_head_js
For j = 0 To first_index ' UBound(myarr, 1)
  strMsg = ""
  For k = 0 To 3
    strMsg = strMsg & myarr(j, k)
      If (k = 3 And myarr(j, k) = "\") Then   ' удвоение слешей для JScript ("\" -> "\\")
        strMsg = strMsg & "\"
      End If
  Next
    If Len(strMsg) > 0 Then
      AkelPad.ReplaceSel shbl_sk & "(""" & strMsg & """);" & VbCrLf
    End If
Next
  AkelPad.ReplaceSel(String(40, "-") & VbCrLf)

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Features to support files, directories and NTFS streams (alternate data streams).
Script must be placed in directory: ...\AkelPad\AkelFiles\Plugs\Scripts\Include\
Examples of use in the next post.

Code: Select all

// FileAndStream_functions.js
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=15389#p15389
// Version: 2015-01-05
// Author: KDJ
//
// Contains functions:
// IsSupportStreams()
// IsDriveExists()
// IsDirExists()
// IsFileExists()
// IsStreamExists()
// GetFileAttr()
// FilePropertiesDialog()
// CreateFile()
// CopyFile()
// DeleteFile()
// RenameFile()
// WriteFile()
// EnumStreams()
//
// Usage in script:
// if (! AkelPad.Include("FileAndStream_functions.js")) WScript.Quit();
//
// based on the article: http://www.flexhex.com/docs/articles/alternate-streams.phtml

//------------------------------------------------------------
// bSupport = IsSupportStreams(sDrive)
//
// Argument:
// sDrive - drive name, eg. "D" or "D:" or "D:\",
//          if empty string or not specified, drive of current directory is used
//
// Return value:
// true if file system supports NTFS streams, otherwise false.
//------------------------------------------------------------
function IsSupportStreams(sDrive)
{
  var lpBuffer = AkelPad.MemAlloc(4);
  var bSupport = false;

  if (sDrive)
  {
    if (sDrive.length == 1)
      sDrive += ":";
    if (sDrive.length == 2)
      sDrive += "\\";
  }
  else
    sDrive = 0;

  AkelPad.SystemFunction().Call("Kernel32::GetVolumeInformation" + _TCHAR, sDrive, 0, 0, 0, 0, lpBuffer, 0, 0);

  if (AkelPad.MemRead(lpBuffer, 3 /*DT_DWORD*/) & 0x00040000 /*FILE_NAMED_STREAMS*/)
    bSupport = true;

  AkelPad.MemFree(lpBuffer);

  return bSupport;
}

//----------------------------------------------
// bExists = IsDriveExists(sDrive)
//
// Argument:
// sDrive - drive name, eg. "D" or "D:" or "D:\"
//
// Return value:
// true if drive exists, otherwise false.
//----------------------------------------------
function IsDriveExists(sDrive)
{
  if (sDrive.length == 1)
    sDrive += ":";
  if (sDrive.length == 2)
    sDrive += "\\";

  return AkelPad.SystemFunction().Call("Kernel32::GetVolumeInformation" + _TCHAR, sDrive, 0, 0, 0, 0, 0, 0, 0);
}

//---------------------------------------------------
// nAttr = IsDirExists(sDir)
//
// Argument:
// sDir - full directory name, eg. "D:\Text\AkelPad",
//        "D:\Text\AkelPad\", "C:\", "C:", "..\"
//
// Return value:
// number that specifies the directory attributes,
// 0 - if directory does not exist.
//---------------------------------------------------
function IsDirExists(sDir)
{
  var nAttr = GetFileAttr(sDir);

  if (nAttr & 16 /*FILE_ATTRIBUTE_DIRECTORY*/)
    return nAttr;
  else
    return 0;
}

//----------------------------------------------
// nAttr = IsFileExists(sFile)
//
// Argument:
// sFile - full file name, eg. "D:\Text\abc.txt"
//
// Return value:
// number that specifies the file attributes,
// 0 - if file does not exist.
//----------------------------------------------
function IsFileExists(sFile)
{
  var nAttr = GetFileAttr(sFile);

  if (! (nAttr & 16 /*FILE_ATTRIBUTE_DIRECTORY*/))
    return nAttr;
  else
    return 0;
}

//-------------------------------------------------
// bExists = IsStreamExists(sFile, sStream)
//
// Arguments:
// sFile   - full file name, eg. "D:\Text\abc.txt"
// sStream - stream name
//
// Return value:
// true if sFile contains sStream, otherwise false.
//-------------------------------------------------
function IsStreamExists(sFile, sStream)
{
  var hStream = AkelPad.SystemFunction().Call("Kernel32::CreateFile" + _TCHAR,
                  sFile + ":" + sStream, //lpFileName
                  0,  //dwDesiredAccess
                  3,  //dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
                  0,  //lpSecurityAttributes
                  3,  //dwCreationDisposition = OPEN_EXISTING
                  0,  //dwFlagsAndAttributes
                  0); //hTemplateFile

  if (hStream != -1) //INVALID_HANDLE_VALUE
  {
    AkelPad.SystemFunction().Call("Kernel32::CloseHandle", hStream);
    return true;
  }
  else
    return false;
}

//-----------------------------------------------------------------------
// nAttr = GetFileAttr(sFile)
//
// Argument:
// sFile - full file or directory name, eg. "D:\Text\abc.txt"
//
// Return value:
// number that specifies the attributes (msdn: File Attribute Constants),
// 0 - if file/directory does not exist.
//-----------------------------------------------------------------------
function GetFileAttr(sFile)
{
  var nAttr = AkelPad.SystemFunction().Call("Kernel32::GetFileAttributes" + _TCHAR, sFile);
  var lpBuffer;
  var hFindFile;

  if (nAttr == -1 /*INVALID_FILE_ATTRIBUTES*/)
  {
    if (sFile.slice(-1) == "\\")
      sFile = sFile.slice(0, -1);

    lpBuffer  = AkelPad.MemAlloc(44 + (260 + 14) * _TSIZE); //sizeof(WIN32_FIND_DATA)
    hFindFile = AkelPad.SystemFunction().Call("Kernel32::FindFirstFile" + _TCHAR, sFile, lpBuffer);

    if (hFindFile == -1) //INVALID_HANDLE_VALUE
      nAttr = 0;
    else
    {
      nAttr = AkelPad.MemRead(lpBuffer, 3 /*DT_DWORD*/);
      AkelPad.SystemFunction().Call("Kernel32::FindClose", hFindFile);
    }

    AkelPad.MemFree(lpBuffer);
  }

  return nAttr;
}

//------------------------------------------------------------
// Display dialog box with file, directory or drive properties
// FilePropertiesDialog(sFile, hWnd)
//
// Arguments:
// sFile - full file/directory name, eg. "D:\Text\abc.txt"
//         or drive name, eg. "D:"
// hWnd - optional, a handle to the parent window
//
// Return value:
// true if successful, otherwise false.
//------------------------------------------------------------
function FilePropertiesDialog(sFile, hWnd)
{
  var sVerb     = "properties";
  var nInfoSize = _X64 ? 112 : 60; //sizeof(SHELLEXECUTEINFO)
  var lpInfo    = AkelPad.MemAlloc(nInfoSize);
  var lpVerb    = AkelPad.MemAlloc((sVerb.length + 1) * _TSIZE);
  var lpFile    = AkelPad.MemAlloc((sFile.length + 1) * _TSIZE);
  var bSuccess  = false;

  AkelPad.MemCopy(lpVerb, sVerb, _TSTR);
  AkelPad.MemCopy(lpFile, sFile, _TSTR);

  AkelPad.MemCopy(lpInfo, nInfoSize, 3 /*DT_DWORD*/); //cbSize
  AkelPad.MemCopy(_PtrAdd(lpInfo, 4), 0x0000000C /*SEE_MASK_INVOKEIDLIST*/, 3 /*DT_DWORD*/); //fMask
  if (hWnd)
    AkelPad.MemCopy(_PtrAdd(lpInfo, 8), hWnd, 3 /*DT_DWORD*/); //hwnd
  AkelPad.MemCopy(_PtrAdd(lpInfo, _X64 ? 16 : 12), lpVerb, 2 /*DT_QWORD*/); //lpVerb
  AkelPad.MemCopy(_PtrAdd(lpInfo, _X64 ? 24 : 16), lpFile, 2 /*DT_QWORD*/); //lpFile
  AkelPad.MemCopy(_PtrAdd(lpInfo, _X64 ? 48 : 28), 5 /*SW_SHOW*/, 3 /*DT_DWORD*/); //nShow

  if (AkelPad.SystemFunction().Call("Shell32::ShellExecuteEx" + _TCHAR, lpInfo))
    bSuccess = true;

  AkelPad.MemFree(lpInfo);
  AkelPad.MemFree(lpVerb);
  AkelPad.MemFree(lpFile);

  return bSuccess;
}

//-------------------------------------------------------
// Create new file or NTFS stream
// bCreated = CreateFile(sFile[, sStream])
//
// Arguments:
// sFile   - full file name, eg. "D:\Text\abc.txt"
// sStream - stream name, optional
//
// Return value:
// true if sFile or sStream was created, otherwise false.
//-------------------------------------------------------
function CreateFile(sFile, sStream)
{
  var hFile = AkelPad.SystemFunction().Call("Kernel32::CreateFile" + _TCHAR,
                sFile + ((sStream) ? (":" + sStream) : ""), //lpFileName
                0,  //dwDesiredAccess
                3,  //dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
                0,  //lpSecurityAttributes
                1,  //dwCreationDisposition = CREATE_NEW
                0,  //dwFlagsAndAttributes
                0); //hTemplateFile

  if (hFile != -1) //INVALID_HANDLE_VALUE
  {
    AkelPad.SystemFunction().Call("Kernel32::CloseHandle", hFile);
    return true;
  }
  else
    return false;
}

//------------------------------------------------------------------------
// Copy/move file, directory or NTFS stream
// bCopied = CopyFile(sFromFile, sFromStream, sToFile, sToStream[, bMove])
//
// Arguments:
// sFromFile   - source file or directory full name
// sFromStream - source stream name, if the operation is not performed
//               on the stream may be zero, null or empty string
// sToFile     - target file or directory full name
// sToStream   - target stream name, if the operation is not performed
//               on the stream may be zero, null or empty string
// bMove       - if true, after copying the source will be deleted
//
// Return value:
// true if file/directory/stream was copied/moved, otherwise false.
//-------------------------------------------------------------------------
function CopyFile(sFromFile, sFromStream, sToFile, sToStream, bMove)
{
  var bCopied;

  if (sFromStream || sToStream)
  {
    var nAttr = GetFileAttr(sToFile);
    if (nAttr & 1 /*FILE_ATTRIBUTE_READONLY*/)
      AkelPad.SystemFunction().Call("Kernel32::SetFileAttributes" + _TCHAR, sToFile, nAttr ^ 1);

    var hFromFile = AkelPad.SystemFunction().Call("Kernel32::CreateFile" + _TCHAR,
                      sFromFile + ((sFromStream) ? (":" + sFromStream) : ""), //lpFileName
                      0x80000000, //dwDesiredAccess = GENERIC_READ
                      1,          //dwShareMode = FILE_SHARE_READ
                      0,          //lpSecurityAttributes
                      3,          //dwCreationDisposition = OPEN_EXISTING
                      0x08000000, //dwFlagsAndAttributes = FILE_FLAG_SEQUENTIAL_SCAN
                      0);         //hTemplateFile
    var hToFile = AkelPad.SystemFunction().Call("Kernel32::CreateFile" + _TCHAR,
                    sToFile + ((sToStream) ? (":" + sToStream) : ""), //lpFileName
                    0x40000000, //dwDesiredAccess = GENERIC_WRITE
                    1,          //dwShareMode = FILE_SHARE_READ
                    0,          //lpSecurityAttributes
                    2,          //dwCreationDisposition = CREATE_ALWAYS
                    0x08000080, //dwFlagsAndAttributes = FILE_FLAG_SEQUENTIAL_SCAN|FILE_ATTRIBUTE_NORMAL
                    0);         //hTemplateFile

    if ((hFromFile != -1) && (hToFile != -1)) //INVALID_HANDLE_VALUE
    {
      var nBufSize       = 64 * 1024;
      var lpBuffer       = AkelPad.MemAlloc(nBufSize);
      var lpBytesRead    = AkelPad.MemAlloc(4);
      var lpBytesWritten = AkelPad.MemAlloc(4);

      bCopied = true;

      do
      {
        AkelPad.SystemFunction().Call("Kernel32::ReadFile", hFromFile, lpBuffer, nBufSize, lpBytesRead, 0);

        if (AkelPad.MemRead(lpBytesRead, 3 /*DT_DWORD*/))
        {
          if (! AkelPad.SystemFunction().Call("Kernel32::WriteFile", hToFile, lpBuffer, AkelPad.MemRead(lpBytesRead, 3 /*DT_DWORD*/), lpBytesWritten, 0))
          {
            bCopied = false;
            break;
          }
        }
      }
      while (AkelPad.MemRead(lpBytesRead, 3 /*DT_DWORD*/) == nBufSize);

      AkelPad.MemFree(lpBuffer);
      AkelPad.MemFree(lpBytesRead);
      AkelPad.MemFree(lpBytesWritten);
    }
    else
      bCopied = false;

    AkelPad.SystemFunction().Call("Kernel32::CloseHandle", hFromFile);
    AkelPad.SystemFunction().Call("Kernel32::CloseHandle", hToFile);

    if (nAttr & 1 /*FILE_ATTRIBUTE_READONLY*/)
      AkelPad.SystemFunction().Call("Kernel32::SetFileAttributes" + _TCHAR, sToFile, nAttr);

    if (bMove && bCopied)
      DeleteFile(sFromFile, sFromStream);
  }

  else
  {
    var lpFromFile = AkelPad.MemAlloc((sFromFile.length + 2) * _TSIZE);
    var lpToFile   = AkelPad.MemAlloc((sToFile.length + 2) * _TSIZE);
    var lpBuffer   = AkelPad.MemAlloc(_X64 ? 56 : 32); //sizeof(SHFILEOPSTRUCT)

    AkelPad.MemCopy(lpFromFile, sFromFile, _TSTR);
    AkelPad.MemCopy(lpToFile, sToFile, _TSTR);

    //wFunc = FO_MOVE or FO_COPY
    AkelPad.MemCopy(_PtrAdd(lpBuffer, _X64 ? 8 : 4), bMove ? 1 : 2, 3 /*DT_DWORD*/);
    //pFrom = lpFromFile
    AkelPad.MemCopy(_PtrAdd(lpBuffer, _X64 ? 16 : 8), lpFromFile, 2 /*DT_QWORD*/);
    //pTo = lpToFile
    AkelPad.MemCopy(_PtrAdd(lpBuffer, _X64 ? 24 : 12), lpToFile, 2 /*DT_QWORD*/);
    //fFlags = FOF_NOERRORUI|FOF_NOCONFIRMATION|FOF_SILENT
    AkelPad.MemCopy(_PtrAdd(lpBuffer, _X64 ? 32 : 16), 0x0400 | 0x0010 | 0x0004, 4 /*DT_WORD*/);

    bCopied = ! AkelPad.SystemFunction().Call("Shell32::SHFileOperation" + _TCHAR, lpBuffer);

    AkelPad.MemFree(lpFromFile);
    AkelPad.MemFree(lpToFile);
    AkelPad.MemFree(lpBuffer);
  }

  return bCopied;
}

//---------------------------------------------------------------
// Delete file, directory or NTFS stream
// bDeleted = DeleteFile(sFile, sStream, bRecBin)
//
// Arguments:
// sFile   - full file or directory name, eg. "D:\Text\abc.txt"
// sStream - stream name, can be null or empty string
// bRecBin - if true, file or directory is deleted to Recycle Bin
//
// Return value:
// true if file/directory/stream was deleted, otherwise false.
//---------------------------------------------------------------
function DeleteFile(sFile, sStream, bRecBin)
{
  var bDeleted;

  if (sStream)
  {
    var nAttr = GetFileAttr(sFile);

    if (nAttr & 1 /*FILE_ATTRIBUTE_READONLY*/)
      AkelPad.SystemFunction().Call("Kernel32::SetFileAttributes" + _TCHAR, sFile, nAttr ^ 1);

    bDeleted = AkelPad.SystemFunction().Call("Kernel32::DeleteFile" + _TCHAR, sFile + ":" + sStream);

    if (nAttr & 1 /*FILE_ATTRIBUTE_READONLY*/)
      AkelPad.SystemFunction().Call("Kernel32::SetFileAttributes" + _TCHAR, sFile, nAttr);
  }

  else
  {
    var lpBuffer = AkelPad.MemAlloc(_X64 ? 56 : 32); //sizeof(SHFILEOPSTRUCT)
    var lpFrom   = AkelPad.MemAlloc((sFile.length + 2) * _TSIZE);
    var nFlag    = 0x0400 | 0x0010 | 0x0004; //FOF_NOERRORUI|FOF_NOCONFIRMATION|FOF_SILENT

    if (bRecBin)
      nFlag |= 0x0040; //FOF_ALLOWUNDO

    AkelPad.MemCopy(lpFrom, sFile, _TSTR);

    //wFunc = FO_DELETE
    AkelPad.MemCopy(_PtrAdd(lpBuffer, _X64 ? 8 : 4), 3, 3 /*DT_DWORD*/);
    //pFrom = lpFrom
    AkelPad.MemCopy(_PtrAdd(lpBuffer, _X64 ? 16 : 8), lpFrom, 2 /*DT_QWORD*/);
    //fFlags = nFlag
    AkelPad.MemCopy(_PtrAdd(lpBuffer, _X64 ? 32 : 16), nFlag, 4 /*DT_WORD*/);

    bDeleted = ! AkelPad.SystemFunction().Call("Shell32::SHFileOperation" + _TCHAR, lpBuffer);

    AkelPad.MemFree(lpBuffer);
    AkelPad.MemFree(lpFrom);
  }

  return bDeleted;
}

//--------------------------------------------------------------
// Rename file, directory or NTFS stream
// bRenamed = RenameFile(sFile, sStream, sNewName)
//
// Arguments:
// sFile    - full file or directory name, eg. "D:\Text\abc.txt"
// sStream  - stream name, if the operation is not performed
//            on the stream it may be zero, null or empty string
// sNewName - new name of file/directory/stream, without path
//
// Return value:
// true if file/directory/stream was renamed, otherwise false.
//--------------------------------------------------------------
function RenameFile(sFile, sStream, sNewName)
{
  var bRenamed;

  if (sStream)
    bRenamed = CopyFile(sFile, sStream, sFile, sNewName, 1);
  else
    bRenamed = AkelPad.SystemFunction().Call("Kernel32::MoveFile" + _TCHAR, sFile, sFile.substr(0, sFile.lastIndexOf("\\") + 1) + sNewName);

  return bRenamed;
}

//-----------------------------------------------------
// Write file or NTFS stream
// bWritten = WriteFile(sFile, sStream, sData, nType)
//
// Arguments:
// sFile   - full file name, eg. "D:\Text\abc.txt"
// sStream - stream name, can be null or empty string
// sData   - text data to write
// nType   - type of the sData parameter:
//           0 - ANSI
//           1 - UNICODE
//
// Return value:
// bWritten - true if the function succeeds.
//-----------------------------------------------------
function WriteFile(sFile, sStream, sData, nType)
{
  var nAttr    = GetFileAttr(sFile);
  var bWritten = false;
  var hFile;
  var nDisposition;
  var nBufSize;
  var lpBuffer;
  var lpNumBytes;

  if (nAttr)
  {
    nDisposition = 5; //TRUNCATE_EXISTING

    if (nAttr & 1 /*FILE_ATTRIBUTE_READONLY*/)
      AkelPad.SystemFunction().Call("Kernel32::SetFileAttributes" + _TCHAR, sFile, nAttr ^ 1);
  }
  else
    nDisposition = 1; //CREATE_NEW

  hFile = AkelPad.SystemFunction().Call("Kernel32::CreateFile" + _TCHAR,
            sFile + ((sStream) ? (":" + sStream) : ""), //lpFileName
            0x40000000,   //dwDesiredAccess = GENERIC_WRITE
            3,            //dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
            0,            //lpSecurityAttributes
            nDisposition, //dwCreationDisposition
            0,            //dwFlagsAndAttributes
            0);           //hTemplateFile

  if (hFile != -1) //INVALID_HANDLE_VALUE
  {
    nBufSize = sData.length + 1;
    if (nType)
      nBufSize = 2 + nBufSize * 2;

    lpBuffer   = AkelPad.MemAlloc(nBufSize);
    lpNumBytes = AkelPad.MemAlloc(4);

    if (nType)
    {
      //BOM UTF-16LE
      AkelPad.MemCopy(lpBuffer, 0xFF, 5 /*DT_BYTE*/);
      AkelPad.MemCopy(_PtrAdd(lpBuffer, 1), 0xFE, 5 /*DT_BYTE*/);
      AkelPad.MemCopy(_PtrAdd(lpBuffer, 2), sData, nType);
    }
    else
      AkelPad.MemCopy(lpBuffer, sData, nType);

    bWritten = AkelPad.SystemFunction().Call("Kernel32::WriteFile",
                 hFile,                //hFile
                 lpBuffer,             //lpBuffer
                 nBufSize - 1 - nType, //nNumberOfBytesToWrite
                 lpNumBytes,           //lpNumberOfBytesWritten
                 0);                   //lpOverlapped
  
    AkelPad.SystemFunction().Call("Kernel32::CloseHandle", hFile);

    AkelPad.MemFree(lpBuffer);
    AkelPad.MemFree(lpNumBytes);
  }

  if (nAttr & 1 /*FILE_ATTRIBUTE_READONLY*/)
    AkelPad.SystemFunction().Call("Kernel32::SetFileAttributes" + _TCHAR, sFile, nAttr);

  return bWritten;
}

//-----------------------------------------------------------
// aStream = EnumStreams(sFile)
//
// Argument:
// sFile - full file or directory name, eg. "D:\Text\abc.txt"
//
// Return value:
// Array. Each element of array is two-elements array,
// contains information about a single stream:
// aStream[n][0] - stream name,
// aStream[n][1] - stream size in bytes.
//-----------------------------------------------------------
function EnumStreams(sFile)
{
  var aStream = [];
  var nVerLen = 4 * 5 + 128 * _TSIZE; //sizeof(OSVERSIONINFO)
  var lpOsVer = AkelPad.MemAlloc(nVerLen);
  var nMajorVer;
  var nMinorVer;
  var sStreamName;
  var nStreamSize;

  //Get system version
  AkelPad.MemCopy(lpOsVer, nVerLen, 3 /*DT_DWORD*/);
  AkelPad.SystemFunction().Call("Kernel32::GetVersionEx" + _TCHAR, lpOsVer);
  nMajorVer = AkelPad.MemRead(_PtrAdd(lpOsVer, 4), 3 /*DT_DWORD*/);
  nMinorVer = AkelPad.MemRead(_PtrAdd(lpOsVer, 8), 3 /*DT_DWORD*/);
  AkelPad.MemFree(lpOsVer);

  //Win-Vista+, Win-Server-2003+
  if ((nMajorVer > 5) || ((nMajorVer == 5) && (nMinorVer >= 2)))
  {
    var lpFindStream = AkelPad.MemAlloc(8 + (260 + 36) * 2); //WIN32_FIND_STREAM_DATA
    var hFindStream  = AkelPad.SystemFunction().Call("Kernel32::FindFirstStreamW", sFile, 0 /*FindStreamInfoStandard*/, lpFindStream, 0);

    if (hFindStream != -1) //INVALID_HANDLE_VALUE
    {
      do
      {
        sStreamName = AkelPad.MemRead(_PtrAdd(lpFindStream, 8), 1 /*DT_UNICODE*/);
        sStreamName = sStreamName.substring(1, sStreamName.lastIndexOf(":"));
        nStreamSize = GetStreamSize(lpFindStream);

        aStream[aStream.length] = [sStreamName, nStreamSize];
      }
      while(AkelPad.SystemFunction().Call("Kernel32::FindNextStreamW", hFindStream, lpFindStream));
    }

    AkelPad.SystemFunction().Call("Kernel32::FindClose", hFindStream);
    AkelPad.MemFree(lpFindStream);
  }

  //Win-XP
  else
  {
    var nInfoLen = 65536;
    var lpInfo   = AkelPad.MemAlloc(nInfoLen);
    var lpStatus = AkelPad.MemAlloc(8);
    var nFlag    = 0;
    var hFile;
    var lpElement;
    var nNextOffset;
    var nNameLength;

    if (IsDirExists(sFile))
    {
      var lpToken     = AkelPad.MemAlloc(4);
      var lpPrivilege = AkelPad.MemAlloc(16);
      var hToken;

      AkelPad.SystemFunction().Call("Advapi32::OpenProcessToken", AkelPad.SystemFunction().Call("Kernel32::GetCurrentProcess"), 0x0020 /*TOKEN_ADJUST_PRIVILEGES*/, lpToken);
      hToken = AkelPad.MemRead(lpToken, 3 /*DT_DWORD*/);

      AkelPad.MemCopy(lpPrivilege, 1, 3 /*DT_DWORD*/); //PrivilegeCount
      AkelPad.MemCopy(_PtrAdd(lpPrivilege, 12), 2 /*SE_PRIVILEGE_ENABLED*/, 3 /*DT_DWORD*/); //Attributes

      AkelPad.SystemFunction().Call("Advapi32::LookupPrivilegeValue" + _TCHAR, 0, "SeBackupPrivilege", _PtrAdd(lpPrivilege, 4));
      AkelPad.SystemFunction().Call("Advapi32::AdjustTokenPrivileges", hToken, 0, lpPrivilege, 16, 0, 0);

      AkelPad.SystemFunction().Call("Kernel32::CloseHandle", hToken);
      AkelPad.MemFree(lpToken);
      AkelPad.MemFree(lpPrivilege);

      nFlag = 0x02000000; //FILE_FLAG_BACKUP_SEMANTICS
    }

    hFile = AkelPad.SystemFunction().Call("Kernel32::CreateFile" + _TCHAR,
              sFile, //lpFileName
              0,     //dwDesiredAccess
              3,     //dwShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
              0,     //lpSecurityAttributes
              3,     //dwCreationDisposition = OPEN_EXISTING
              nFlag, //dwFlagsAndAttributes
              0);    //hTemplateFile

    if (hFile != -1) //INVALID_HANDLE_VALUE
    {
      AkelPad.SystemFunction().Call("Ntdll::NtQueryInformationFile",
        hFile,    //FileHandle
        lpStatus, //IoStatusBlock
        lpInfo,   //FileInformation
        nInfoLen, //Length
        22);      //FileInformationClass:FileStreamInformation
        // http://msdn.microsoft.com/en-us/library/cc232090%28v=prot.13%29.aspx

      lpElement   = lpInfo;
      nNextOffset = 0;

      do
      {
        lpElement = _PtrAdd(lpElement, nNextOffset);

        if (nNameLength = AkelPad.MemRead(_PtrAdd(lpElement, 4), 3 /*DT_DWORD*/))
        {
          sStreamName = AkelPad.MemRead(_PtrAdd(lpElement, 24), 1 /*DT_UNICODE*/, nNameLength / 2);
          sStreamName = sStreamName.substring(1, sStreamName.lastIndexOf(":"));
          nStreamSize = GetStreamSize(_PtrAdd(lpElement, 8));

          aStream[aStream.length] = [sStreamName, nStreamSize];
        }
      }
      while (nNextOffset = AkelPad.MemRead(lpElement, 3 /*DT_DWORD*/));

      AkelPad.SystemFunction().Call("Kernel32::CloseHandle", hFile);
    }

    AkelPad.MemFree(lpInfo);
    AkelPad.MemFree(lpStatus);
  }

  return aStream;

  function GetStreamSize(lpBuffer)
  {
    var sNum = "";
    var sByte;
    var i;

    for (i = 0; i < 8; ++i)
    {
      sByte = AkelPad.MemRead(_PtrAdd(lpBuffer, i), 5 /*DT_BYTE*/).toString(16);
      if (sByte.length == 1)
        sByte = "0" + sByte;

      sNum = sByte + sNum;
    }

    return parseInt("0x" + sNum);
  }
}
Last edited by KDJ on Mon Jan 05, 2015 5:12 pm, edited 11 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Examples of use FileAndStream_functions.js:

Listing streams contained in the edited file

Code: Select all

// Enumerate NTFS streams

var sFile = AkelPad.GetEditFile(0);
var sText;
var sDrive;
var aStream;
var i;

if (AkelPad.Include("FileAndStream_functions.js") && sFile)
{
  sDrive = sFile.substr(0, 3).toUpperCase();

  if (IsSupportStreams(sDrive))
  {
    aStream = EnumStreams(sFile);
    sText   = sFile + "\n\nNumber of streams: " + aStream.length + "\n\n";

    for (i = 0; i < aStream.length; ++i)
      sText += ((aStream[i][0]) ? aStream[i][0] : "<unnamed - main stream>") + "      " + aStream[i][1] + " B\n";

    WScript.Echo(sText);
  }
  else
    WScript.Echo("Drive "  + sDrive + " does not supports NTFS streams.");
}


Create new stream

Code: Select all

// Create new NTFS stream

var sFile = AkelPad.GetEditFile(0);
var sStream;
var sDrive;

if (AkelPad.Include("FileAndStream_functions.js") && sFile)
{
  sDrive = sFile.substr(0, 3).toUpperCase();

  if (IsSupportStreams(sDrive))
  {
    sStream = AkelPad.InputBox(AkelPad.GetMainWnd(), "Create new NTFS stream", "Input stream name:", "");

    if (sStream)
    {
      if (IsStreamExists(sFile, sStream))
        WScript.Echo('Stream "' + sStream + '" already exists.');
      else
      {
        if (CreateFile(sFile, sStream))
          WScript.Echo('Stream "'  + sStream + '" has been created.');
        else
          WScript.Echo('Error: failed to create stream.');
      }
    }
  }
  else
    WScript.Echo("Drive "  + sDrive + " does not supports NTFS streams.");
}


Delete stream

Code: Select all

// Delete NTFS stream

var sFile   = AkelPad.GetEditFile(0);
var sStream = "";
var sDrive;
var aStream;

if (AkelPad.Include("FileAndStream_functions.js") && sFile)
{
  sDrive = sFile.substr(0, 3).toUpperCase();

  if (IsSupportStreams(sDrive))
  {
    aStream = EnumStreams(sFile);
    if (aStream.length > 1)
      sStream = aStream[1][0];

    sStream = AkelPad.InputBox(AkelPad.GetMainWnd(), "Delete NTFS stream", "Input stream name:", sStream);

    if (sStream)
    {
      if (IsStreamExists(sFile, sStream))
      {
        if (DeleteFile(sFile, sStream))
          WScript.Echo('Stream "'  + sStream + '" has been deleted.');
        else
          WScript.Echo('Error: failed to delete.');
      }
      else
        WScript.Echo('Stream "' + sStream + '" does not exists.');
    }
  }
  else
    WScript.Echo("Drive "  + sDrive + " does not supports NTFS streams.");
}


Open stream for editing

Code: Select all

// Opens NTFS stream for editing in AkelPad window.
// If the stream does not exists, creates new empty stream and opens it.

var sFile   = AkelPad.GetEditFile(0);
var sStream = "";
var sDrive;
var aStream;

if (AkelPad.Include("FileAndStream_functions.js") && sFile)
{
  sDrive = sFile.substr(0, 3).toUpperCase();

  if (IsSupportStreams(sDrive))
  {
    aStream = EnumStreams(sFile);
    if (aStream.length > 1)
      sStream = aStream[1][0];

    sStream = AkelPad.InputBox(AkelPad.GetMainWnd(), "Open NTFS stream", "Input stream name:", sStream);

    if (sStream)
      AkelPad.OpenFile(sFile + ":" + sStream);
  }
  else
    WScript.Echo("Drive "  + sDrive + " does not supports NTFS streams.");
}


Read stream

Code: Select all

// Read contents of NTFS stream to variable.

var sFile   = AkelPad.GetEditFile(0);
var sStream = "";
var sDrive;
var aStream;
var sContents;

if (AkelPad.Include("FileAndStream_functions.js") && sFile)
{
  sDrive = sFile.substr(0, 3).toUpperCase();

  if (IsSupportStreams(sDrive))
  {
    aStream = EnumStreams(sFile);
    if (aStream.length > 1)
      sStream = aStream[1][0];

    sStream = AkelPad.InputBox(AkelPad.GetMainWnd(), "Read NTFS stream", "Input stream name:", sStream);

    if (sStream)
    {
      if (IsStreamExists(sFile, sStream))
      {
        sContents = AkelPad.ReadFile(sFile + ":" + sStream);
        WScript.Echo(sContents);
      }
      else
        WScript.Echo('Stream "' + sStream + '" does not exists.');
    }
  }
  else
    WScript.Echo("Drive "  + sDrive + " does not supports NTFS streams.");
}


Write stream

Code: Select all

// Write selected text to NTFS stream.
// If no selection, all text.
// Previous contents of the stream will be deleted.

var sFile   = AkelPad.GetEditFile(0);
var sStream = "";
var sDrive;
var aStream;
var sData;

if (AkelPad.Include("FileAndStream_functions.js") && sFile)
{
  sDrive = sFile.substr(0, 3).toUpperCase();

  if (IsSupportStreams(sDrive))
  {
    aStream = EnumStreams(sFile);
    if (aStream.length > 1)
      sStream = aStream[1][0];

    sStream = AkelPad.InputBox(AkelPad.GetMainWnd(), "Write text to NTFS stream", "Input stream name:", sStream);

    if (sStream)
    {
      if (IsStreamExists(sFile, sStream))
      {
        if (AkelPad.GetSelStart() == AkelPad.GetSelEnd())
          sData = AkelPad.GetTextRange(0, -1);
        else
          sData = AkelPad.GetSelText();

        if (WriteFile(sFile, sStream, sData, 1))
          WScript.Echo('Stream "'  + sStream + '" has been written.');
        else
          WScript.Echo('Error: failed to write.');
      }
      else
        WScript.Echo('Stream "' + sStream + '" does not exists.');
    }
  }
  else
    WScript.Echo("Drive "  + sDrive + " does not supports NTFS streams.");
}
Last edited by KDJ on Fri Mar 02, 2012 8:53 pm, edited 3 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Switching four caret options:
- Caret after end of line,
- Show active column,
- Show active line,
- Show active line border.

Based on Instructor's script ActiveColumnSwitch.js.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=15760#p15760
// Version: 2013-08-24
// Author: KDJ
//
// *** Switch four caret options ***
//
// How to use:
//   Directly call:
//     Call("Scripts::Main", 1, "CaretOptionsSwitch.js", "Option")
//   Add button to Toolbar plugin:
//     -"Caret option switch" Call("Scripts::Main", 1, "CaretOptionsSwitch.js", "Option %m %i") Icon(0)
//   Add item to ContextMenu plugin:
//     -"Caret option switch" Call("Scripts::Main", 1, "CaretOptionsSwitch.js", "Option %m %i")
//
// Option argument can have value:
//   0 - Caret after end of line (default)
//   1 - Show active column
//   2 - Show active line
//   3 - Show active line border
//
// Example for Active line show/hide:
//   -"Active line switch" Call("Scripts::Main", 1, "CaretOptionsSwitch.js", "2 %m %i") Icon(0)

var hMainWnd = AkelPad.GetMainWnd();
var hEditWnd = AkelPad.GetEditWnd();
var oSys     = AkelPad.SystemFunction();
var nAction  = 0;
var nHandle  = 0;
var nItemID  = 0;
var nSetOptions;
var nCaretOptions;
var nAECO_flag;
var nCO_flag;

if (hMainWnd && hEditWnd)
{
  //Arguments
  if (WScript.Arguments.length > 0)
  {
    nAction = parseInt(WScript.Arguments(0));
    if ((nAction < 0) || (nAction > 3))
      nAction = 0;
  }
  if (WScript.Arguments.length > 2)
  {
    nHandle = parseInt(WScript.Arguments(1));
    nItemID = parseInt(WScript.Arguments(2));
  }

  if (nAction == 0) //Allow caret moving out of the line edge
  {
    nAECO_flag = 0x00000200; //AECO_CARETOUTEDGE
    nCO_flag   = 0x00000001; //CO_CARETOUTEDGE
  }
  else if (nAction == 1) //Draw caret vertical line
  {
    nAECO_flag = 0x00000400; //AECO_ACTIVECOLUMN
    nCO_flag   = 0x00000002; //CO_CARETVERTLINE
  }
  else if (nAction == 2) //Draw active line
  {
    nAECO_flag = 0x00000800; //AECO_ACTIVELINE
    nCO_flag   = 0x00000004; //CO_CARETACTIVELINE
  }
  else //Draw active line border
  {
    nAECO_flag = 0x00001000; //AECO_ACTIVELINEBORDER
    nCO_flag   = 0x00000008; //CO_CARETACTIVELINEBORDER
  }

  nSetOptions   = SendMessage(hEditWnd, 3227 /*AEM_GETOPTIONS*/, 0, 0);
  nCaretOptions = SendMessage(hMainWnd, 1223 /*AKD_GETFRAMEINFO*/, 69 /*FI_CARETOPTIONS*/, 0);

  if (nSetOptions & nAECO_flag)
  {
    SendMessage(hEditWnd, 3228 /*AEM_SETOPTIONS*/, 4 /*AECOOP_XOR*/, nAECO_flag);

    if (nCaretOptions & nCO_flag)
      nCaretOptions = nCaretOptions ^ nCO_flag;

    if (oSys.Call("User32::IsMenu", nHandle))
      oSys.Call("User32::CheckMenuItem", nHandle, nItemID, 0x0 /*MF_BYCOMMAND|MF_UNCHECKED*/);
    else
      SendMessage(nHandle, 1026 /*TB_CHECKBUTTON*/, nItemID, false);
  }
  else
  {
    SendMessage(hEditWnd, 3228 /*AEM_SETOPTIONS*/, 2 /*AECOOP_OR*/, nAECO_flag);

    if (! (nCaretOptions & nCO_flag))
      nCaretOptions = nCaretOptions | nCO_flag;

    if (oSys.Call("User32::IsMenu", nHandle))
      oSys.Call("User32::CheckMenuItem", nHandle, nItemID, 0x8 /*MF_BYCOMMAND|MF_CHECKED*/);
    else
      SendMessage(nHandle, 1026 /*TB_CHECKBUTTON*/, nItemID, true);
  }

  AkelPad.SetFrameInfo(0, 17 /*FIS_CARETOPTIONS*/, nCaretOptions);
}

function SendMessage(hWnd, uMsg, wParam, lParam)
{
  return oSys.Call("User32::SendMessage" + _TCHAR, hWnd, uMsg, wParam, lParam);
}

Last edited by KDJ on Sat Dec 20, 2014 6:35 pm, edited 4 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Sends data and keystrokes from text file or Excel worksheet to another window.
Required to include: FileAndStream_functions.js
Help files in the next post.

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=15767#p15767
// Version: 2015-01-08
// Author: KDJ
//
// *** Sends data and keystrokes from text file or Excel worksheet to another window. ***
//
// Required to include: FileAndStream_functions.js
//
// Usage:
// - in AkelPad window:
//   Call("Scripts::Main", 1, "SendData.js")
// - form command line:
//   AkelPad.exe /Show(0) /Call("Scripts::Main", 2, "SendData.js") /quit

if (! AkelPad.Include("FileAndStream_functions.js"))
  WScript.Quit();

if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 0x0415) //Polish
{
  var sTxtDataSource  = "Źródło danych";
  var sTxtTextSemic   = "Tekst - średnik jako separator ;";
  var sTxtTextPipe    = "Tekst - pipeline jako separator |";
  var sTxtTextTab     = "Tekst - TAB jako separator";
  var sTxtWorksheet   = "Arkusz Excela";
  var sTxtExcelBusy   = "<Excel jest zajęty>";
  var sTxtNoFileName  = "<plik bez nazwy>";
  var sTxtNoOpenFiles = "<brak otwartych plików>";
  var sTxtOpen        = "Otwórz plik";
  var sTxtSave        = "Zapisz plik";
  var sTxtAddSend     = "Dodatkowo wyślij";
  var sTxtBeforeStart = "Na początku:";
  var sTxtAfterField  = "Po polu z danymi:";
  var sTxtAfterRow    = "Po każdym wierszu:";
  var sTxtAfterEnd    = "Po zakończeniu:";
  var sTxtDelay_ms    = "Opóźnienie (milisekundy)";
  var sTxtAfterData   = "Po wysłaniu pola z danymi:";
  var sTxtAfterKeys   = "Po wysłaniu pola z klawiszami:";
  var sTxtTargetWin   = "Okno docelowe";
  var sTxtRefresh     = "Odśwież listę";
  var sTxtSend        = "Wyślij dane";
  var sTxtUnableExec  = "Nie można wykonać, Excel jest zajęty.";
  var sTxtNoWorkbook  = "Nie otwarto żadnego skoroszytu w Excelu.";
  var sTxtNoOpenText  = "Nie otwarto żadnego pliku w edytorze.";
  var sTxtWantSave    = "Czy chcesz zapisać ten plik?";
  var sTxtWinClosed   = "To okno zostało już zamknięte. Czy odświeżyć litę okien?";
  var sTxtNoWorksheet = "Aktywny obiekt w Excelu nie jest arkuszem kalkulacyjnym.";
  var sTxtNoSelection = "Nie zaznaczono danych do wysłania.";
  var sTxtTerminate   = "Zatrzymano. Czy zakończyć wysyłanie?";
  var sTxtPressEsc    = "żeby zatrzymać, wciśnij i przytrzymaj ESC";
  var sTxtCurSent     = "Aktualnie wysyłane: ";
  var sTxtOffset      = "offset: ";
  var sTxtCell        = "komórka: ";
  var sTxtRow         = "wiersz: ";
  var sTxtColumn      = "kolumna: ";
  var sTxtNumRows     = "Liczba wysłanych wierszy:";
  var sTxtNoErrors    = "Brak błędów";
  var sTxtKeysError   = "Błąd w polu klawiszy: ";
  var sTxtEndSend     = "Wysyłanie zakończone.";
}
else
{
  var sTxtDataSource  = "Data source";
  var sTxtTextSemic   = "Text - semicolon as separator ;";
  var sTxtTextPipe    = "Text - pipeline as separator |";
  var sTxtTextTab     = "Text - TAB as separator";
  var sTxtWorksheet   = "Excel worksheet";
  var sTxtExcelBusy   = "<Excel is busy>";
  var sTxtNoFileName  = "<no file name>";
  var sTxtNoOpenFiles = "<no opened files>";
  var sTxtOpen        = "Open file";
  var sTxtSave        = "Save file";
  var sTxtAddSend     = "Additionally send";
  var sTxtBeforeStart = "Before start:";
  var sTxtAfterField  = "After data field:";
  var sTxtAfterRow    = "After each row:";
  var sTxtAfterEnd    = "After end:";
  var sTxtDelay_ms    = "Delay (miliseconds)";
  var sTxtAfterData   = "After sending field with data:";
  var sTxtAfterKeys   = "After sending field with keystrokes:";
  var sTxtTargetWin   = "Target window";
  var sTxtRefresh     = "Refresh list";
  var sTxtSend        = "Send data";
  var sTxtUnableExec  = "Unable to execute, Excel is busy.";
  var sTxtNoWorkbook  = "There is no open workbook in Excel.";
  var sTxtNoOpenText  = "There is no open text file in editor.";
  var sTxtWantSave    = "Do you want to save this file?";
  var sTxtWinClosed   = "This window is already closed. Do you refresh the windows list?";
  var sTxtNoWorksheet = "Active object in Excel is no worksheet.";
  var sTxtNoSelection = "There is no data selection to send.";
  var sTxtTerminate   = "Stopped. Terminate sending?";
  var sTxtPressEsc    = "to stop, press and hold ESC key";
  var sTxtCurSent     = "Currently is sent: ";
  var sTxtOffset      = "offset: ";
  var sTxtCell        = "cell: ";
  var sTxtRow         = "row: ";
  var sTxtColumn      = "kolumn: ";
  var sTxtNumRows     = "Number of sent rows:";
  var sTxtNoErrors    = "No errors";
  var sTxtKeysError   = "Error in keystrokes field: ";
  var sTxtEndSend     = "Sending completed.";
}

var oSys          = AkelPad.SystemFunction();
var oWshShell     = new ActiveXObject("WScript.shell");
var hMainWnd      = AkelPad.GetMainWnd();
var hInstanceDLL  = AkelPad.GetInstanceDll();
var sClassName    = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstanceDLL;
var sScriptName   = "SendData";
var hGuiFont      = oSys.Call("Gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
var sExcelClass   = "XLMAIN";
var nWndX         = 350;
var nWndY         = 120;
var nSource       = 0;
var bBeforeStart  = false;
var bAfterField   = false;
var bAfterRow     = false;
var bAfterEnd     = false;
var bDelayData    = false;
var bDelayKeys    = false;
var sBeforeStart  = "";
var sAfterField   = "";
var sAfterRow     = "";
var sAfterEnd     = "";
var sDelayData    = "";
var sDelayKeys    = "";
var hWndDlg;
var hFocus;
var bExcelWasRunning;
var oExcel;

ReadWriteIni(false);

var CLASS   = 0;
var HWND    = 1;
var EXSTYLE = 2;
var STYLE   = 3;
var X       = 4;
var Y       = 5;
var W       = 6;
var H       = 7;
var TXT     = 8;

var aWnd           = [];
var IDSOURCEG      = 1000;
var IDSOURCELB     = 1001;
var IDSOURCES      = 1002;
var IDOPENB        = 1003;
var IDSAVEB        = 1004;
var IDADDSENDG     = 1005;
var IDBEFORESTARTB = 1006;
var IDBEFORESTARTE = 1007;
var IDKEYSMENUB1   = 1008;
var IDAFTERFIELDB  = 1009;
var IDAFTERFIELDE  = 1010;
var IDKEYSMENUB2   = 1011;
var IDAFTERROWB    = 1012;
var IDAFTERROWE    = 1013;
var IDKEYSMENUB3   = 1014;
var IDAFTERENDB    = 1015;
var IDAFTERENDE    = 1016;
var IDKEYSMENUB4   = 1017;
var IDDELAYG       = 1018;
var IDDELAYDATAB   = 1019;
var IDDELAYDATAE   = 1020;
var IDDELAYKEYSB   = 1021;
var IDDELAYKEYSE   = 1022;
var IDTARGETG      = 1023;
var IDTARGETLB     = 1024;
var IDREFRESHB     = 1025;
var IDSENDB        = 1026;

//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
//0x50010080 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL
//0x50012002 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_NUMBER|ES_RIGHT
//0x50010003 - WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
//0x50810001 - WS_VISIBLE|WS_CHILD|WS_BORDER|WS_TABSTOP|LBS_NOTIFY
//0x50A10001 - WS_VISIBLE|WS_CHILD|WS_VSCROLL|WS_BORDER|WS_TABSTOP|LBS_NOTIFY
//Windows             CLASS,            HWND,EXSTYLE,      STYLE,   X,   Y,   W,   H, TXT
aWnd[IDSOURCEG     ]=["BUTTON",            0,      0, 0x50000007,  10,  10, 280, 100, sTxtDataSource];
aWnd[IDSOURCELB    ]=["LISTBOX",           0,      0, 0x50810001,  20,  30, 170,  70, ""];
aWnd[IDSOURCES     ]=["STATIC",            0,      0, 0x50000000,  20,  90, 260,  13, ""];
aWnd[IDOPENB       ]=["BUTTON",            0,      0, 0x50010000, 200,  30,  80,  23, sTxtOpen];
aWnd[IDSAVEB       ]=["BUTTON",            0,      0, 0x50010000, 200,  60,  80,  23, sTxtSave];
aWnd[IDADDSENDG    ]=["BUTTON",            0,      0, 0x50000007,  10, 120, 280, 110, sTxtAddSend];
aWnd[IDBEFORESTARTB]=["BUTTON",            0,      0, 0x50010003,  20, 140, 110,  16, sTxtBeforeStart];
aWnd[IDBEFORESTARTE]=["RichEdit20"+_TCHAR, 0,  0x200, 0x50010080, 130, 140, 135,  20, ""];
aWnd[IDKEYSMENUB1  ]=["BUTTON",            0,      0, 0x50010000, 265, 140,  15,  21, "..."];
aWnd[IDAFTERFIELDB ]=["BUTTON",            0,      0, 0x50010003,  20, 160, 110,  16, sTxtAfterField];
aWnd[IDAFTERFIELDE ]=["RichEdit20"+_TCHAR, 0,  0x200, 0x50010080, 130, 160, 135,  20, ""];
aWnd[IDKEYSMENUB2  ]=["BUTTON",            0,      0, 0x50010000, 265, 160,  15,  21, "..."];
aWnd[IDAFTERROWB   ]=["BUTTON",            0,      0, 0x50010003,  20, 180, 110,  16, sTxtAfterRow];
aWnd[IDAFTERROWE   ]=["RichEdit20"+_TCHAR, 0,  0x200, 0x50010080, 130, 180, 135,  20, ""];
aWnd[IDKEYSMENUB3  ]=["BUTTON",            0,      0, 0x50010000, 265, 180,  15,  21, "..."];
aWnd[IDAFTERENDB   ]=["BUTTON",            0,      0, 0x50010003,  20, 200, 110,  16, sTxtAfterEnd];
aWnd[IDAFTERENDE   ]=["RichEdit20"+_TCHAR, 0,  0x200, 0x50010080, 130, 200, 135,  20, ""];
aWnd[IDKEYSMENUB4  ]=["BUTTON",            0,      0, 0x50010000, 265, 200,  15,  21, "..."];
aWnd[IDDELAYG      ]=["BUTTON",            0,      0, 0x50000007,  10, 240, 280,  70, sTxtDelay_ms];
aWnd[IDDELAYDATAB  ]=["BUTTON",            0,      0, 0x50010003,  35, 260, 180,  13, sTxtAfterData];
aWnd[IDDELAYDATAE  ]=["EDIT",              0,  0x001, 0x50012002, 225, 260,  40,  20, ""];
aWnd[IDDELAYKEYSB  ]=["BUTTON",            0,      0, 0x50010003,  35, 280, 180,  13, sTxtAfterKeys];
aWnd[IDDELAYKEYSE  ]=["EDIT",              0,  0x001, 0x50012002, 225, 280,  40,  20, ""];
aWnd[IDTARGETG     ]=["BUTTON",            0,      0, 0x50000007,  10, 320, 280, 110, sTxtTargetWin];
aWnd[IDTARGETLB    ]=["LISTBOX",           0,      0, 0x50A10001,  20, 340, 260,  70, ""];
aWnd[IDREFRESHB    ]=["BUTTON",            0,      0, 0x50010000,  20, 400,  80,  23, sTxtRefresh];
aWnd[IDSENDB       ]=["BUTTON",            0,      0, 0x50010000, 200, 400,  80,  23, sTxtSend];

if (AkelPad.WindowRegisterClass(sClassName))
{
  hWndDlg = oSys.Call("User32::CreateWindowEx" + _TCHAR,
                      0x00000008,      //dwExStyle=WS_EX_TOPMOST
                      sClassName,      //lpClassName
                      sScriptName,     //lpWindowName
                      0x90CA0000,      //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
                      nWndX,           //x
                      nWndY,           //y
                      305,             //nWidth
                      470,             //nHeight
                      0,               //hWndParent
                      0,               //ID
                      hInstanceDLL,    //hInstance
                      DialogCallback); //Script function callback. To use it class must be registered by WindowRegisterClass.

  //Allow other scripts running
  AkelPad.ScriptNoMutex();

  //Message loop
  AkelPad.WindowGetMessage();

  AkelPad.WindowUnregisterClass(sClassName);
}
else if (hWndDlg = oSys.Call("User32::FindWindowEx" + _TCHAR, 0, 0, sClassName, 0))
{
  if (! oSys.Call("User32::IsWindowVisible", hWndDlg))
    oSys.Call("User32::ShowWindow", hWndDlg, 8 /*SW_SHOWNA*/);
  if (oSys.Call("User32::IsIconic", hWndDlg))
    oSys.Call("User32::ShowWindow", hWndDlg, 9 /*SW_RESTORE*/);

  SetForegroundWindow(hWndDlg);
}

if ((oExcel) && (! bExcelWasRunning) && (! IsExcelBusy()))
  oExcel.Quit();

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 1) //WM_CREATE
  {
    var i;

    for (i = 1000; i < aWnd.length; ++i)
    {
      aWnd[i][HWND] =
        oSys.Call("User32::CreateWindowEx" + _TCHAR,
                  aWnd[i][EXSTYLE], //dwExStyle
                  aWnd[i][CLASS],   //lpClassName
                  0,                //lpWindowName
                  aWnd[i][STYLE],   //dwStyle
                  aWnd[i][X],       //x
                  aWnd[i][Y],       //y
                  aWnd[i][W],       //nWidth
                  aWnd[i][H],       //nHeight
                  hWnd,             //hWndParent
                  i,                //ID
                  hInstanceDLL,     //hInstance
                  0);               //lpParam

      //Set font and text
      SetWndFontAndText(aWnd[i][HWND], hGuiFont, aWnd[i][TXT]);
    }

    AkelPad.SendMessage(aWnd[IDBEFORESTARTE][HWND], 197 /*EM_SETLIMITTEXT*/, 64, 0);
    AkelPad.SendMessage(aWnd[IDAFTERFIELDE ][HWND], 197 /*EM_SETLIMITTEXT*/, 64, 0);
    AkelPad.SendMessage(aWnd[IDAFTERROWE   ][HWND], 197 /*EM_SETLIMITTEXT*/, 64, 0);
    AkelPad.SendMessage(aWnd[IDAFTERENDE   ][HWND], 197 /*EM_SETLIMITTEXT*/, 64, 0);
    AkelPad.SendMessage(aWnd[IDDELAYDATAE  ][HWND], 197 /*EM_SETLIMITTEXT*/,  5, 0);
    AkelPad.SendMessage(aWnd[IDDELAYKEYSE  ][HWND], 197 /*EM_SETLIMITTEXT*/,  5, 0);

    //Fill Listbox
    FillSourceLB();

    //Special message for ShowSourceWindow()
    oSys.Call("User32::PostMessage" + _TCHAR, hWnd, 0x8000, 0, 0);

    hFocus = aWnd[IDSOURCELB][HWND];
  }

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

  else if (uMsg == 7 /*WM_SETFOCUS*/)
  {
    {
      CheckExcel();
      GetParametersSourceFile();
      AkelPad.SendMessage(aWnd[IDSOURCELB][HWND], 0x0186 /*LB_SETCURSEL*/, nSource, 0);
      ShowSourceName();
      CheckButtons();
      SetEditTexts();
      FillTargetLB();
      oSys.Call("User32::SetFocus", hFocus);
    }
  }

  else if (uMsg == 0x8000)
    ShowSourceWindow();

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

  else if ((uMsg == 260) /*WM_SYSKEYDOWN*/ &&
           (oSys.Call("User32::GetKeyState", 0x10 /*VK_SHIFT*/) & 0x8000))
  {
    if (wParam == 0x27) //VK_RIGHT
      MoveWindow("R");
    else if (wParam == 0x25) //VK_LEFT
      MoveWindow("L");
    else if (wParam == 0x28) //VK_DOWN
      MoveWindow("D");
    else if (wParam == 0x26) //VK_UP
      MoveWindow("U");
    else if (wParam == 0x23) //VK_END
      MoveWindow("E");
    else if (wParam == 0x24) //VK_HOME
      MoveWindow("H");
    else if (wParam == 0x22) //VK_NEXT
      MoveWindow("B");
    else if (wParam == 0x21) //VK_PRIOR
      MoveWindow("T");
    else if (wParam == 0x43) //C key
      MoveWindow("C");
  }

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

    if (nLowParam == IDSOURCELB)
    {
      if (nHiwParam == 1 /*LBN_SELCHANGE*/)
      {
        nSource = AkelPad.SendMessage(lParam, 0x0188 /*LB_GETCURSEL*/, 0, 0);
        CheckExcel();
        ShowSourceWindow();
        ShowSourceName();
        FillTargetLB();
      }
    }
    else if (nLowParam == IDOPENB)
      OpenFile();
    else if (nLowParam == IDSAVEB)
      SaveFile();
    else if ((nLowParam == IDBEFORESTARTB) ||
             (nLowParam == IDAFTERFIELDB) ||
             (nLowParam == IDAFTERROWB) ||
             (nLowParam == IDAFTERENDB) ||
             (nLowParam == IDDELAYDATAB) ||
             (nLowParam == IDDELAYKEYSB))
      CheckButtons(nLowParam);
    else if ((nLowParam == IDBEFORESTARTE) ||
             (nLowParam == IDAFTERFIELDE) ||
             (nLowParam == IDAFTERROWE) ||
             (nLowParam == IDAFTERENDE) ||
             (nLowParam == IDDELAYDATAE) ||
             (nLowParam == IDDELAYKEYSE))
    {
      if (nHiwParam == 0x0200 /*EN_KILLFOCUS*/)
        GetEditTexts();
    }
    else if ((nLowParam == IDKEYSMENUB1) || (nLowParam == IDKEYSMENUB2) ||
             (nLowParam == IDKEYSMENUB3) || (nLowParam == IDKEYSMENUB4))
      MenuKeys(nLowParam);
    else if (nLowParam == IDTARGETLB)
    {
      if (nHiwParam == 1 /*LBN_SELCHANGE*/)
        ShowTargetWindow(true);
    }
    else if (nLowParam == IDREFRESHB)
    {
      FillTargetLB();
      ShowTargetWindow(true);
    }
    else if (nLowParam == IDSENDB)
      SendData();
  }

  else if (uMsg == 16 /*WM_CLOSE*/)
  {
    ReadWriteIni(true);
    oSys.Call("User32::DestroyWindow", hWnd); //Destroy dialog
  }

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

  return 0;
}

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

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

function GetWindowPos(hWnd)
{
  var oRect  = new Object();
  var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)

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

  oRect.X = AkelPad.MemRead(_PtrAdd(lpRect,  0), 3 /*DT_DWORD*/);
  oRect.Y = AkelPad.MemRead(_PtrAdd(lpRect,  4), 3 /*DT_DWORD*/);
  oRect.W = AkelPad.MemRead(_PtrAdd(lpRect,  8), 3 /*DT_DWORD*/) - oRect.X;
  oRect.H = AkelPad.MemRead(_PtrAdd(lpRect, 12), 3 /*DT_DWORD*/) - oRect.Y;

  AkelPad.MemFree(lpRect);
  return oRect;
}

function MoveWindow(sAction)
{
  var oRectDesk = GetWindowPos(oSys.Call("User32::GetDesktopWindow"));
  var oRect     = GetWindowPos(hWndDlg);

  if (sAction == "R") //Right
    oRect.X = oRect.X + ((oRect.X < oRectDesk.X + oRectDesk.W - 50) ? 20 : 0);
  else if (sAction == "L") //Left
    oRect.X = oRect.X - ((oRect.X + oRect.W > oRectDesk.X + 50) ? 20 : 0);
  else if (sAction == "D") //Down
    oRect.Y = oRect.Y + ((oRect.Y < oRectDesk.Y + oRectDesk.H - 50) ? 20 : 0);
  else if (sAction == "U") //Up
    oRect.Y = oRect.Y - ((oRect.Y + oRect.H > oRectDesk.Y + 50) ? 20 : 0);
  else if (sAction == "E") //End (to right edge)
    oRect.X = oRectDesk.X + oRectDesk.W - oRect.W;
  else if (sAction == "H") //Home (to left edge)
    oRect.X = oRectDesk.X;
  else if (sAction == "B") //Bottom edge
    oRect.Y = oRectDesk.Y + oRectDesk.H - oRect.H;
  else if (sAction == "T") //Top edge
    oRect.Y = oRectDesk.Y;
  else if (sAction == "C") //Center
  {
    oRect.X = oRectDesk.X + oRectDesk.W / 2 - oRect.W / 2;
    oRect.Y = oRectDesk.Y + oRectDesk.H / 2 - oRect.H / 2;
  }

  oSys.Call("User32::SetWindowPos", hWndDlg, 0, oRect.X, oRect.Y, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
}

function SetWndFontAndText(hWnd, hFont, sText)
{
  AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
  oSys.Call("User32::SetWindowText" + _TCHAR, hWnd, sText);
}

function FillSourceLB()
{
  AkelPad.SendMessage(aWnd[IDSOURCELB][HWND], 0x0180 /*LB_ADDSTRING*/, 0, sTxtTextSemic);
  AkelPad.SendMessage(aWnd[IDSOURCELB][HWND], 0x0180 /*LB_ADDSTRING*/, 0, sTxtTextPipe);
  AkelPad.SendMessage(aWnd[IDSOURCELB][HWND], 0x0180 /*LB_ADDSTRING*/, 0, sTxtTextTab);

  try
  {
    if (oSys.Call("User32::FindWindow" + _TCHAR, sExcelClass, 0))
    {
      oExcel = GetObject("", "Excel.Application");
      bExcelWasRunning = true;
    }
    else
      oExcel = new ActiveXObject("Excel.Application");

    oSys.Call("User32::ShowWindow", oSys.Call("User32::FindWindow" + _TCHAR, sExcelClass, 0), 5 /*SW_SHOW*/);
    AkelPad.SendMessage(aWnd[IDSOURCELB][HWND], 0x0180 /*LB_ADDSTRING*/, 0, sTxtWorksheet);
  }
  catch (oError)
  {
    if (nSource == 3)
      --nSource;
  }

  AkelPad.SendMessage(aWnd[IDSOURCELB][HWND], 0x0186 /*LB_SETCURSEL*/, nSource, 0);
}

function ShowSourceWindow()
{
  var hWndSource = GetSourceWnd();

  if (! oSys.Call("User32::IsWindowVisible", hWndSource))
  {
    oSys.Call("User32::ShowWindow", hWndSource, 5 /*SW_SHOW*/);

    if (hWndSource == hMainWnd)
      AkelPad.SendMessage(hMainWnd, 1277 /*AKD_RESIZE*/, 0, 0);
  }

  if (oSys.Call("User32::IsIconic", hWndSource))
    oSys.Call("User32::ShowWindow", hWndSource, 9 /*SW_RESTORE*/);

  SetForegroundWindow(hWndSource);
  SetForegroundWindow(hWndDlg);
}

function GetSourceWnd()
{
  if (nSource == 3) //Excel
    return oSys.Call("User32::FindWindow" + _TCHAR, sExcelClass, 0);
  else
    return hMainWnd;
}

function SetForegroundWindow(hWndSet)
{
  var nStopTime = new Date().getTime() + 2000;

  oSys.Call("User32::SetForegroundWindow", hWndSet);

  while ((oSys.Call("User32::GetForegroundWindow", 0) != hWndSet) &&
         (new Date().getTime() < nStopTime))
    WScript.Sleep(5);
}

function ShowSourceName()
{
  var sSource;

  if (nSource == 3) //Excel
  {
    if (IsExcelBusy())
      sSource = sTxtExcelBusy;
    else
    {
      if (oExcel.Workbooks.Count)
        sSource = oExcel.ActiveWorkbook.Name + ":" + oExcel.ActiveSheet.Name;
      else
        sSource = sTxtNoOpenFiles;
    }
  }
  else
  {
    if (AkelPad.GetEditWnd())
    {
      sSource = AkelPad.GetEditFile(0).substr(AkelPad.GetEditFile(0).lastIndexOf("\\") + 1);
      if (! sSource)
        sSource = sTxtNoFileName;
    }
    else
      sSource = sTxtNoOpenFiles;
  }

  SetWndFontAndText(aWnd[IDSOURCES][HWND], hGuiFont, sSource);
}

function CheckExcel()
{
  if (nSource == 3)
  {
    var hWndExcel = oSys.Call("User32::FindWindow" + _TCHAR, sExcelClass, 0);

    if (! oSys.Call("User32::IsWindowVisible", hWndExcel))
    {
      oExcel.Quit();
      oExcel = new ActiveXObject("Excel.Application");

      hWndExcel = oSys.Call("User32::FindWindow" + _TCHAR, sExcelClass, 0);
      oSys.Call("User32::ShowWindow", hWndExcel, 5 /*SW_SHOW*/);
      if (oSys.Call("User32::IsIconic", hWndExcel))
        oSys.Call("User32::ShowWindow", hWndExcel, 9 /*SW_RESTORE*/);
    }
  }
}

function IsExcelBusy()
{
  try
  {
    oExcel.Workbooks.Count;
  }
  catch (oError)
  {
    return true;
  }

  return false;
}

function CheckButtons(nButton)
{
  if (nButton == IDBEFORESTARTB)
    bBeforeStart = ! bBeforeStart;
  else if (nButton == IDAFTERFIELDB)
    bAfterField = ! bAfterField;
  else if (nButton == IDAFTERROWB)
    bAfterRow = ! bAfterRow;
  else if (nButton == IDAFTERENDB)
    bAfterEnd = ! bAfterEnd;
  else if (nButton == IDDELAYDATAB)
    bDelayData = ! bDelayData;
  else if (nButton == IDDELAYKEYSB)
    bDelayKeys = ! bDelayKeys;

  AkelPad.SendMessage(aWnd[IDBEFORESTARTB][HWND], 241 /*BM_SETCHECK*/, bBeforeStart, 0);
  AkelPad.SendMessage(aWnd[IDAFTERFIELDB ][HWND], 241 /*BM_SETCHECK*/, bAfterField,  0);
  AkelPad.SendMessage(aWnd[IDAFTERROWB   ][HWND], 241 /*BM_SETCHECK*/, bAfterRow,    0);
  AkelPad.SendMessage(aWnd[IDAFTERENDB   ][HWND], 241 /*BM_SETCHECK*/, bAfterEnd,    0);
  AkelPad.SendMessage(aWnd[IDDELAYDATAB  ][HWND], 241 /*BM_SETCHECK*/, bDelayData,   0);
  AkelPad.SendMessage(aWnd[IDDELAYKEYSB  ][HWND], 241 /*BM_SETCHECK*/, bDelayKeys,   0);
}

function GetEditTexts()
{
  var nBufSize = 65;
  var lpBuffer = AkelPad.MemAlloc(nBufSize * _TSIZE);

  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDBEFORESTARTE][HWND], lpBuffer, nBufSize);
  sBeforeStart = AkelPad.MemRead(lpBuffer, _TSTR);
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDAFTERFIELDE][HWND], lpBuffer, nBufSize);
  sAfterField = AkelPad.MemRead(lpBuffer, _TSTR);
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDAFTERROWE][HWND], lpBuffer, nBufSize);
  sAfterRow = AkelPad.MemRead(lpBuffer, _TSTR);
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDAFTERENDE][HWND], lpBuffer, nBufSize);
  sAfterEnd = AkelPad.MemRead(lpBuffer, _TSTR);
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDDELAYDATAE][HWND], lpBuffer, nBufSize);
  sDelayData = AkelPad.MemRead(lpBuffer, _TSTR);
  oSys.Call("User32::GetWindowText" + _TCHAR, aWnd[IDDELAYKEYSE][HWND], lpBuffer, nBufSize);
  sDelayKeys = AkelPad.MemRead(lpBuffer, _TSTR);

  AkelPad.MemFree(lpBuffer);
}

function SetEditTexts()
{
  SetWndFontAndText(aWnd[IDBEFORESTARTE][HWND], hGuiFont, sBeforeStart);
  SetWndFontAndText(aWnd[IDAFTERFIELDE ][HWND], hGuiFont, sAfterField);
  SetWndFontAndText(aWnd[IDAFTERROWE   ][HWND], hGuiFont, sAfterRow);
  SetWndFontAndText(aWnd[IDAFTERENDE   ][HWND], hGuiFont, sAfterEnd);
  SetWndFontAndText(aWnd[IDDELAYDATAE  ][HWND], hGuiFont, sDelayData);
  SetWndFontAndText(aWnd[IDDELAYKEYSE  ][HWND], hGuiFont, sDelayKeys);
}

function MenuKeys(nID)
{
  var aKey =
      [["Ctrl"       , "*CTRL"],
       ["Shift"      , "*SH"],
       ["Alt"        , "*ALT"],
       ["Enter"      , "*ENT"],
       ["Esc"        , "*ESC"],
       ["Insert"     , "*INS"],
       ["Delete"     , "*DEL"],
       ["BackSpace"  , "*BS"],
       ["Tab"        , "*TAB"],
       ["Down"       , "*DN"],
       ["Up"         , "*UP"],
       ["Right"      , "*RT"],
       ["Left"       , "*LT"],
       ["Page Down"  , "*PGDN"],
       ["Page Up"    , "*PGUP"],
       ["End"        , "*END"],
       ["Home"       , "*HOME"],
       ["F1"         , "*F1"],
       ["F2"         , "*F2"],
       ["F3"         , "*F3"],
       ["F4"         , "*F4"],
       ["F5"         , "*F5"],
       ["F6"         , "*F6"],
       ["F7"         , "*F7"],
       ["F8"         , "*F8"],
       ["F9"         , "*F9"],
       ["F10"        , "*F10"],
       ["F11"        , "*F11"],
       ["F12"        , "*F12"],
       ["+"          , "*+"],
       ["^"          , "*^"],
       ["%"          , "*%"],
       ["~"          , "*~"],
       ["("          , "*("],
       [")"          , "*)"],
       ["["          , "*["],
       ["]"          , "*]"],
       ["{"          , "*{"],
       ["}"          , "*}"],
       ["delay (ms)" , "*100"]];
  var oRect = GetWindowPos(aWnd[nID][HWND]);
  var hMenu = oSys.Call("User32::CreatePopupMenu");
  var nFlag;
  var nCmd;
  var i;

  for (i = 0; i < aKey.length; ++i)
  {
    if (i == Math.ceil(aKey.length / 2))
      nFlag = 0x60; //MF_MENUBREAK|MF_MENUBARBREAK|MF_STRING
    else
      nFlag = 0x00; //MF_STRING

    oSys.Call("User32::AppendMenu" + _TCHAR, hMenu, nFlag, i + 1, aKey[i][0] + "\t" + aKey[i][1]);
  }

  nCmd = oSys.Call("User32::TrackPopupMenu", hMenu, 0x188 /*TPM_RETURNCMD|TPM_NONOTIFY|TPM_RIGHTALIGN*/,
                   oRect.X + oRect.W, oRect.Y + oRect.H, 0, hWndDlg, 0);
  oSys.Call("User32::DestroyMenu", hMenu);

  if (nCmd)
    AkelPad.SendMessage(aWnd[nID - 1][HWND], 0x00C2 /*EM_REPLACESEL*/, 1, aKey[nCmd - 1][1]);
}

function GetParametersSourceFile()
{
  var oRE = GetParametersRegExp();
  var aString;
  var sFile;
  var sStream;

  if (nSource == 3) //Excel
  {
    if (! IsExcelBusy())
    {
      if (oExcel.Workbooks.Count &&
          ActiveSheetIsWorksheet() &&
          oExcel.ActiveSheet.Range("A1").Comment)
        aString = oRE.exec(oExcel.ActiveSheet.Range("A1").Comment.Text());
    }
  }
  else
  {
    sFile   = AkelPad.GetEditFile(0);
    sStream = sScriptName + "Paramaters";

    if (IsSupportStreams(sFile.substr(0, 3)))
    {
      if (IsStreamExists(sFile, sStream))
        aString = oRE.exec(AkelPad.ReadFile(sFile + ":" + sStream));
    }
  }

  try
  {
    eval(aString[0]);
  }
  catch (oError)
  {
  }
}

function ActiveSheetIsWorksheet(bMessage)
{
  if (oExcel.ActiveSheet.Type == -4167 /*xlWorksheet*/)
    return true;
  else
  {
    if (bMessage)
      AkelPad.MessageBox(hWndDlg, sTxtNoWorksheet, sScriptName, 0x00000030 /*MB_ICONWARNING*/);
    return false;
  }
}

function GetParametersRegExp()
{
  var oMarker = GetParametersMarker();

  return new RegExp(Escape(oMarker.Begin) + "[\\s\\S]*" + Escape(oMarker.End));
}

function GetParametersMarker()
{
  return {Begin : "/*Begin SendData parameters block*/",
          End   : "/*End SendData parameters block*/"};
}

function Escape(sText)
{
  return sText.replace(/[\\\/.^$+*?|()\[\]{}]/g, "\\$&");
}

function OpenFile()
{
  var hWndSource = GetSourceWnd();

  SetForegroundWindow(hWndSource);
  WScript.Sleep(10);

  if (nSource == 3) //Excel
  {
    if (IsExcelBusy())
      AkelPad.MessageBox(hWndSource, sTxtUnableExec, sScriptName, 0x00000030 /*MB_ICONWARNING*/);
    else
      oWshShell.SendKeys("^o");
  }
  else
    AkelPad.Command(4103); //IDM_FILE_OPEN
}

function SaveFile()
{
  var hWndSource = GetSourceWnd();
  var oRE        = GetParametersRegExp();
  var oMarker    = GetParametersMarker();
  var sText      =
        oMarker.Begin + "\n" +
        'bBeforeStart='  + bBeforeStart + ';\n' +
        'bAfterField='   + bAfterField  + ';\n' +
        'bAfterRow='     + bAfterRow    + ';\n' +
        'bAfterEnd='     + bAfterEnd    + ';\n' +
        'bDelayData='    + bDelayData   + ';\n' +
        'bDelayKeys='    + bDelayKeys   + ';\n' +
        'sBeforeStart="' + sBeforeStart.replace(/[\\"]/g, "\\$&") + '";\n' +
        'sAfterField="'  + sAfterField.replace(/[\\"]/g, "\\$&")  + '";\n' +
        'sAfterRow="'    + sAfterRow.replace(/[\\"]/g, "\\$&")    + '";\n' +
        'sAfterEnd="'    + sAfterEnd.replace(/[\\"]/g, "\\$&")    + '";\n' +
        'sDelayData="'   + sDelayData   + '";\n' +
        'sDelayKeys="'   + sDelayKeys   + '";\n' +
        oMarker.End;
  var sFile;
  var sStream;
  var sOldText;
  var hMenuMain;
  var nWatchState;

  if (nSource == 3) //Excel
  {
    if (IsExcelBusy())
    {
      SetForegroundWindow(hWndSource);
      AkelPad.MessageBox(hWndSource, sTxtUnableExec, sScriptName, 0x00000030 /*MB_ICONWARNING*/);
    }
    else if ((oExcel.Workbooks.Count) && (ActiveSheetIsWorksheet(1)) && (WantSave()))
    {
      SetForegroundWindow(hWndSource);

      if (oExcel.ActiveSheet.Range("A1").Comment)
      {
        sOldText = oExcel.ActiveSheet.Range("A1").Comment.Text();
        if (oRE.test(sOldText))
          sText = sOldText.replace(oRE, sText);
        else if (sOldText)
          sText = sOldText + "\n" + sText;

        oExcel.ActiveSheet.Range("A1").Comment.Text(sText);
      }
      else
        oExcel.ActiveSheet.Range("A1").AddComment(sText);

      oExcel.ActiveSheet.Range("A1").Comment.Visible = false;
      oExcel.ActiveWorkbook.Save();

      SetForegroundWindow(hWndDlg);
    }
  }

  else if (AkelPad.GetEditWnd() && (WantSave()))
  {
    SetForegroundWindow(hWndSource);

    sFile        = AkelPad.GetEditFile(0);
    sStream      = sScriptName + "Paramaters";
    nWatchState  = 0;

    if (IsSupportStreams(sFile.substr(0, 3)))
    {
      hMenuMain   = AkelPad.SendMessage(hMainWnd, 1222 /*AKD_GETMAININFO*/, 21 /*MI_MENUMAIN*/, 0);
      nWatchState = oSys.Call("User32::GetMenuState", hMenuMain, 4253 /*IDM_OPTIONS_WATCHFILE*/, 0 /*MF_BYCOMMAND*/);

      if (nWatchState & 0x8 /*MF_CHECKED*/)
        AkelPad.Command(4253 /*IDM_OPTIONS_WATCHFILE*/);

      if (IsStreamExists(sFile, sStream))
      {
        sOldText = AkelPad.ReadFile(sFile + ":" + sStream);
        if (oRE.test(sOldText))
          sText = sOldText.replace(oRE, sText);
        else if (sOldText)
          sText = sOldText + "\n" + sText;
      }
      else
        CreateFile(sFile, sStream);

      WriteFile(sFile, sStream, sText, 1);
    }

    AkelPad.Command(4105); //IDM_FILE_SAVE
    AkelPad.Command(4104); //IDM_FILE_REOPEN

    if (nWatchState & 0x8 /*MF_CHECKED*/)
      AkelPad.Command(4253 /*IDM_OPTIONS_WATCHFILE*/);

    SetForegroundWindow(hWndDlg);
  }
}

function WantSave()
{
  var sFileName;

  if (nSource == 3) //Excel
     sFileName = oExcel.ActiveWorkbook.Name;
  else
  {
    sFileName = AkelPad.GetEditFile(0).substr(AkelPad.GetEditFile(0).lastIndexOf("\\") + 1);
    if (! sFileName)
      sFileName = sTxtNoFileName;
  }

  if (AkelPad.MessageBox(hWndDlg, sTxtWantSave + "\n" + sFileName, sScriptName,
                         0x00000021 /*MB_DEFBUTTON1|MB_ICONQUESTION|MB_OKCANCEL*/) == 1 /*IDOK*/)
    return true;
  else
    return false;
}

function FillTargetLB()
{
  var nPosSel  = AkelPad.SendMessage(aWnd[IDTARGETLB][HWND], 0x0188 /*LB_GETCURSEL*/, 0, 0);
  var hWndSel  = GetTargetWnd();
  var aListWnd = EnumWindows();
  var nPos;
  var i;

  aListWnd.sort(
    function(oWndA, oWndB)
    {
      return oSys.Call("Kernel32::lstrcmpi" + _TCHAR,
                       oWndA.Title + "  " + oWndA.Handle,
                       oWndB.Title + "  " + oWndB.Handle);
    });

  AkelPad.SendMessage(aWnd[IDTARGETLB][HWND], 0x0184 /*LB_RESETCONTENT*/, 0, 0);

  for (i = 0; i < aListWnd.length; ++i)
  {
    nPos = AkelPad.SendMessage(aWnd[IDTARGETLB][HWND], 0x0180 /*LB_ADDSTRING*/, 0, aListWnd[i].Title);
    AkelPad.SendMessage(aWnd[IDTARGETLB][HWND], 0x019A /*LB_SETITEMDATA*/, nPos, aListWnd[i].Handle);
  }

  if (nPosSel >= 0)
  {
    nPos = -1;
    for (i = 0; i < aListWnd.length; ++i)
    {
      if (hWndSel == aListWnd[i].Handle)
      {
        nPos = i;
        break;
      }
    }

    if (nPos == -1)
    {
      if (nPosSel < aListWnd.length)
        nPos = nPosSel;
      else
        nPos = aListWnd.length - 1;
    }
  }
  else
    nPos = 0;

  AkelPad.SendMessage(aWnd[IDTARGETLB][HWND], 0x0186 /*LB_SETCURSEL*/, nPos, 0);
}

function EnumWindows()
{
  var aWnd       = [];
  var hWndSource = GetSourceWnd();
  var lpInfo;
  var sTitle;
  var bVisible;
  var bToolWin;
  var nX1;
  var nX2;
  var nY1;
  var nY2;
  var sClass;
  var hProcess;
  var sBaseName;

  try
  {
    oSys.RegisterCallback(EnumWindowsProc);
  }
  catch (oError)
  {
    return aWnd;
  }

  lpInfo = AkelPad.MemAlloc(260 * _TSIZE);

  oSys.Call("User32::EnumWindows", EnumWindowsProc, 0);

  oSys.UnregisterCallback(EnumWindowsProc);
  AkelPad.MemFree(lpInfo);

  return aWnd;

  function EnumWindowsProc(hWnd, lParam)
  {
    if (oSys.Call("User32::GetWindowText" + _TCHAR, hWnd, lpInfo, 260))
      sTitle = AkelPad.MemRead(lpInfo, _TSTR);
    else
      sTitle = "";

    bVisible = oSys.Call("User32::IsWindowVisible", hWnd);
    bToolWin = oSys.Call("User32::GetWindowLong" + _TCHAR, hWnd, -20 /*GWL_EXSTYLE*/) & 0x00000080 /*WS_EX_TOOLWINDOW*/;

    if (oSys.Call("User32::GetWindowRect", hWnd, lpInfo))
    {
      nX1 = AkelPad.MemRead(_PtrAdd(lpInfo,  0), 3 /*DT_DWORD*/);
      nY1 = AkelPad.MemRead(_PtrAdd(lpInfo,  4), 3 /*DT_DWORD*/);
      nX2 = AkelPad.MemRead(_PtrAdd(lpInfo,  8), 3 /*DT_DWORD*/);
      nY2 = AkelPad.MemRead(_PtrAdd(lpInfo, 12), 3 /*DT_DWORD*/);
    }
    else
    {
      nX1 = 0;
      nY1 = 0;
      nX2 = 0;
      nY2 = 0;
    }

    if (oSys.Call("User32::GetClassName" + _TCHAR, hWnd, lpInfo, 260))
      sClass = AkelPad.MemRead(lpInfo, _TSTR);
    else
      sClass = "";

    oSys.Call("User32::GetWindowThreadProcessId", hWnd, lpInfo);
    hProcess = oSys.Call("Kernel32::OpenProcess", 0x0410 /*PROCESS_QUERY_INFORMATION|PROCESS_VM_READ*/, 0, AkelPad.MemRead(lpInfo, 3 /*DT_DWORD*/) /*PID*/);

    if (oSys.Call("Psapi::GetModuleBaseName" + _TCHAR, hProcess, 0, lpInfo, 260))
      sBaseName = AkelPad.MemRead(lpInfo, _TSTR);
    else
      sBaseName = "";

    oSys.Call("Kernel32::CloseHandle", hProcess);

    if (sTitle && bVisible && (nX2 - nX1) && (nY2 - nY1) && (! bToolWin) &&
        (hWnd != hWndDlg) && (hWnd != hWndSource) &&
        (((sBaseName == "EXCEL.EXE") && (sClass == sExcelClass)) || (sBaseName != "EXCEL.EXE")))
      aWnd.push({Handle : hWnd, Title : sTitle});

    return true;
  }
}

function ShowTargetWindow(bRestoreDialog)
{
  var hWndTarget = GetTargetWnd();

  if ((hWndTarget) && (IsWindow(hWndTarget)))
  {
    oSys.Call("User32::ShowWindow", hWndTarget, 5 /*SW_SHOW*/);

    if (oSys.Call("User32::IsIconic", hWndTarget))
      oSys.Call("User32::ShowWindow", hWndTarget, 9 /*SW_RESTORE*/);

    SetForegroundWindow(hWndTarget);

    if (bRestoreDialog)
      SetForegroundWindow(hWndDlg);

    return true;
  }
  else
    return false;
}

function GetTargetWnd()
{
  var nPos = AkelPad.SendMessage(aWnd[IDTARGETLB][HWND], 0x0188 /*LB_GETCURSEL*/, 0, 0);

  if (nPos >= 0)
    return AkelPad.SendMessage(aWnd[IDTARGETLB][HWND], 0x0199 /*LB_GETITEMDATA*/, nPos, 0);
  else
    return 0;
}

function IsWindow(hWnd)
{
  if (oSys.Call("User32::IsWindow", hWnd))
    return true;
  else
  {
    if (AkelPad.MessageBox(hWndDlg, sTxtWinClosed, sScriptName,
                           0x00000031 /*MB_DEFBUTTON1|MB_ICONWARNING|MB_OKCANCEL*/) == 1 /*IDOK*/)
      FillTargetLB();
    return false;
  }
}

function SendData()
{
  var bTerminate = false;
  var nSentRows  = 0;
  var nTotalRows = 0;
  var oSheet;
  var nR1;
  var nC1;
  var nR2;
  var nC2;
  var sSep;
  var nBegSel;
  var aField;
  var oHwnd;
  var nFieldType;
  var r, c;

  if ((! IsDataToSend()) || (! ShowTargetWindow(false)))
    return;

  oSys.Call("User32::ShowWindow", hWndDlg, 7 /*SW_SHOWMINNOACTIVE*/);

  oHwnd = CreateSendStatusWindow();

  if (bBeforeStart)
    SendKeys(sBeforeStart, oHwnd);

  if (nSource == 3) //Excel
  {
    oSheet = oExcel.ActiveSheet;
    nR1    = oExcel.Selection.Row;
    nC1    = oExcel.Selection.Column;
    nR2    = nR1 + oExcel.Selection.Rows.Count - 1;
    nC2    = nC1 + oExcel.Selection.Columns.Count - 1;

    for (r = nR1; r <= nR2; ++r)
    {
      if (! oSheet.Rows(r).Hidden)
        ++nTotalRows;
    }

    SetWndFontAndText(oHwnd.SentRows, hGuiFont, sTxtNumRows + " 0/" + nTotalRows);

    for (r = nR1; r <= nR2; ++r)
    {
      if (! oSheet.Rows(r).Hidden)
      {
        for (c = nC1; c <= nC2; ++c)
        {
          if (! oSheet.Columns(c).Hidden)
          {
            SetWndFontAndText(oHwnd.CurCell, hGuiFont,
                              sTxtRow + r + "         "  + sTxtColumn + c + "        " +
                              sTxtCell + oSheet.Cells(r, c).AddressLocal(0 /*RowAbsolute*/, 0 /*ColumnAbsolute*/));

            nFieldType = SendKeys(oSheet.Cells(r, c).Text, oHwnd);

            if ((c < nC2) && (bAfterField) && (nFieldType == 0))
              SendKeys(sAfterField, oHwnd);

            if (bTerminate = TerminateSend())
              break;
          }
        }

        if (bTerminate)
          break;

        SetWndFontAndText(oHwnd.SentRows, hGuiFont, sTxtNumRows + " " + (++nSentRows) + "/" + nTotalRows);

        if ((r < nR2) && (bAfterRow))
          SendKeys(sAfterRow, oHwnd);
      }
    }

    if (bTerminate)
    {
      oSheet.Range(oSheet.Cells(r, nC1), oSheet.Cells(nR2, nC2)).Select();
      oSheet.Cells(r, c).Activate();
    }
    else
      oSheet.Cells(nR2, nC2).Select();
  }

  else
  {
    if (nSource == 0)
      sSep = ";";
    else if (nSource == 1)
      sSep = "|";
    else
      sSep = "\t";

    nBegSel = AkelPad.GetSelStart();
    aField  = AkelPad.GetSelText().split("\r");

    SetWndFontAndText(oHwnd.SentRows, hGuiFont, sTxtNumRows + " 0/" + aField.length);

    for (r = 0; r < aField.length; ++r)
    {
      aField[r] = aField[r].split(sSep);

      for (c = 0; c < aField[r].length; ++c)
      {
        SetWndFontAndText(oHwnd.CurCell, hGuiFont,
                          sTxtRow + (r + 1) + "         "  + sTxtColumn + (c + 1) + "        " +
                          sTxtOffset + nBegSel);

        nFieldType = SendKeys(aField[r][c], oHwnd);
        nBegSel   += aField[r][c].length + 1;

        if ((c < aField[r].length - 1) && (bAfterField) && (nFieldType == 0))
          SendKeys(sAfterField, oHwnd);

        if (bTerminate = TerminateSend())
          break;
      }

      if (bTerminate)
        break;

      SetWndFontAndText(oHwnd.SentRows, hGuiFont, sTxtNumRows + " " + (++nSentRows) + "/" + aField.length);

      if ((r < aField.length - 1) && (bAfterRow))
        SendKeys(sAfterRow, oHwnd);
    }

    if (nBegSel > AkelPad.GetSelEnd())
      nBegSel = AkelPad.GetSelEnd();

    AkelPad.SetSel(AkelPad.GetSelEnd(), nBegSel);
  }

  if (bAfterEnd && (! bTerminate))
    SendKeys(sAfterEnd, oHwnd);

  if (! bTerminate)
    AkelPad.MessageBox(GetTargetWnd(), sTxtEndSend, sScriptName, 0x00000040 /*MB_ICONINFORMATION*/);

  oSys.Call("User32::DestroyWindow", oHwnd.Main);
  oSys.Call("User32::ShowWindow", hWndDlg, 1 /*SW_SHOWNORMAL*/);

}

function IsDataToSend()
{
  var bIsData = false;

  if (nSource == 3) //Excel
  {
    if (IsExcelBusy())
      AkelPad.MessageBox(hWndDlg, sTxtUnableExec, sScriptName, 0x00000030 /*MB_ICONWARNING*/);
    else if (! oExcel.Workbooks.Count)
      AkelPad.MessageBox(hWndDlg, sTxtNoWorkbook, sScriptName, 0x00000030 /*MB_ICONWARNING*/);
    else if (ActiveSheetIsWorksheet(1))
    {
      if ((oExcel.Selection.Areas(1).Rows.Count == 1) &&
          (oExcel.Selection.Areas(1).Columns.Count == 1))
        AkelPad.MessageBox(hWndDlg, sTxtNoSelection, sScriptName, 0x00000030 /*MB_ICONWARNING*/);
      else
        bIsData = true;
    }
  }
  else
  {
    if (! AkelPad.GetEditWnd())
      AkelPad.MessageBox(hWndDlg, sTxtNoOpenText, sScriptName, 0x00000030 /*MB_ICONWARNING*/);
    else if (AkelPad.GetSelStart() == AkelPad.GetSelEnd())
      AkelPad.MessageBox(hWndDlg, sTxtNoSelection, sScriptName, 0x00000030 /*MB_ICONWARNING*/);
    else
      bIsData = true;
  }

  return bIsData;
}

function SendKeys(sField, oHwnd)
{
  var nFieldType;
  var aKeys;
  var aDelay;
  var i;

  SetWndFontAndText(oHwnd.CurSent, hGuiFont, sTxtCurSent + sField);

  //Keys and delay field
  if ((sField.length > 1) && (sField.charAt(0) == "\\") && (sField.charAt(1) != "\\"))
  {
    nFieldType = 1;
    aKeys      = sField.substr(1).split(/\*\d+/);
    aDelay     = sField.substr(1).match(/\*\d+/g);

    if (aKeys.length)
    {
      for (i = 0; i < aKeys.length; ++i)
      {
        if (aKeys[i])
        {
          aKeys[i] = GetStringKeys(aKeys[i]);

          try
          {
            oWshShell.SendKeys(aKeys[i]);
          }
          catch (oError)
          {
            SetWndFontAndText(oHwnd.Error, hGuiFont, sTxtKeysError + sField);
          }
        }

        if (aDelay && (i < aDelay.length))
          WScript.Sleep(Number(aDelay[i].substr(1)));
      }
    }
    else if(aDelay && aDelay.length)
    {
      for (i = 0; i < aDelay.length; ++i)
        WScript.Sleep(Number(aDelay[i].substr(1)));
    }

    if (bDelayKeys)
      WScript.Sleep(Number(sDelayKeys));
  }

  //Data field
  else
  {
    nFieldType = 0;
    sField     = sField.replace(/[\{\}\[\]\(\)\+\^%~]/g, "{$&}");

    if ((sField.length > 1) && (sField.charAt(0) == "\\"))
      sField = sField.substr(1);

    if (sField)
    {
      oWshShell.SendKeys(sField);

      if (bDelayKeys)
        WScript.Sleep(Number(sDelayData));
    }
  }

  return nFieldType;
}

function GetStringKeys(sKeys)
{
  var oKey =
      {"*CTRL"  : "^",
       "*SH"    : "+",
       "*ALT"   : "%",
       "*ENT"   : "~",
       "*ESC"   : "{ESC}",
       "*INS"   : "{INS}",
       "*DEL"   : "{DEL}",
       "*BS"    : "{BS}",
       "*TAB"   : "{TAB}",
       "*DN"    : "{DOWN}",
       "*UP"    : "{UP}",
       "*RT"    : "{RIGHT}",
       "*LT"    : "{LEFT}",
       "*PGDN"  : "{PGDN}",
       "*PGUP"  : "{PGUP}",
       "*END"   : "{END}",
       "*HOME"  : "{HOME}",
       "*F12"   : "{F12}",
       "*F11"   : "{F11}",
       "*F10"   : "{F10}",
       "*F9"    : "{F9}",
       "*F8"    : "{F8}",
       "*F7"    : "{F7}",
       "*F6"    : "{F6}",
       "*F5"    : "{F5}",
       "*F4"    : "{F4}",
       "*F3"    : "{F3}",
       "*F2"    : "{F2}",
       "*F1"    : "{F1}",
       "*+"     : "{+}",
       "*^"     : "{^}",
       "*%"     : "{%}",
       "*~"     : "{~}",
       "*("     : "{(}",
       "*)"     : "{)}",
       "*["     : "{[}",
       "*]"     : "{]}",
       "*{"     : "{{}",
       "*}"     : "{}}"};
  var sPattern = "";
  var n;

  for (n in oKey)
    sPattern += "(" + Escape(n) + ")|";

  sPattern = sPattern.slice(0, -1);

  sKeys = sKeys.replace(new RegExp(sPattern, "g"),
                        function(sSubKey)
                        {
                          return oKey[sSubKey];
                        } );
  return sKeys;
}

function TerminateSend()
{
  if (oSys.Call("User32::GetAsyncKeyState", 0x1B /*VK_ESCAPE*/) < 0)
  {
    if (AkelPad.MessageBox(GetTargetWnd(), sTxtTerminate, sScriptName,
                           0x00000024 /*MB_DEFBUTTON1|MB_ICONQUESTION|MB_YESNO*/) == 6 /*IDYES*/)
      return true;
  }

  return false;
}

function CreateSendStatusWindow()
{
//                              X,  Y,   W
  var aWndStat = [["CurSent",  10, 10, 999],
                  ["CurCell",  50, 30, 300],
                  ["SentRows", 10, 50, 330],
                  ["Error",    10, 70, 999]];
  var oHwnd  = {};
  var sTitle = sScriptName +": " + sTxtPressEsc;
  var oRect  = GetWindowPos(oSys.Call("User32::GetDesktopWindow"));
  var nW     = 350;
  var nH     = 120;
  var i;

  oHwnd.Main =
    oSys.Call("User32::CreateWindowEx" + _TCHAR,
              0x00000008,   //WS_EX_TOPMOST
              sClassName,   //lpClassName
              sTitle,       //lpWindowName
              0x90C00000,   //WS_VISIBLE|WS_POPUP|WS_CAPTION
              oRect.W - nW, //x
              0,            //y
              nW,           //nWidth
              nH,           //nHeight
              hWndDlg,      //hWndParent
              0,            //ID
              hInstanceDLL, //hInstance
              0);           //lpParam

  for (i = 0; i < aWndStat.length; ++i)
  {
    oHwnd[aWndStat[i][0]] =
      oSys.Call("User32::CreateWindowEx" + _TCHAR,
                0x00000000,     //dwExStyle
                "STATIC",       //lpClassName
                0,              //lpWindowName
                0x50000000,     //dwStyle
                aWndStat[i][1], //x
                aWndStat[i][2], //y
                aWndStat[i][3], //nWidth
                13,             //nHeight
                oHwnd.Main,     //hWndParent
                0,              //ID
                hInstanceDLL,   //hInstance
                0);             //lpParam
  }

  SetWndFontAndText(oHwnd.Error, hGuiFont, sTxtNoErrors);
  return oHwnd;
}

function ReadWriteIni(bWrite)
{
  var oFSO     = new ActiveXObject("Scripting.FileSystemObject");
  var sIniFile = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini";
  var sIniTxt;
  var oFile;
  var oRect;
  var i;

  if (bWrite)
  {
    GetEditTexts();
    oRect   = GetWindowPos(hWndDlg);
    sIniTxt =
      'nWndX='         + oRect.X      + ';\r\n' +
      'nWndY='         + oRect.Y      + ';\r\n' +
      'nSource='       + nSource      + ';\r\n' +
      'bBeforeStart='  + bBeforeStart + ';\r\n' +
      'bAfterField='   + bAfterField  + ';\r\n' +
      'bAfterRow='     + bAfterRow    + ';\r\n' +
      'bAfterEnd='     + bAfterEnd    + ';\r\n' +
      'bDelayData='    + bDelayData   + ';\r\n' +
      'bDelayKeys='    + bDelayKeys   + ';\r\n' +
      'sBeforeStart="' + sBeforeStart.replace(/[\\"]/g, "\\$&") + '";\r\n' +
      'sAfterField="'  + sAfterField.replace(/[\\"]/g, "\\$&")  + '";\r\n' +
      'sAfterRow="'    + sAfterRow.replace(/[\\"]/g, "\\$&")    + '";\r\n' +
      'sAfterEnd="'    + sAfterEnd.replace(/[\\"]/g, "\\$&")    + '";\r\n' +
      'sDelayData="'   + sDelayData   + '";\r\n' +
      'sDelayKeys="'   + sDelayKeys   + '";';

    oFile = oFSO.OpenTextFile(sIniFile, 2, true, -1);
    oFile.Write(sIniTxt);
    oFile.Close();
  }

  else if (oFSO.FileExists(sIniFile))
  {
    try
    {
      eval(AkelPad.ReadFile(sIniFile));
    }
    catch (oError)
    {
    }
  }
}
Last edited by KDJ on Thu Jan 08, 2015 8:37 pm, edited 11 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Help files for SendData.js

English:

Code: Select all

*** Description of SendData.js for AkelPad ***

Script SendData is used to send data and keystrokes from an open text file
or Excel worksheet into active window of another application.
In particular, it may be useful to load data into database tables.

Usage:
- in AkelPad window:
  Call("Scripts::Main", 1, "SendData.js")
- form command line:
  AkelPad.exe /Show(0) /Call("Scripts::Main", 2, "SendData.js") /quit

To send the data uses SendKeys method of WshShell object:
http://msdn.microsoft.com/en-us/library/8c6yea83%28v=VS.85%29.aspx

In source file, we can distinguish two types of fields:
- fields that contain data,
- fields containing keystrokes and delays.

In the text file, fields should be separated by char: ";", "|" or TAB.
In the single file should be used one type of field separator.
In Excel worksheet, each field is placed in a separate cell.

Data fields can contain any string of characters, that will be sent to the
target window. If the first character of send string is backslash "\",
then such the string should be preceded by an additional backslash character.
So to send "\AbC", you should use "\\AbC".

Field with keystrokes and delays must begin with a single backslash "\".

In order to send special keys, you must use the symbols by the following
statement:
Ctrl       : *CTRL
Shift      : *SH
Alt        : *ALT
Enter      : *ENT
Esc        : *ESC
Insert     : *INS
Delete     : *DEL
BackSpace  : *BS
Tab        : *TAB
Down arrow : *DN
Up arrow   : *UP
Right arrow: *RT
Left arrow : *LT
Page Down  : *PGDN
Page Up    : *PGUP
End        : *END
Home       : *HOME
F1         : *F1
F2         : *F2
F3         : *F3
F4         : *F4
F5         : *F5
F6         : *F6
F7         : *F7
F8         : *F8
F9         : *F9
F10        : *F10
F11        : *F11
F12        : *F12
+          : *+
^          : *^
%          : *%
~          : *~
(          : *(
)          : *)
[          : *[
]          : *]
{          : *{
}          : *}

Combination keys with Ctrl, Shift and Alt:
\*ALTaso
means pressing A while holding down the Alt key,
and then release the Alt key and pressing the sequence S and O.
\*ALT(aso)
means sequentially pressing the keys A, S, O while holding down the Alt key.

Should be use lowercase letters to identify the keystrokes that returns letter
character.

Delays:
*n
where n is the delay in milliseconds (an integer), eg:
\*2000 - stop sending data by 2 seconds.

In one field can be combined keystrokes and delays:
\*CTRL(vp)*500ALTw*100*F1*DN*TAB

Note:
Option "Save file", additionally saves parameters set in the program.
In the case of text file, the parameters are saved in NTFS file-stream
named "SendDataParameters". If the file system does not support NTFS streams,
the parameters are not saved.
In the case of Excel workbook, the parameters are saved as a comment in cell A1.

Keyboard shortcuts available in the dialog box of program:
Shift+Alt+Right, Left, Down, Up, End, Home, PgDn, PgUp, C - move dialog box,
Esc - close program.


Polish:

Code: Select all

*** Opis SendData.js dla AkelPad'a ***

Skrypt SendData służy do wysyłania danych i naciśnięć klawiszy z otwartego
pliku tekstowego lub arkusza Excela do aktywnego okna innej aplikacji.
W szczególności może być przydatny do wypełniania tabel baz danych.

Uruchomienie:
- w oknie AkelPad'a:
  Call("Scripts::Main", 1, "SendData.js")
- z linii poleceń:
  AkelPad.exe /Show(0) /Call("Scripts::Main", 2, "SendData.js") /quit

Do wysyłania danych wykorzystano metodę SendKeys obiektu WshShell:
http://msdn.microsoft.com/en-us/library/8c6yea83%28v=VS.85%29.aspx

W pliku źródłowym możemy wyróżnić dwa rodzaje pól:
- pola zawierające dane,
- pola zawierające klawisze sterujące i opóźnienia.

W pliku tekstowym, pola oddzielamy znakiem: ";", "|" lub TAB. W jednym pliku
należy stosować jeden rodzaj separatora pól.
W arkuszu Excela każde pole umieszczamy w oddzielnej komórce.

Pola danych mogą zawierać dowolny ciąg znaków, który zostanie wysłany do okna
docelowego. Jeśli pierwszym znakiem wysyłanego ciągu ma być backslash "\", to
należy taki ciąg poprzedzić dodatkowym znakiem backslash. Czyli żeby wysłać
"\AbC", należy użyć ciągu "\\AbC".

Pola klawiszy sterujących i opóźnień muszą zaczynać się pojedynczym znakiem
backslash "\".

W celu wysłania klawiszy specjalnych, należy posłużyć się symbolami według
poniższego zestawienia:
Ctrl       : *CTRL
Shift      : *SH
Alt        : *ALT
Enter      : *ENT
Esc        : *ESC
Insert     : *INS
Delete     : *DEL
BackSpace  : *BS
Tab        : *TAB
Down arrow : *DN
Up arrow   : *UP
Right arrow: *RT
Left arrow : *LT
Page Down  : *PGDN
Page Up    : *PGUP
End        : *END
Home       : *HOME
F1         : *F1
F2         : *F2
F3         : *F3
F4         : *F4
F5         : *F5
F6         : *F6
F7         : *F7
F8         : *F8
F9         : *F9
F10        : *F10
F11        : *F11
F12        : *F12
+          : *+
^          : *^
%          : *%
~          : *~
(          : *(
)          : *)
[          : *[
]          : *]
{          : *{
}          : *}

Łączenie klawiszy z Ctrl, Shift i Alt:
\*ALTaso
oznacza wciśnięcie klawisza A przy wciśniętym klawiszu Alt,
a następnie zwolnienie klawisza Alt i wciśnięcie kolejno S i O.
\*ALT(aso)
oznacza wciśnięcie kolejno klawiszy A, S, O przy wciśniętym klawiszu Alt.

Należy używać małych liter dla określenia klawiszy zwracających znak litery.

Opóźnienia:
*n
gdzie n oznacza opóźnienie w milisekundach (liczba całkowita), np:
\*2000 - wstrzymanie wysyłania danych przez 2 sekundy.

W jednym polu można łączyć klawisze i opóźnienia:
\*CTRL(vp)*500ALTw*100*F1*DN*TAB

Uwaga:
Opcja "Zapisz plik" dodatkowo zapisuje parametry ustawione w programie.
W przypadku pliku tekstowego, parametry są zapisywane w strumieniu plikowym NTFS
o nazwie "SendDataParameters". Jeśli system plików nie obsługuje strumieni, to
parametry nie są zapisywane.
W przypadku arkusza Excel, parametry są zapisywane jako komentarz w komórce A1.

Skróty klawiaturowe dostępne w oknie dialogowym programu:
Shift+Alt+Right, Left, Down, Up, End, Home, PgDn, PgUp, C - przesuwa okno,
Esc - zamyka program.
Last edited by KDJ on Mon Nov 03, 2014 7:14 pm, edited 2 times in total.

Offline
Posts: 2247
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

Resident script, which allows to restore recently closed documents.
Repository

Code: Select all

// === Closed document history collector ===
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=16205#p16205
// http://sourceforge.net/projects/feyfre.u/files/Akelpad%20plugins/Scripts/history/
// FeyFre (c) 2011-2014
// v0.14 (2014.12.20) Fixed crash since AkelPad v4.9.1
// v0.13 (2014.10.12) Now hotkey-assigend functions are externally callable
// v0.12 (2014.04.20) Cleaning list of no more existing items function. Bugfixes.
// v0.11.3 (2014.04.19) New Scripts plugin compatibility(continued)
// v0.11.2 (2014.04.12) New Scripts plugin compatibility
// v0.11.1 (2012.10.07) Fixed "Persistent storage UI option"; tooltips for testing should be unlcoked manually
// v0.11 (2012.09.14) Perzsistent storage UI option
// v0.10.1 (2012.09.14) Sync with AkelPad API
// v0.10 Dock anywhere + SmartRun
// v0.9 Filtering
// v0.8.2 3.12
// v0.8.1 3.12
// v0.8 Persist history
// v0.7 Internal reforge
// v0.6 Added hidden mode: hotkey+button
// v0.5.2
// v0.5.1
// v0.5 Reopen by keyboard. Hotkeys editing.
// v0.4 Set standart system font. No autofocus on dockbar creation(it useless anyway now). Manual hotkey setup.
// v0.3 Added hotkeys: ALT+Z, CTRL+SHIFT+ALT+Z - single and whole reopen.
// v0.2 Some fixes, optimisations. Persistent settings.
// v0.1 Initial public release
//
// Example:
//	Call("Scripts::Main", 1, "History.js")
//
//	SmartRun Call
//	Call("Scripts::Main", 1, "History.js","sr")
//		Run if absent
//		Show if hidden
//		Close if visible
//
//	Autostart it.
//	AkelPad.ini or registry key CmdLineBegin append /Call("Scripts::Main", 1, "History.js")
//
//// REQUIRED: WIN32 Constant library at http://akelpad.sourceforge.net/forum/viewtopic.php?p=9420#p9420

//! Окно редактора
var g_hAkelPad = AkelPad.GetMainWnd();
//! Прокси системных вызовов
var oSys=AkelPad.SystemFunction();
//! Модуль плагина
var g_hModuleDll = AkelPad.GetInstanceDll();
//! Флаг завершения обработы скрипта
var QuitMutext = false;
var oSet=AkelPad.ScriptSettings()
//! Shell
//var WshShell=new ActiveXObject("WScript.shell");

//! Константы используемые системными вызовами
AkelPad.Include("win32\\user32.js");
AkelPad.Include("win32\\comctl32.js");

//! Панелька
var g_pDock = 0;
//! Окно панельки
var g_hDockWnd = 0;
//! Класс окна панельки
var DOCKCLASSNAME = "WNDCLS_"+WScript.ScriptBaseName;
//! Для удобства
var lb_hist			= 0;
/////
var ttwnd = 0;
/////
var HK_CallBackAddr	= 0;
var func_opentop	= 0;
var func_openall	= 0;
var func_showhide	= 0;

//! Settings
var _W = 0;
var _H = 0;
var _BS = 0;
var _GAP = 0;
var _SIDE = 0;
var _ELSE = 0;
var _FULLDND = 0;
var _HK_RT = 0;
var _HK_RA = 0;
var _HK_SH = 0;
var _HIDE = 0;
var _PERSIST = 0;
var _FILTER = "";
var _APPLY = 0;

//! Идентификаторы элементов управления на панельке
var IDC_DNDST	= 1000;
var IDC_HIDE	= 1001
var IDC_EXIT	= 1002;
var IDC_FILT	= 1003;
var IDC_APPLY	= 1004;
var IDC_HIST	= 1005;
var IDC_HKT		= 1006;
var IDC_HKA		= 1007;
var IDC_HKSH	= 1008;
var IDC_HKBT	= 1009;
var IDC_HKBA	= 1010;
var IDC_HKBSH	= 1011;
var IDC_SMARTRUN= 1012;
var IDC_PERSIST	= 1013;
var IDC_CNOE	= 1014;
var layout = {};
layout[IDC_DNDST]  ={sf:1,c:"STATIC",    t:"History",            wse:0,ws:WS_CHILD|WS_VISIBLE|SS_SUNKEN|SS_CENTER,hwnd:0,
                   x:{W:0,H:0,G:1,B:0},  y:{W:0,H:0,G:1,B:0},  w:{W:1,H:0,G:-4,B:-2},h:{W:0,H:0,G:0,B:1},tt:"History"};
layout[IDC_HIDE]   ={sf:0,c:"BUTTON",    t:"",                   wse:0,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON|BS_OWNERDRAW,hwnd:0,
                   x:{W:1,H:0,G:-2,B:-2},y:{W:0,H:0,G:1,B:0},  w:{W:0,H:0,G:0,B:1},  h:{W:0,H:0,G:0,B:1},tt:"Hide window"};
layout[IDC_EXIT]   ={sf:0,c:"BUTTON",    t:"",                   wse:0,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON|BS_OWNERDRAW,hwnd:0,
                   x:{W:1,H:0,G:-1,B:-1},y:{W:0,H:0,G:1,B:0},  w:{W:0,H:0,G:0,B:1},  h:{W:0,H:0,G:0,B:1},tt:"Shutdown script"};
layout[IDC_FILT]   ={sf:1,c:"EDIT",      t:"",                   wse:WS_EX_CLIENTEDGE,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP,hwnd:0,
                   x:{W:0,H:0,G:1,B:0},  y:{W:0,H:0,G:2,B:1},  w:{W:1,H:0,G:-3,B:-1},h:{W:0,H:0,G:0,B:1},tt:"Filter"};
layout[IDC_APPLY]  ={sf:0,c:"BUTTON",    t:"F",                  wse:0,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTOCHECKBOX|BS_PUSHLIKE,hwnd:0,
                   x:{W:1,H:0,G:-1,B:-1},y:{W:0,H:0,G:2,B:1},  w:{W:0,H:0,G:0,B:1},  h:{W:0,H:0,G:0,B:1},tt:"Apply filter"};
layout[IDC_HIST]   ={sf:1,c:"LISTBOX",   t:"",                   wse:0,ws:WS_CHILD|WS_VISIBLE|LBS_NOINTEGRALHEIGHT|WS_VSCROLL|WS_HSCROLL|LBS_NOTIFY|WS_TABSTOP,hwnd:0,
                   x:{W:0,H:0,G:1,B:0},  y:{W:0,H:0,G:3,B:2},  w:{W:1,H:0,G:-2,B:0}, h:{W:0,H:1,G:-8,B:-6},tt:"Closing history"};
layout[IDC_PERSIST]={sf:1,c:"BUTTON",    t:"Persistent storage", wse:0,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTOCHECKBOX,hwnd:0,
                   x:{W:0,H:0,G:1,B:0},  y:{W:0,H:1,G:-4,B:-4},w:{W:1,H:0,G:-2,B:-3},  h:{W:0,H:0,G:0,B:1},tt:"Persistent storage"};
layout[IDC_CNOE]   ={sf:1,c:"BUTTON",    t:"Clean",              wse:0,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON,hwnd:0,
                   x:{W:1,H:0,G:-1,B:-3}, y:{W:0,H:1,G:-4,B:-4},w:{W:0,H:0,G:0,B:3},   h:{W:0,H:0,G:0,B:1},tt:"Clean non-existent"};
layout[IDC_HKT]    ={sf:1,c:HOTKEY_CLASS,t:"",                   wse:0,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP,hwnd:0,
                   x:{W:0,H:0,G:1,B:0},  y:{W:0,H:1,G:-3,B:-3},w:{W:1,H:0,G:-2,B:-1},h:{W:0,H:0,G:0,B:1},tt:"HK Open last"};
layout[IDC_HKBT]   ={sf:0,c:"BUTTON",    t:"",                   wse:0,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON,hwnd:0,
                   x:{W:1,H:0,G:-1,B:-1},y:{W:0,H:1,G:-3,B:-3},w:{W:0,H:0,G:0,B:1},  h:{W:0,H:0,G:0,B:1},tt:"HK Open last set"};
layout[IDC_HKA]    ={sf:1,c:HOTKEY_CLASS,t:"",                   wse:0,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP,hwnd:0,
                   x:{W:0,H:0,G:1,B:0},  y:{W:0,H:1,G:-2,B:-2},w:{W:1,H:0,G:-2,B:-1},h:{W:0,H:0,G:0,B:1},tt:"HK Open all"};
layout[IDC_HKBA]   ={sf:0,c:"BUTTON",    t:"",                   wse:0,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON,hwnd:0,
                   x:{W:1,H:0,G:-1,B:-1},y:{W:0,H:1,G:-2,B:-2},w:{W:0,H:0,G:0,B:1},  h:{W:0,H:0,G:0,B:1},tt:"HK Open all set"};
layout[IDC_HKSH]   ={sf:1,c:HOTKEY_CLASS,t:"",                   wse:0,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP,hwnd:0,
                   x:{W:0,H:0,G:1,B:0},  y:{W:0,H:1,G:-1,B:-1},w:{W:1,H:0,G:-2,B:-1},h:{W:0,H:0,G:0,B:1},tt:"HK Show/Hide"};
layout[IDC_HKBSH]  ={sf:0,c:"BUTTON",    t:"",                   wse:0,ws:WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON,hwnd:0,
                   x:{W:1,H:0,G:-1,B:-1},y:{W:0,H:1,G:-1,B:-1},w:{W:0,H:0,G:0,B:1},  h:{W:0,H:0,G:0,B:1},tt:"HK Show/Hide set"};
//! Названия функций
var rott = "Reopen Last";
var rota = "Reopen All";
var showhide = "Show/Hide";
//! Хранилище истории
var history		= HList();
var CBC_OPENTOP = 0;
var CBC_OPENALL = 1;
var CBC_SHOWHIDE = 2;

//! Взято из AkelDLL.h
var DKS_LEFT	=1
var DKS_RIGHT	=2
var DKS_TOP		=3
var DKS_BOTTOM	=4

//Dock flags
var DKF_OWNTHREAD		=0x00000001
var DKF_FIXEDSIZE		=0x00000002
var DKF_DRAGDROP		=0x00000004
var DKF_HIDDEN			=0x00000008
var DKF_NODROPLEFT		=0x00000010
var DKF_NODROPRIGHT		=0x00000020
var DKF_NODROPTOP		=0x00000040
var DKF_NODROPBOTTOM	=0x00000080

//Dock action
var DK_ADD			=0x00000001
var DK_DELETE		=0x00000002
var DK_SUBCLASS		=0x00000004
var DK_UNSUBCLASS	=0x00000008
var DK_SETLEFT		=0x00000010
var DK_SETRIGHT		=0x00000020
var DK_SETTOP		=0x00000040
var DK_SETBOTTOM	=0x00000080
var DK_HIDE			=0x00000100
var DK_SHOW			=0x00000200
var DK_FINDDOCK		=0x00000400
var DK_FINDCHILD	=0x00000800

var BIF_BITMAP		=0x001; //Bitmap handle is used in BUTTONDRAW.hImage.
var BIF_ICON		=0x002; //Icon handle is used in BUTTONDRAW.hImage.
var BIF_CROSS		=0x004; //Draw small cross 8x7. BUTTONDRAW.hImage is ignored.
var BIF_DOWNARROW	=0x008; //Draw small down arrow 7x4. BUTTONDRAW.hImage is ignored.
var BIF_ETCHED		=0x100; //Draw edge around button.
var BIF_ENABLEFOCUS	=0x200; //Draw focus rectangle when button receive focus.

var DT_ANSI    = 0;
var DT_UNICODE = 1;
var DT_QWORD   = 2;
var DT_DWORD   = 3;
var DT_WORD    = 4;
var DT_BYTE    = 5;

var PO_DWORD  = 1;
var PO_BIANRY = 2;
var PO_STRING = 3;

var AKD_RESIZE			= WM_USER + 253;
var AKD_DOCK			= WM_USER + 254;
var AKD_SETBUTTONDRAW	= WM_USER + 255;
var AKD_DLLADD			= WM_USER + 308;
var AKD_DLLDELETE		= WM_USER + 311;
var AKDN_MAIN_ONFINISH	= WM_USER + 6;
var AKDN_FRAME_DESTROY	= WM_USER + 24;
var AKDN_OPENDOCUMENT_FINISH = WM_USER + 54;
var AKD_GETEDITINFO		= WM_USER + 200;
var AKD_GETFRAMEINFO	= WM_USER + 199;
var EOD_SUCCESS			= 0;
var FI_FILEW			= 32;
var sizeof_EDITINFO		= _X64?160:80;

var WSC_MAINPROC   = 1;
var WSC_EDITPROC   = 2;
var WSC_FRAMEPROC  = 3;

//// РАБОЧИЕ ФУНКЦИИ
//! Создаёт панельку
function CreateDock()
{
	var pDock = AkelPad.MemAlloc(52/*sizeof(DOCK)*/);
	switch(_SIDE)
	{
		case DKS_LEFT:case DKS_RIGHT:
		case DKS_TOP:case DKS_BOTTOM:break;
		default:_SIDE = DKS_RIGHT;WRITE_SETTINGS();break;
	}
	AkelPad.MemCopy(pDock + 8, DKF_OWNTHREAD|DKF_DRAGDROP, DT_DWORD);
	AkelPad.MemCopy(pDock + 16, _SIDE, DT_DWORD);
	g_pDock = AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_ADD, pDock);
	AkelPad.MemFree(pDock);
	if(g_pDock != 0)
	{

		g_hDockWnd = CreateWindowEx(0,DOCKCLASSNAME,DOCKCLASSNAME,WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE,0,0,_W,_H,g_hAkelPad,0,DockWindowProc);
		if(g_hDockWnd!=0)
		{
			GetWindowRect(g_hDockWnd,g_pDock+20);
			var szL = AkelPad.MemRead(g_pDock+20, DT_DWORD);
			var szT = AkelPad.MemRead(g_pDock+24, DT_DWORD);
			var szR = AkelPad.MemRead(g_pDock+28, DT_DWORD);
			var szB = AkelPad.MemRead(g_pDock+32, DT_DWORD);
			//rcSize={0,0,right-left,bottom-top}
			AkelPad.MemCopy(g_pDock+20, 0, DT_DWORD);
			AkelPad.MemCopy(g_pDock+24, 0, DT_DWORD);
			AkelPad.MemCopy(g_pDock+28, szR-szL, DT_DWORD);
			AkelPad.MemCopy(g_pDock+32, szB-szT, DT_DWORD);
			/*rcDragDrop=rcSize*/
			AkelPad.MemCopy(g_pDock+36, 0, DT_DWORD);
			AkelPad.MemCopy(g_pDock+40, 0, DT_DWORD);
			AkelPad.MemCopy(g_pDock+44, szR-szL, DT_DWORD);
			AkelPad.MemCopy(g_pDock+48, szB-szT, DT_DWORD);
			AkelPad.MemCopy(g_pDock+12, g_hDockWnd, DT_DWORD);
			AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_SUBCLASS, g_pDock);
			AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_SHOW, g_pDock);
			return 1;
		}
		else
		{
			AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_DELETE,g_pDock);
			g_pDock = 0;
			return 0;
		}
	}
	else return 0;
}
//! Хук главного окна.
function AkelPadCallBack(hwnd,umsg,wparam,lparam)
{
	//! Нотификция о закрытии редактора
	if(umsg == AKDN_MAIN_ONFINISH)
	{
		AkelPad.SendMessage(g_hDockWnd, WM_CLOSE, 0, 0);
		while(!QuitMutext)
		{
			oSys.Call("kernel32::SwitchToThread");
		}
	}
	//! Закладку закрыли
	if(umsg == AKDN_FRAME_DESTROY)
	{
		var addr = AkelPad.SendMessage(g_hAkelPad, AKD_GETFRAMEINFO, FI_FILEW, lparam );
		if(addr)
		{
			var string = AkelPad.MemRead(addr, _TSTR);
			if(string && string.length>0)
			{
				var name = string.split("\\");
				name = name[name.length-1];
				var regex = new RegExp(QuoteFilter(_FILTER),"ig");
				var newid = history.InsertTop(string);
				if(!_APPLY || _FILTER.length==0 || regex.test(name))
				{
					var na = AkelPad.MemAlloc((name.length+1)*_TSIZE);
					AkelPad.MemCopy(na, name, _TSTR);
					if(oSys.Call("user32::IsWindow", lb_hist))
					{
						var ind = AkelPad.SendMessage(lb_hist,LB_INSERTSTRING, 0, na);
						AkelPad.SendMessage(lb_hist, LB_SETITEMDATA, ind, newid);
					}
					AkelPad.MemFree(na);
				}
			}
		}
	}
	//! Открыли документ. Нужно его убрать из списка закрытых, если есть такой
	if(umsg == AKDN_OPENDOCUMENT_FINISH && lparam == EOD_SUCCESS)
	{
		var ei = AkelPad.MemAlloc(sizeof_EDITINFO);
		AkelPad.SendMessage(g_hAkelPad, AKD_GETEDITINFO, wparam, ei);
		var addr = AkelPad.MemRead(ei + 2*(_X64?8:4), DT_QWORD);
		var file = AkelPad.MemRead(addr, _TSTR);
		AkelPad.MemFree(ei);
		var i =0;
		file = file.toLowerCase();
		var ids = [];
		history.IterateTop(function(p,id,val)
		{
			var t = val.toLowerCase();
			if(t == file)
			{
				ids.push(id);
			}
			return true;
		},0);
		var cnt = AkelPad.SendMessage(lb_hist, LB_GETCOUNT, 0, 0);
		var ci = cnt-1;
		while(ci >= 0)
		{
			var del = false;
			var id = AkelPad.SendMessage(lb_hist, LB_GETITEMDATA, ci, 0);
			var i = 0;
			for(; i<ids.length;i++)
			{
				if(id == ids[i])
				{
					del = true;
					break;
				}
			}
			if(del)
			{
				AkelPad.SendMessage(lb_hist, LB_DELETESTRING, ci, 0);
			}
			ci--;
		}
	}
	return 0;
}
//! События в списке
function ListSubClass(hwnd,umsg,wparam,lparam)
{
	if(umsg == WM_KEYDOWN)
	{
		var mod = GetKeyState(VK_SHIFT) && GetKeyState(VK_CONTROL) && GetKeyState(VK_MENU);
		if(! mod)
		{
			//! Нажали на в списке - открыть его
			if(wparam == VK_RETURN || wparam == VK_SPACE)
			{
				var ind = AkelPad.SendMessage(lb_hist, LB_GETCURSEL, 0, 0);
				if(ind != LB_ERR)
				{
					var id = AkelPad.SendMessage(lb_hist,LB_GETITEMDATA, ind, 0);
					AkelPad.SendMessage(lb_hist, LB_DELETESTRING, ind, 0);
					DoReopen(id);
				}
				return 1;
			}
		}
	}
	else if (umsg == WM_GETDLGCODE)
	{
		//! Да, мы хотим обрабатывать все нажатия клавиш
		return DLGC_WANTALLKEYS;
	}
	return 0;
}
//! Оконная процедура панельки
function DockWindowProc(hwnd, umsg, wparam,lparam)
{
	//! Панельку создают
	if(umsg == WM_CREATE)
	{
		var font = oSys.Call("gdi32::GetStockObject", 17);
		ttwnd = CreateToolTipControl(hwnd);
		//! Создать все контролы
		var wia = [IDC_DNDST,IDC_HIDE,IDC_EXIT,IDC_FILT,IDC_APPLY,IDC_HIST,IDC_PERSIST,IDC_CNOE,IDC_HKT,IDC_HKA,IDC_HKSH,IDC_HKBT,IDC_HKBA,IDC_HKBSH];
		for(var ci in wia)
		{
			var id = wia[ci];
			var pos = GetControlPos(_W,_H,id);
			var lay = layout[id];
			layout[id].hwnd = CreateWindowEx(lay.wse,lay.c,lay.t,lay.ws,pos.x,pos.y,pos.w,pos.h,hwnd,id,0);
			if(lay.sf)
			{
				AkelPad.SendMessage(layout[id].hwnd, WM_SETFONT, font, 1);
			}
			ShowWindow(layout[id].hwnd,SW_SHOW);
			UpdateWindow(layout[id].hwnd);
			if(layout[id].tt!=0)
			AddToolTip(ttwnd,hwnd,layout[id].hwnd,layout[id].tt);
		}
		lb_hist = layout[IDC_HIST].hwnd;
		//! Настройка агрегатора горячих клавиш
		AkelPad.SendMessage(layout[IDC_HKT].hwnd,HKM_SETRULES,0, HOTKEYF_ALT|HOTKEYF_CONTROL|HOTKEYF_SHIFT);
		AkelPad.SendMessage(layout[IDC_HKA].hwnd,HKM_SETRULES,0, HOTKEYF_ALT|HOTKEYF_CONTROL|HOTKEYF_SHIFT);
		AkelPad.SendMessage(layout[IDC_HKSH].hwnd,HKM_SETRULES,0, HOTKEYF_ALT|HOTKEYF_CONTROL|HOTKEYF_SHIFT);
		AkelPad.SendMessage(layout[IDC_HKT].hwnd,HKM_SETHOTKEY,_HK_RT, 0);
		AkelPad.SendMessage(layout[IDC_HKA].hwnd,HKM_SETHOTKEY,_HK_RA, 0);
		AkelPad.SendMessage(layout[IDC_HKSH].hwnd,HKM_SETHOTKEY,_HK_SH, 0);
		//! Рисовать кнопку закрытия
		var memBD = AkelPad.MemAlloc(16/*sizeof BUTTONDRAW*/);
		AkelPad.MemCopy(memBD+0, BIF_CROSS|BIF_ETCHED, DT_DWORD);
		AkelPad.SendMessage(g_hAkelPad, AKD_SETBUTTONDRAW, layout[IDC_EXIT].hwnd, memBD);
		AkelPad.MemCopy(memBD+0, BIF_DOWNARROW|BIF_ETCHED, DT_DWORD);
		AkelPad.SendMessage(g_hAkelPad, AKD_SETBUTTONDRAW, layout[IDC_HIDE].hwnd, memBD);
		AkelPad.MemFree(memBD);
		//! Сабкласим список, нужен перехват клавиш VK_RETURN и VK_SPACE
		AkelPad.WindowSubClass(lb_hist, ListSubClass, WM_KEYDOWN, WM_GETDLGCODE);
		AkelPad.SendMessage(layout[IDC_APPLY].hwnd, BM_SETCHECK, _APPLY?BST_CHECKED:BST_UNCHECKED, 0);
		AkelPad.SendMessage(layout[IDC_PERSIST].hwnd, BM_SETCHECK, _PERSIST?BST_CHECKED:BST_UNCHECKED, 0);
		SetWindowText( layout[IDC_FILT].hwnd, _FILTER );
		ReApplyFilter();
		return 0;
	}
	else if(umsg == WM_KEYDOWN)
	{
		//! Перехват клавиш Escape на окне
		var mod = GetKeyState(VK_SHIFT) && GetKeyState(VK_CONTROL) && GetKeyState(VK_MENU);
		if(! mod)
		{
			if(wparam == VK_ESCAPE)
			{
				AkelPad.SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_EXIT,BN_CLICKED), 0);
			}
		}
	}
	else if(umsg == WM_SETFOCUS)
	{
		//! Фокус на список
		SetFocus(lb_hist);
	}
	else if(umsg == WM_COMMAND)
	{
		var CODE = HIWORD(wparam);
		var IDC  = LOWORD(wparam);
		if(CODE == BN_CLICKED)
		{
			if(IDC == IDC_SMARTRUN)
			{
				//! SmartRun
				//! Show if hidden
				//! Close if visible
				IDC = (_HIDE)?IDC_HIDE:IDC_EXIT;
			}
			if(IDC == IDC_EXIT)
			{
				//! Нажата кнопка выйти.
				AkelPad.SendMessage(hwnd,WM_CLOSE, 0, 0);
			}
			if(IDC == IDC_HIDE)
			{
				if(_HIDE==0)
				{
					AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_HIDE, g_pDock);
					_HIDE = 1;
				}
				else
				{
					AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_SHOW, g_pDock);
					_HIDE = 0;
				}
				WRITE_SETTINGS();
			}
			if(IDC == IDC_HKBT)
			{
				//! Применить новую гор.кл. открыть последнее
				var r = AkelPad.SendMessage(layout[IDC_HKT].hwnd , HKM_GETHOTKEY, 0, 0);
				//! Только если изменилось
				if(r != _HK_RT)
				{
					//! Запомнить
					_HK_RT = r;
					//! Удалить старую
					DelFunction(func_opentop);
					//! Сделать новую
					func_opentop = AddFunction(rott,_HK_RT,HK_CallBackAddr,CBC_OPENTOP);
					//! Сохранить
					WRITE_SETTINGS();
				}
			}
			if(IDC == IDC_HKBA)
			{
				//! Применить новую гор.кл. открыть все
				var r = AkelPad.SendMessage(layout[IDC_HKA].hwnd, HKM_GETHOTKEY, 0, 0);
				if(r != _HK_RA)
				{
					//! Запомнить
					_HK_RA = r;
					//! Удалить старую
					DelFunction(func_openall);
					//! Сделать новую
					func_openall = AddFunction(rota,_HK_RA,HK_CallBackAddr,CBC_OPENALL);
					//! Сохранить
					WRITE_SETTINGS();
				}
			}
			if(IDC == IDC_HKBSH)
			{
				//! Применить новую гор.кл. открыть все
				var r = AkelPad.SendMessage(layout[IDC_HKSH].hwnd, HKM_GETHOTKEY, 0, 0);
				if(r != _HK_SH)
				{
					//! Запомнить
					_HK_SH = r;
					//! Удалить старую
					DelFunction(func_showhide);
					//! Сделать новую
					func_showhide = AddFunction(showhide,_HK_SH,HK_CallBackAddr,CBC_SHOWHIDE);
					//! Сохранить
					WRITE_SETTINGS();
				}
			}
			if(IDC == IDC_APPLY)
			{
				_APPLY = (AkelPad.SendMessage(layout[IDC_APPLY].hwnd, BM_GETCHECK, 0, 0)==BST_CHECKED)?1:0;
				ReApplyFilter();
			}
			if(IDC == IDC_PERSIST)
			{
				_PERSIST = (AkelPad.SendMessage(layout[IDC_PERSIST].hwnd, BM_GETCHECK, 0, 0)==BST_CHECKED)?1:0;
				WRITE_SETTINGS();
			}
			if(IDC == IDC_CNOE)
			{
				CleanNonExist();
				ReApplyFilter();
			}
		}
		if(CODE == LBN_DBLCLK)
		{
			//! Двойной клик на списке
			if(IDC == IDC_HIST)
			{
				var ind = AkelPad.SendMessage(lb_hist, LB_GETCURSEL, 0, 0);
				//! По чем кликнули
				if(ind != LB_ERR)
				{
					var id = AkelPad.SendMessage(lb_hist, LB_GETITEMDATA, ind, 0);
					AkelPad.SendMessage(lb_hist, LB_DELETESTRING, ind, 0);
					//! Переоткрыть это
					DoReopen(id);
				}
			}
		}
		if(CODE == EN_CHANGE)
		{
			if(IDC == IDC_FILT)
			{
				if(_APPLY)
				{
					var was = _FILTER.toLowerCase();
					var len = 1+AkelPad.SendMessage(layout[IDC_FILT].hwnd, WM_GETTEXTLENGTH, 0, 0);
					var pflt = AkelPad.MemAlloc(len*_TSIZE);
					AkelPad.MemCopy(pflt, 0, (_TSIZE==1)?DT_BYTE:DT_WORD);
					AkelPad.SendMessage(layout[IDC_FILT].hwnd, WM_GETTEXT, len, pflt);
					_FILTER = AkelPad.MemRead(pflt, _TSTR);
					AkelPad.MemFree(pflt);
					if(was != _FILTER.toLowerCase())
					{
						ReApplyFilter();
					}
				}
			}
		}
		return 0;
	}
	else if(umsg == WM_SIZE)
	{
		//! Меняем Drag&Drob область за размером панельки
		if(g_pDock)
		{
//			GetWindowRect(g_hDockWnd,g_pDock+36);
//			var szL = AkelPad.MemRead(g_pDock+36, DT_DWORD);
//			var szT = AkelPad.MemRead(g_pDock+40, DT_DWORD);
//			var szR = AkelPad.MemRead(g_pDock+44, DT_DWORD);
//			var szB = AkelPad.MemRead(g_pDock+48, DT_DWORD);
//			_H = szB-szT;
//			_W = szR-szL;
			_H=HIWORD(lparam);
			_W=LOWORD(lparam);
			//! Взять положение надписи
			var pos = GetControlPos(_W,_H,IDC_DNDST);
			if(_FULLDND)
			{
				//! Если тягаем за всю панельку
				AkelPad.MemCopy(g_pDock+36, 0, DT_DWORD);
				AkelPad.MemCopy(g_pDock+40, 0, DT_DWORD);
				AkelPad.MemCopy(g_pDock+44, _W, DT_DWORD);
				AkelPad.MemCopy(g_pDock+48, _H, DT_DWORD);
			}
			else
			{
				//! Если тягаем только за надпись
				AkelPad.MemCopy(g_pDock+36, pos.x, DT_DWORD);
				AkelPad.MemCopy(g_pDock+40, pos.y, DT_DWORD);
				AkelPad.MemCopy(g_pDock+44, pos.x+pos.w, DT_DWORD);
				AkelPad.MemCopy(g_pDock+48, pos.y+pos.h, DT_DWORD);
			}
			//! Запомним новое состояние
			WRITE_SETTINGS();
			//! Переразместим контролы
			for(var ci in layout)
			{
				pos = GetControlPos(_W,_H,ci);
				MoveWindow(layout[ci].hwnd, pos.x, pos.y, pos.w, pos.h, 0);
			}
		}
	}
	else if(umsg == WM_CLOSE)
	{
		//! Нас закрывают.
		DestroyWindow(hwnd);
		return 1;
	}
	else if(umsg == WM_DESTROY)
	{
		if(ttwnd!=0)
			DestroyWindow(ttwnd);
		//! Закрыли нас. 
		_SIDE = AkelPad.MemRead(g_pDock+16, DT_DWORD);
		WRITE_SETTINGS();
		AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_UNSUBCLASS,g_pDock);
		AkelPad.SendMessage(g_hAkelPad,AKD_DOCK,DK_DELETE,g_pDock);
		g_pDock = 0;
		AkelPad.SendMessage(g_hAkelPad, AKD_RESIZE, 0, 0);
		g_hDockWnd = 0;
		//! Отпускаем список
		AkelPad.WindowUnsubClass(lb_hist);
		//! Выйти из цикла
		PostQuitMessage(0);
		return 0;
	}
	return 0;
}
function ReApplyFilter()
{
	var regex = new RegExp(QuoteFilter(_FILTER),"gi");
	AkelPad.SendMessage(lb_hist, LB_RESETCONTENT, 0, 0);
	history.IterateBottom(function(param,id,val)
	{
		var name = val.split("\\");
		if(name.length>0)
		{
			var name = name[name.length-1];
			regex.lastIndex = 0;
			if(!_APPLY || (_FILTER.length==0) || regex.test(name))
			{
				var na = AkelPad.MemAlloc((1+name.length)*_TSIZE);
				AkelPad.MemCopy(na, name, _TSTR)
				var ind = AkelPad.SendMessage(lb_hist, LB_INSERTSTRING, 0, na);
				AkelPad.SendMessage(lb_hist, LB_SETITEMDATA, ind, id);
				AkelPad.MemFree(na);
			}
		}
		return true;
	},0);
}
function QuoteFilter(str)
{
	return str.replace("\\","\\\\")
	          .replace("[","\\[").replace("]","\\]").replace("(","\\(").replace("(","\\(")
	          .replace("{","\\{").replace("}","\\}").replace(".","\\.").replace("*","\\*")
	          .replace("?","\\?").replace("+","\\+").replace("$","\\$").replace("^","\\^");
}

function FirstInstance(smart)
{
	var dock = FindWindowEx(g_hAkelPad,DOCKCLASSNAME);
	if(dock)
	{
		if(smart)
		{
			AkelPad.SendMessage(dock, WM_COMMAND, MAKEWPARAM(IDC_SMARTRUN,BN_CLICKED), 0);
		}
		else
		{
			AkelPad.SendMessage(dock, WM_CLOSE, 0, 0);
		}
		return false;
	}
	else
		return true;
}
var smartrun = false;
if(WScript.Arguments.length>0)
{
	var arg = WScript.Arguments(0);
	if(arg.toLowerCase()=="sr")
	{
		smartrun = true;
	}
}
if(FirstInstance(smartrun))
{
	READ_SETTINGS();
	layout[IDC_HIST].wse = _ELSE;
	layout[IDC_FILT].t = _FILTER;
	//! Регистрируем класс окна
	var res = AkelPad.WindowRegisterClass(DOCKCLASSNAME);

	//! Создаем панельку
	if(CreateDock())
	{
		AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, _HIDE?DK_HIDE:DK_SHOW, g_pDock);
		//! Создаем функции быстрого вызова
		HK_CallBackAddr   = oSys.RegisterCallback(HK_CallBack);
		func_opentop = AddFunction(rott,_HK_RT,HK_CallBackAddr,CBC_OPENTOP);
		func_openall = AddFunction(rota,_HK_RA,HK_CallBackAddr,CBC_OPENALL);
		func_showhide = AddFunction(showhide,_HK_SH,HK_CallBackAddr,CBC_SHOWHIDE);
		//! Сабкласим главное окно
		if(AkelPad.WindowSubClass( WSC_MAINPROC, AkelPadCallBack, AKDN_OPENDOCUMENT_FINISH, AKDN_MAIN_ONFINISH, AKDN_FRAME_DESTROY))
		{
			//! Мы инициализировались, можно дать работать другим скриптам
			AkelPad.ScriptNoMutex();
			//! Поток в цикл сообщений
			AkelPad.WindowGetMessage();
			//! Вышли(только по закрытии панельки)
			AkelPad.WindowUnsubClass( WSC_MAINPROC );
			//! Сняли хук
		}
		//! Функции нужно удалить
		DelFunction(func_opentop);
		DelFunction(func_openall);
		DelFunction(func_showhide);
		oSys.UnregisterCallback(HK_CallBackAddr);
		if(g_hDockWnd != 0)
		{
			//AkelPad.MessageBox(0, "Text", "Caption", 0 /*MB_OK*/);
			//! По идее сюда не попадем
			AkelPad.SendMessage(g_hDockWnd, WM_CLOSE, 0, 0);
			g_hDockWnd = 0;
		}
	}
	//! Класс долой
	AkelPad.WindowUnregisterClass(DOCKCLASSNAME);
	//! Вернуть фокус
	SetFocus(g_hAkelPad);
	//! Взводим флаг разрешения выхода из скрипта.
	QuitMutext = true;
}
//! Переоткрывет указаный файл из списка
function DoReopen(id)
{
	if(id == 0) return;
	var file = history.GetItem(id).value;
	//! Открыть
	AkelPad.OpenFile(file);
	history.RemoveId(id);
}
//! Обработчик горячей клавиши
function HK_CallBack(regparam,callparam,support)
{
	var task=regparam;
	if(task == CBC_OPENALL)
	{
		var str;
		//! Открыть все
		while(history.GetCount()>0)
		{
			var id = history.GetTop();
			str = str+id+";";
			DoReopen(id);
		}
		//AkelPad.SendMessage(lb_hist, LB_RESETCONTENT, 0, 0);
	}
	if(task == CBC_OPENTOP)
	{
		var id = history.GetTop();
		//! Открыть последнее
		if(id != 0)
		{
			DoReopen(id);
/*			var cnt = AkelPad.SendMessage(lb_hist, LB_GETCOUNT, 0, 0);
			var ci = cnt - 1;
			while(ci >= 0)
			{
				var del = false;
				var lid = AkelPad.SendMessage(lb_hist, LB_GETITEMDATA, ci, 0);
				var i = 0;
				if(id==lid)
				{
					AkelPad.SendMessage(lb_hist, LB_DELETESTRING, ci, 0);
				}
				ci--;
			}*/
		}
	}
	if(task == CBC_SHOWHIDE)
	{
		if(_HIDE)
		{
			AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_SHOW, g_pDock);
			_HIDE = 0;
		}
		else
		{
			AkelPad.SendMessage(g_hAkelPad, AKD_DOCK, DK_HIDE, g_pDock);
			_HIDE = 1;
		}
		WRITE_SETTINGS();
	}
}
//! Вернуть позицию указанного контрола по размеру панельки
function GetControlPos(W,H,what)
{
	var r = {"x":0,"y":0,"w":W,"h":H};
	if(layout[what])
	{
		var lo = layout[what];
		r.x = lo.x.W*W + lo.x.H*H + lo.x.B*_BS+lo.x.G*_GAP;
		r.y = lo.y.W*W + lo.y.H*H + lo.y.B*_BS+lo.y.G*_GAP;
		r.w = lo.w.W*W + lo.w.H*H + lo.w.B*_BS+lo.w.G*_GAP;
		r.h = lo.h.W*W + lo.h.H*H + lo.h.B*_BS+lo.h.G*_GAP;
	}
	return r;
}
function CleanNonExist()
{
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	var todelete = [];
	history.IterateBottom(function(param,id,val){
		if( ! fso.FileExists(val) )
			todelete.push(id);
		return true;
	});
	while(todelete.length >0)
	{
		var id = todelete.pop();
		history.RemoveId(id);
	}
}
///// UTILITY
//! Register hotkey-ed function
function AddFunction( Name,hk,proc,param)
{
	var name = "Scripts::"+WScript.ScriptBaseName+"::" + Name;
	var szof = _X64?8:4;
	var func = AkelPad.MemAlloc(5*szof);
	var mn = AkelPad.MemAlloc((name.length+1)*_TSIZE);
	AkelPad.MemCopy(mn, name, _TSTR);
	AkelPad.MemCopy(func, 			mn,		DT_QWORD);    //name
	AkelPad.MemCopy(func+szof,		hk,		DT_WORD);     //hotkey
	AkelPad.MemCopy(func+2*szof,	0,		DT_WORD);     //FALSE
	AkelPad.MemCopy(func+3*szof,	proc,	DT_QWORD);    //proc
	AkelPad.MemCopy(func+4*szof,	param,	DT_QWORD);    //param
	var res = AkelPad.SendMessage(g_hAkelPad, AKD_DLLADD, 0, func);
	AkelPad.MemFree(mn);
	AkelPad.MemFree(func);
	return res;
}
//! Unregister hotkey-ed function
function DelFunction(prs)
{
	AkelPad.SendMessage(g_hAkelPad, AKD_DLLDELETE, 0, prs);
}
//! Записать настройки скрипта
function WRITE_SETTINGS()
{
	oSet.Begin(WScript.ScriptBaseName, 0x2 /*POB_SAVE*/);
	oSet.Write("WIDTH", PO_DWORD, _W);
	oSet.Write("HEIGHT", PO_DWORD, _H);
	oSet.Write("BS", PO_DWORD,    _BS);
	oSet.Write("GAP", PO_DWORD,   _GAP);
	oSet.Write("SIDE", PO_DWORD,  _SIDE);
	oSet.Write("ELSE", PO_DWORD, _ELSE);
	oSet.Write("FULLDND", PO_DWORD, _FULLDND);
	oSet.Write("HK_RT", PO_DWORD, _HK_RT);
	oSet.Write("HK_RA", PO_DWORD, _HK_RA);
	oSet.Write("HK_SH", PO_DWORD, _HK_SH);
	oSet.Write("HIDE", PO_DWORD, _HIDE);
	oSet.Write("PS", PO_DWORD, _PERSIST);
	if(_PERSIST)
	{
		oSet.Write("DATA", PO_STRING, history.serialize());
	}
	else oSet.Write("DATA", PO_STRING, "");
	oSet.Write("FILTER", PO_STRING, _FILTER);
	oSet.Write("APPLY", PO_DWORD, _APPLY);
	oSet.End();
}
//! Прочитать настройки скрипта
function READ_SETTINGS()
{
	oSet.Begin(WScript.ScriptBaseName, 0x1 /*POB_READ*/);
	_W    = oSet.Read("WIDTH", PO_DWORD, 100);
	_H    = oSet.Read("HEIGHT", PO_DWORD, 300);
	_BS   = oSet.Read("BS", PO_DWORD, 20);
	_GAP  = oSet.Read("GAP", PO_DWORD, 5);
	_SIDE = oSet.Read("SIDE", PO_DWORD, DKS_RIGHT);
	_ELSE = oSet.Read("ELSE", PO_DWORD, WS_EX_CLIENTEDGE);
	_FULLDND = oSet.Read("FULLDND", PO_DWORD, 0);
	_HK_RT = oSet.Read("HK_RT", PO_DWORD, MAKEWORD(0x5A,HOTKEYF_ALT));
	_HK_RA = oSet.Read("HK_RA", PO_DWORD, MAKEWORD(0x5A,HOTKEYF_ALT|HOTKEYF_CONTROL|HOTKEYF_SHIFT));
	_HK_SH = oSet.Read("HK_SH", PO_DWORD, MAKEWORD(0x48,HOTKEYF_ALT|HOTKEYF_CONTROL));
	_HIDE = oSet.Read("HIDE", PO_DWORD, 0);
	_PERSIST = oSet.Read("PS", PO_DWORD, 0);
	if(_PERSIST)
	{
		history.unserialize(oSet.Read("DATA", PO_STRING,""));
	}
	_FILTER = oSet.Read("FILTER", PO_STRING,"");
	_APPLY = oSet.Read("APPLY", PO_DWORD, 0);
	oSet.End();
}
///// HELPERS: функции для упрощения системных вызовов
//! Передвинуть окно
function MoveWindow(hwnd,x,y,w,h,repaint)
{
	oSys.Call("user32::MoveWindow",hwnd,x,y,w,h,repaint);
}
//! Поиск окна в пределах рабочего стола по родителю и имени класса
function FindWindowEx(hwndParent,lpszClassName)
{
	var memclass =0;
	var t = "" + lpszClassName;
	memclass = AkelPad.MemAlloc((t.length+1)*_TSIZE);
	AkelPad.MemCopy(memclass, t, _TSTR);
	var hwnd = oSys.Call("user32::FindWindowEx"+_TCHAR, hwndParent,0,memclass,0);
	AkelPad.MemFree(memclass);
	return hwnd;
}
//! Установить текст окна
function SetWindowText(hwnd, text)
{
	return oSys.Call( "user32::SetWindowText"+_TCHAR, hwnd, text );
}
//! Создаёт окно
function CreateWindowEx(styleex,_class,title,style,x,y,cx,cy,parent,menu,lparam)
{
	//! Нативные строки
	var mem_class = AkelPad.MemAlloc((_class.length+1)*_TSIZE);
	AkelPad.MemCopy(mem_class, _class, _TSTR);
	var mem_title = 0;
	if(title != 0)
	{
		mem_title=AkelPad.MemAlloc((title.length+1)*_TSIZE);
		AkelPad.MemCopy(mem_title, title, _TSTR);
	}
	var hwnd = oSys.Call("user32::CreateWindowEx" + _TCHAR,
							styleex,			//! Расширенный стиль
							mem_class,			//! Класс окна
							mem_title,			//! Заголовок окна
							style,				//! Стиль окна
							x,y,cx,cy,			//! Координаты и размер
							parent, menu,		//! Родитель и меню(идентификатор)
							g_hModuleDll,		//! принадлежность коду
							lparam);			//! Доп. параметр
	//! Освободить память
	AkelPad.MemFree(mem_class);
	if(mem_title!=0) AkelPad.MemFree(mem_title);
	return hwnd;
}
//! Показать окно, SW_* константы
function ShowWindow(hwnd,how)
{
	return oSys.Call("user32::ShowWindow",hwnd,how);
}
//! Обновить окно
function UpdateWindow(hwnd)
{
	return oSys.Call("user32::UpdateWindow",hwnd);
}
//! Выйти из оконного цикла
function PostQuitMessage(code)
{
	return oSys.Call("user32::PostQuitMessage",code);
}
//! Уничтожить окно
function DestroyWindow(hwnd)
{
	return oSys.Call("user32::DestroyWindow",hwnd);
}
//! Получить размер окна
function GetWindowRect(hwnd,rc)
{
	return oSys.Call("user32::GetWindowRect",hwnd,rc);
}
//! Дать фокус
function SetFocus(hwnd)
{
	return oSys.Call("user32::SetFocus",hwnd);
}
//! Получить состояние кнопки
function GetKeyState(key)
{
	return oSys.Call("user32::GetKeyState",key);
}
//! MAKEWORD
function MAKEWORD(lo,hi)
{
	return (lo & 0xFF) + ((hi & 0xFF)<<8);
}
//! LOWORD
function LOWORD(long)
{
	return long & 0x0FFFF;
}
//! HIWORD
function HIWORD(long)
{
	return (long >> 16) & 0x0FFFF;
}
//! MAKEWPARAM
function MAKEWPARAM(l, h)
{
	return MAKELONG(l, h);
}
//! MAKELONG
function MAKELONG(l, h)
{
	return (l & 0x0FFFF) + ((h & 0x0FFFF) << 16);
}
function HList()
{
	var obj = {};
	obj.gid = 0;
	obj.head = {prev:null,next:null,id:0,value:null};
	obj.tail = {prev:null,next:null,id:0,value:null};
	obj.count = 0;
	obj.head.next = obj.tail;
	obj.tail.prev = obj.head;
	obj.all = {};
	var NextId = function(o){
		o.gid++;
		while(o.all[o.gid]!=null || o.gid==0)
			o.gid++;
	}
	obj.GetCount = function(){return obj.count;}
	obj.GetItem = function(id)	{
		if(id == 0) return null;
		if(obj.all[id]) return obj.all[id];
		return null;
	}
	obj.RemoveId = function(id)	{
		if(id == 0) return;
		var it = this.GetItem(id);
		if(it != null)
		{
			it.next.prev = it.prev;
			it.prev.next = it.next;
			obj.count = obj.count - 1;
		}
		obj.all[id] = null;
	}
	obj.GetTop = function()	{
		return obj.head.next.id;
	}
	obj.IterateTop = function(func,param)	{
		var cur = obj.head.next;
		while(cur != obj.tail)
		{
			if(!func(param,cur.id,cur.value))
				return;
			cur = cur.next;
		}
	}
	obj.IterateBottom = function(func,param)	{
		var cur = obj.tail.prev;
		while(cur != obj.head)
		{
			if(!func(param,cur.id,cur.value))
				return;
			cur = cur.prev;
		}
	}
	obj.InsertTop = function(val)
	{
		NextId(obj);
		var item = {prev:obj.head,next:obj.head.next,id:obj.gid,value:val};
		obj.head.next.prev = item;
		obj.head.next = item;
		obj.all[obj.gid] = item;
		obj.count++;
		return obj.gid;
	}
	obj.serialize = function()
	{
		var arr = [];
		var cur = obj.head.next;
		while(cur != obj.tail)
		{
			arr.push(cur.value);
			cur = cur.next;
		}
		return arr.join("|");
	}
	obj.unserialize = function(data)
	{
		if(!data) return;
		var arr = data.split("|");
		while(arr.length>0)
		{
			var t = arr.pop();
			if(t)
			obj.InsertTop(t);
		}
	}
	return obj;
}
///////////////////////////////
// *Disabled, testing
////////
function CreateToolTipControl(parent)
{
	return 0;
	var hwnd = CreateWindowEx(
					WS_EX_TOPMOST,//styleex
					TOOLTIPS_CLASS,//class
					0,//title
					WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,//style
					CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,//x,y,cx,cy
					parent,//parent
					0,//menu
					0//lparam
				);
	oSys.Call("user32::SetWindowPos",HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
	AkelPad.SendMessage(hwnd, TTM_ACTIVATE, 1, 0);
	return hwnd;
}
function AddToolTip(ttwnd,parent,tool,text)
{
	return;
	var ti = AkelPad.MemAlloc(_X64?72:48);
	var	offsets={
		cbSize:0,
		uFlags:(_X64?4:4),
		hwnd:(_X64?8:8),
		uId:(_X64?16:12),
		rect:(_X64?24:16),
		hinst:(_X64?40:32),
		lpszText:(_X64?48:36),
		lParam:(_X64?56:40),
		lpReserved:(_X64?64:44)
	};
	oSys.Call("kernel32::RtlZeroMemory",ti,_X64?72:48);
	AkelPad.MemCopy(ti+offsets.cbSize, _X64?72:48, DT_DWORD);
	AkelPad.MemCopy(ti+offsets.uFlags, TTF_IDISHWND|TTF_SUBCLASS|TTF_TRACK, DT_DWORD);
	AkelPad.MemCopy(ti+offsets.hwnd, parent, DT_QWORD);
	AkelPad.MemCopy(ti+offsets.uId, tool, DT_QWORD);
	//RECT ={0,0,0,0} AkelPad.MemCopy(ti+offsets.cbSize, _X64?72:48, DT_DWORD);
	//hinst=NULL,AkelPad.MemCopy(ti+offsets.cbSize, _X64?72:48, DT_DWORD);
	var txt = AkelPad.MemAlloc((text.length+1)*_TSIZE);
	AkelPad.MemCopy(txt, text, _TSTR);
	AkelPad.MemCopy(ti+offsets.lpszText, txt, DT_QWORD);
	//lParam=0 AkelPad.MemCopy(ti+offsets.cbSize, _X64?72:48, DT_DWORD);
	//lpReserved=0 AkelPad.MemCopy(ti+offsets.cbSize, _X64?72:48, DT_DWORD);
	AkelPad.SendMessage(ttwnd, TTM_ADDTOOL, 0, ti);
	//AkelPad.SendMessage(ttwnd, TTM_TRACKACTIVATE, 1, ti);
	AkelPad.MemFree(txt);
	AkelPad.MemFree(ti);
}
////////
// /Disabled, testing
///////////////////////////////

UPD: v0.2 2011.12.21
UPD: v0.3 2011.12.22
UPD: v0.4 2011.12.22
UPD: v0.5 2011.12.23
UPD: v0.5.1 2011.12.24
UPD: v0.5.2 2011.12.24
UPD: v0.6 2011.12.27
UPD: v0.9 2012.01.04
UPD: v0.10 2012.02.07
UPD: v0.10.1 2012.09.14
UPD: v0.11 2012.09.14
UPD: v0.11.1 2012.10.07
UPD: v0.11.2 2014.04.12
UPD: v0.11.3 2014.04.19
UPD: v0.12 2014.04.20
UPD: v0.13 2014.10.12
UPD: v0.14 2014.12.20
Last edited by FeyFre on Sun Nov 15, 2015 1:22 pm, edited 12 times in total.

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=16297#p16297
// Description(1033): Works with AkelPad tabs. Script implemented as the library for using in other scripts.
// Description(1049): Библиотека функций для работы с вкладками AkelPad'а.
// Version: 1.2 (2014.11.15)
// Author: VladSh

var hWndMain = AkelPad.GetMainWnd();

function getTabIndexCurrent() {
	var lpFrame = AkelPad.SendMessage(hWndMain, 1288 /*AKD_FRAMEFIND*/, 1 /*FWF_CURRENT*/, 0)
	return AkelPad.SendMessage(hWndMain, 1294 /*AKD_FRAMEINDEX*/, 0, lpFrame);
}

//MDI only :(
function getTabFileByIndex(nTabIndex) {
	var lpFrame = getTabFrameByIndex(nTabIndex);
	var hWnd = AkelPad.SendMessage(hWndMain, 1223 /*AKD_GETFRAMEINFO*/, 2 /*FI_WNDEDIT*/, lpFrame);
	var ei = AkelPad.MemAlloc(_X64?160:80 /*sizeof(EDITINFO)*/);
	AkelPad.SendMessage(hWndMain, 1224 /*AKD_GETEDITINFO*/, hWnd, ei);
	var addr = AkelPad.MemRead(ei + 2*(_X64?8:4), 2 /*DT_QWORD*/);
	var file = AkelPad.MemRead(addr, _TSTR);
	AkelPad.MemFree(ei);
	return file;
}

function getTabFilePrev() {
	var pFile = "";
	var lpInitFrame = AkelPad.SendMessage(hWndMain, 1288 /*AKD_FRAMEFIND*/, 1 /*FWF_CURRENT*/, 0);
	var lpFrame = lpInitFrame;

	while ((lpFrame = AkelPad.SendMessage(hWndMain, 1288 /*AKD_FRAMEFIND*/, 10 /*FWF_TABPREV*/, lpFrame)) && lpFrame != lpInitFrame) {
		pFile = AkelPad.MemRead(AkelPad.SendMessage(hWndMain, 1223 /*AKD_GETFRAMEINFO*/, 32 /*FI_FILEW*/, lpFrame), 1 /*DT_UNICODE*/);
	}
	return pFile;
}

function activateTabByIndex(nTabIndex) {
	var lpFrame = getTabFrameByIndex(nTabIndex);
	AkelPad.SendMessage(hWndMain, 1285 /*AKD_FRAMEACTIVATE*/, 0, lpFrame);
}

function getTabFrameByIndex(nTabIndex) {
	return AkelPad.SendMessage(hWndMain, 1288 /*AKD_FRAMEFIND*/, 8 /*FWF_BYTABINDEX*/, nTabIndex);
}
Last edited by VladSh on Wed Jan 14, 2015 11:41 pm, edited 2 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Manager of files and NTFS streams.
Part One. Other parts are in the next posts. All parts should be placed in one file.
In one file is here: KDJ.zip
Required to include: FileAndStream_functions.js and InputBox_function.js
Required in Scripts directory: FileAndStream_nnnn.lng (nnnn = language identifier)

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=16796#p16796
// Version: 2015-01-07
// Author: KDJ
//
// *** Manager of files and NTFS streams ***
//
// Required to include: FileAndStream_functions.js and InputBox_function.js
// Required in Scripts directory: FileAndStream_nnnn.lng (nnnn = language identifier)
//
// Usage:
//   Call("Scripts::Main", 1, "FileAndStream.js")
//
// Some keyboard shortcuts that are not visible in menu:
//   TAB - change panel
//   Shift+TAB - change widow Files <-> NTFS streams
//   Alt+Del - delete filter from filter list

var oSys       = AkelPad.SystemFunction();
var sClassName = "AkelPad::Scripts::" + WScript.ScriptName + "::" + oSys.Call("Kernel32::GetCurrentProcessId");
var hWndDlg    = oSys.Call("User32::FindWindowExW", 0, 0, sClassName, 0);

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

  oSys.Call("User32::SetForegroundWindow", hWndDlg);
}
else
{
  if (! (AkelPad.Include("FileAndStream_functions.js") && AkelPad.Include("InputBox_function.js") && GetLangStrings()))
    WScript.Quit();

  var DT_QWORD = 2;
  var DT_DWORD = 3;
  var DT_WORD  = 4;
  var DT_BYTE  = 5;

  var hInstDLL    = AkelPad.GetInstanceDll();
  var sScriptName = "File and Stream";
  var hGuiFont    = oSys.Call("Gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
  var nBufSize    = 2048;
  var lpBuffer    = AkelPad.MemAlloc(nBufSize);
  var lpLVITEM    = AkelPad.MemAlloc(_X64 ? 72 : 60); //sizeof(LVITEM)

  AkelPad.MemCopy(lpLVITEM, 0x0001 /*LVIF_TEXT*/, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, _X64 ? 24 : 20), lpBuffer, DT_QWORD);
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, _X64 ? 32 : 24), nBufSize, DT_DWORD);

  var oWndMin = {"W": 560,
                 "H": 366};
  var oWndPos = {"X": 240,
                 "Y": 160,
                 "W": oWndMin.W,
                 "H": oWndMin.H,
                 "Max": false};
  var bDualPan        = true;
  var bColSize        = true;
  var bColTime        = true;
  var bColAttr        = true;
  var bQuickView      = true;
  var bSaveHist       = true;
  var sViewerName     = "";
  var sViewer         = "";
  var sViewerPar      = "";
  var sViewerName2    = "";
  var sViewer2        = "";
  var sViewerPar2     = "";
  var sEditorName     = "AkelPad";
  var sEditor         = "%a\\AkelPad.exe";
  var sEditorPar      = "";
  var sEditorName2    = "";
  var sEditor2        = "";
  var sEditorPar2     = "";
  var sComparerName   = "";
  var sComparer       = "";
  var sComparerPar    = "";
  var sComparerName2  = "";
  var sComparer2      = "";
  var sComparerPar2   = "";
  var nCurPan         = 0;
  var aFilter         = [];
  var aCurFilter      = ["*.*", "*.*"];
  var aCurWnd         = [0, 0];
  var aCurDrive       = ["", ""];
  var aCurDir         = [{}, {}];
  var aSort           = [[0, 0], [0, 0], [0, 0], [0, 0]];
  var aFavorite       = [];
  var aFavoriteFolder = [];
  var aIntAssoc       = [];
  var aCurHist        = [0, 0];
  var aHistory        = [[], []];
  var nHistMax        = 25;
  var oScrArg         = {};
  var hWndDlg;
  var hWndSort;
  var hWndFilterEdit0;
  var hWndFilterEdit1;

  ReadWriteIni(false);

  if (! bDualPan)
    oWndMin.W = Math.round((oWndMin.W - 2 * oSys.Call("User32::GetSystemMetrics", 32 /*SM_CXSIZEFRAME*/)) / 2) + 2 * oSys.Call("User32::GetSystemMetrics", 32 /*SM_CXSIZEFRAME*/);

  if (oWndPos.H < oWndMin.H)
    oWndPos.H = oWndMin.H;
  if (oWndPos.W < oWndMin.W)
    oWndPos.W = oWndMin.W;

  var CLASS = 0;
  var HWND  = 1;
  var STYLE = 2;
  var TXT   = 3;

  var aSubClassHand = [];
  var aWnd          = [];
  var IDFILTERS0    = 2000;
  var IDFILTERS1    = 2001;
  var IDDRIVECB0    = 2002;
  var IDDRIVECB1    = 2003;
  var IDFILTERCB0   = 2004;
  var IDFILTERCB1   = 2005;
  var IDDIRS0       = 2006;
  var IDDIRS1       = 2007;
  var IDFILELV0     = 2008;
  var IDFILELV1     = 2009;
  var IDSTREAMLV0   = 2010;
  var IDSTREAMLV1   = 2011;
  var IDQUICKVIEWS0 = 2012;
  var IDQUICKVIEWS1 = 2013;
  var IDMAINDIRB0   = 2014;
  var IDMAINDIRB1   = 2015;
  var IDUPDIRB0     = 2016;
  var IDUPDIRB1     = 2017;
  var IDFAVFOLDB0   = 2018;
  var IDFAVFOLDB1   = 2019;
  var IDSPECFOLDB0  = 2020;
  var IDSPECFOLDB1  = 2021;
  var IDHISTORYB0   = 2022;
  var IDHISTORYB1   = 2023;
  var IDLEFTB       = 2024;
  var IDRIGHTB      = 2025;
  var IDMENUB       = 2026;
  var IDRENAMEB     = 2027;
  var IDVIEWB       = 2028;
  var IDEDITB       = 2029;
  var IDCOPYB       = 2030;
  var IDMOVEB       = 2031;
  var IDCREATEB     = 2032;
  var IDDELETEB     = 2033;
  var IDREFRESHB    = 2034;
  var IDCOMPAREB    = 2035;
  var IDWAIT        = 2036;

  //0x50000000 - WS_VISIBLE|WS_CHILD
  //0x50000002 - WS_VISIBLE|WS_CHILD|SS_RIGHT
  //0x50000003 - WS_VISIBLE|WS_CHILD|CBS_DROPDOWNLIST
  //0x50204042 - WS_VISIBLE|WS_CHILD|WS_VSCROLL|CBS_LOWERCASE|CBS_AUTOHSCROLL|CBS_DROPDOWN
  //0x50800001 - WS_VISIBLE|WS_CHILD|WS_BORDER|SS_CENTER
  //0x5080000D - WS_VISIBLE|WS_CHILD|WS_BORDER|LVS_SHOWSELALWAYS|LVS_SINGLESEL|LVS_REPORT
  //0x5080008C - WS_VISIBLE|WS_CHILD|WS_BORDER|SS_NOPREFIX|SS_LEFTNOWORDWRAP
  //0x50802080 - WS_VISIBLE|WS_CHILD|WS_BORDER|SS_EDITCONTROL|SS_NOPREFIX
  //Windows              CLASS,        HWND,      STYLE, TXT
  aWnd[IDFILTERS0   ] = ["STATIC",        0, 0x50000002, sTxtFilter + ":"];
  aWnd[IDFILTERS1   ] = ["STATIC",        0, 0x50000002, sTxtFilter + ":"];
  aWnd[IDDRIVECB0   ] = ["COMBOBOX",      0, 0x50000003, ""];
  aWnd[IDDRIVECB1   ] = ["COMBOBOX",      0, 0x50000003, ""];
  aWnd[IDFILTERCB0  ] = ["COMBOBOX",      0, 0x50204042, ""];
  aWnd[IDFILTERCB1  ] = ["COMBOBOX",      0, 0x50204042, ""];
  aWnd[IDDIRS0      ] = ["STATIC",        0, 0x5080008C, ""];
  aWnd[IDDIRS1      ] = ["STATIC",        0, 0x5080008C, ""];
  aWnd[IDFILELV0    ] = ["SysListView32", 0, 0x5080000D, ""];
  aWnd[IDFILELV1    ] = ["SysListView32", 0, 0x5080000D, ""];
  aWnd[IDSTREAMLV0  ] = ["SysListView32", 0, 0x5080000D, ""];
  aWnd[IDSTREAMLV1  ] = ["SysListView32", 0, 0x5080000D, ""];
  aWnd[IDQUICKVIEWS0] = ["STATIC",        0, 0x50802080, ""];
  aWnd[IDQUICKVIEWS1] = ["STATIC",        0, 0x50802080, ""];
  aWnd[IDMAINDIRB0  ] = ["BUTTON",        0, 0x50000000, "\\"];
  aWnd[IDMAINDIRB1  ] = ["BUTTON",        0, 0x50000000, "\\"];
  aWnd[IDUPDIRB0    ] = ["BUTTON",        0, 0x50000000, ".."];
  aWnd[IDUPDIRB1    ] = ["BUTTON",        0, 0x50000000, ".."];
  aWnd[IDFAVFOLDB0  ] = ["BUTTON",        0, 0x50000000, "FF"];
  aWnd[IDFAVFOLDB1  ] = ["BUTTON",        0, 0x50000000, "FF"];
  aWnd[IDSPECFOLDB0 ] = ["BUTTON",        0, 0x50000000, "SF"];
  aWnd[IDSPECFOLDB1 ] = ["BUTTON",        0, 0x50000000, "SF"];
  aWnd[IDHISTORYB0  ] = ["BUTTON",        0, 0x50000000, "H"];
  aWnd[IDHISTORYB1  ] = ["BUTTON",        0, 0x50000000, "H"];
  aWnd[IDLEFTB      ] = ["BUTTON",        0, 0x50000000, "<-"];
  aWnd[IDRIGHTB     ] = ["BUTTON",        0, 0x50000000, "->"];
  aWnd[IDMENUB      ] = ["BUTTON",        0, 0x50000000, sTxtMenu + " (F1)"];
  aWnd[IDRENAMEB    ] = ["BUTTON",        0, 0x50000000, sTxtRename + " (F2)"];
  aWnd[IDVIEWB      ] = ["BUTTON",        0, 0x50000000, sTxtView + " (F3)"];
  aWnd[IDEDITB      ] = ["BUTTON",        0, 0x50000000, sTxtEdit + " (F4)"];
  aWnd[IDCOPYB      ] = ["BUTTON",        0, 0x50000000, sTxtCopy + " (F5)"];
  aWnd[IDMOVEB      ] = ["BUTTON",        0, 0x50000000, sTxtMove + " (F6)"];
  aWnd[IDCREATEB    ] = ["BUTTON",        0, 0x50000000, sTxtCreate + " (F7)"];
  aWnd[IDDELETEB    ] = ["BUTTON",        0, 0x50000000, sTxtDelete + " (F8)"];
  aWnd[IDREFRESHB   ] = ["BUTTON",        0, 0x50000000, sTxtRefresh + " (F9)"];
  aWnd[IDCOMPAREB   ] = ["BUTTON",        0, 0x50000000, sTxtCompare + " (F12)"];
  aWnd[IDWAIT       ] = ["STATIC",        0, 0x50800001, ""];

  AkelPad.WindowRegisterClass(sClassName);

  //0x90CF0000 - WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SIZEBOX
  //0x91CF0000 - WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_SIZEBOX|WS_MAXIMIZE
  hWndDlg = oSys.Call("User32::CreateWindowExW",
                      0,               //dwExStyle
                      sClassName,      //lpClassName
                      sScriptName,     //lpWindowName
                      oWndPos.Max ? 0x91CF0000 : 0x90CF0000, //dwStyle
                      oWndPos.X,       //x
                      oWndPos.Y,       //y
                      oWndPos.W,       //nWidth
                      oWndPos.H,       //nHeight
                      0,               //hWndParent
                      0,               //ID
                      hInstDLL,        //hInstance
                      DialogCallback); //Script function callback. To use it class must be registered by WindowRegisterClass.

  //Allow other scripts running
  AkelPad.ScriptNoMutex();

  //Message loop
  AkelPad.WindowGetMessage();

  AkelPad.WindowUnregisterClass(sClassName);
  AkelPad.MemFree(lpBuffer);
  AkelPad.MemFree(lpLVITEM);
}

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 1) //WM_CREATE
  {
    var i;

    for (i = 2000; i < aWnd.length; ++i)
    {
      aWnd[i][HWND] =
        oSys.Call("User32::CreateWindowExW",
                  0,              //dwExStyle
                  aWnd[i][CLASS], //lpClassName
                  0,              //lpWindowName
                  aWnd[i][STYLE], //dwStyle
                  0,              //x
                  0,              //y
                  100,            //nWidth (for IDFILTERCB0)
                  1200,           //nHeight (for IDFILELV0)
                  hWnd,           //hWndParent
                  i,              //ID
                  hInstDLL,       //hInstance
                  0);             //lpParam
      //Set font and text
      SetWndFont(aWnd[i][HWND], hGuiFont);
      SetWndText(aWnd[i][HWND], aWnd[i][TXT]);
    }

    //Hide Wait window
    ShowWaitWindow(0);

    //Set limit text of filters
    AkelPad.SendMessage(aWnd[IDFILTERCB0][HWND], 0x0141 /*CB_LIMITTEXT*/, 32, 0);
    AkelPad.SendMessage(aWnd[IDFILTERCB1][HWND], 0x0141 /*CB_LIMITTEXT*/, 32, 0);

    //Set extended UI in ComboBox Filter
    AkelPad.SendMessage(aWnd[IDFILTERCB0][HWND], 0x0155 /*CB_SETEXTENDEDUI*/, 1, 0);
    AkelPad.SendMessage(aWnd[IDFILTERCB1][HWND], 0x0155 /*CB_SETEXTENDEDUI*/, 1, 0);

    //Get handle to edit box in ComboBox Filter
    AkelPad.MemCopy(lpBuffer, _X64 ? 64 : 52 /*sizeof(COMBOBOXINFO)*/, DT_DWORD);
    oSys.Call("User32::GetComboBoxInfo", aWnd[IDFILTERCB0][HWND], lpBuffer);
    hWndFilterEdit0 = AkelPad.MemRead(_PtrAdd(lpBuffer, _X64 ? 48 : 44) /*hwndItem*/, DT_QWORD);
    oSys.Call("User32::GetComboBoxInfo", aWnd[IDFILTERCB1][HWND], lpBuffer);
    hWndFilterEdit1 = AkelPad.MemRead(_PtrAdd(lpBuffer, _X64 ? 48 : 44) /*hwndItem*/, DT_QWORD);

    //To capture NM_RETURN and LVN_KEYDOWN in ListView
    for (i = IDFILELV0; i <= IDSTREAMLV1; ++i)
      aSubClassHand[i] = AkelPad.WindowSubClass(aWnd[i][HWND], ListCallback, 0x87 /*WM_GETDLGCODE*/, 257 /*WM_KEYUP*/);

    //Set extended style and insert columns to ListView
    InsertColumnsLV();
    SetSortInHeader(-1);

    ShowControlsInPanel();
    FillFilterList();
    FillDriveList(0);
    FillDriveList(1);
    if (! FillFileList(0, aCurDir[0][aCurDrive[0]].File))
    {
      AddCurDir(0, aCurDrive[0] + "\\");
      FillFileList(0);
    }
    if (! FillFileList(1, aCurDir[1][aCurDrive[1]].File))
    {
      AddCurDir(1, aCurDrive[1] + "\\");
      FillFileList(1);
    }
    CheckHistory();
  }

  else if (uMsg == 7 /*WM_SETFOCUS*/)
  {
    oSys.Call("User32::SetFocus", aWnd[IDFILELV0 + nCurPan + aCurWnd[nCurPan] * 2][HWND]);
    QuickView(0);
    QuickView(1);
  }

  else if (uMsg == 36) //WM_GETMINMAXINFO
  {
    AkelPad.MemCopy(_PtrAdd(lParam, 24), oWndMin.W, DT_DWORD); //ptMinTrackSize_x
    AkelPad.MemCopy(_PtrAdd(lParam, 28), oWndMin.H, DT_DWORD); //ptMinTrackSize_y
  }

  else if (uMsg == 3) //WM_MOVE
  {
    if (oSys.Call("User32::IsZoomed", hWnd))
      oWndPos.Max = true;
    else
    {
      oWndPos.Max = false;
      GetWindowPos(hWnd, oWndPos);
    }
  }

  else if (uMsg == 5) //WM_SIZE
  {
    if (wParam == 2) //SIZE_MAXIMIZED
      oWndPos.Max = true;
    else
    {
      oWndPos.Max = false;
      GetWindowPos(hWnd, oWndPos);
    }
    ResizeWindow(hWnd);
  }

  else if (uMsg == 15) //WM_PAINT
    PaintPanelFrame(hWnd);

  else if (uMsg == 256 /*WM_KEYDOWN*/)
  {
    if ((oSys.Call("User32::GetFocus") == hWndFilterEdit0) ||
        (oSys.Call("User32::GetFocus") == hWndFilterEdit1))
    {
      if (wParam == 27 /*VK_ESCAPE*/)
      {
        SetWndText(aWnd[IDFILTERCB0 + Number(oSys.Call("User32::GetFocus") != hWndFilterEdit0)][HWND], aCurFilter[Number(oSys.Call("User32::GetFocus") != hWndFilterEdit0)]);
        oSys.Call("User32::SetFocus", aWnd[IDFILELV0 + nCurPan + aCurWnd[nCurPan] * 2][HWND]);
      }
      else if (wParam == 13 /*VK_RETURN*/)
      {
        SetCurFilter(Number(oSys.Call("User32::GetFocus") != hWndFilterEdit0));
        oSys.Call("User32::SetFocus", aWnd[IDFILELV0 + nCurPan + aCurWnd[nCurPan] * 2][HWND]);
      }
    }
  }

  else if (uMsg == 258 /*WM_CHAR*/)
  {
    if ((oSys.Call("User32::GetFocus") == aWnd[IDDRIVECB0][HWND]) ||
        (oSys.Call("User32::GetFocus") == aWnd[IDDRIVECB1][HWND]))
    {
      if (String.fromCharCode(wParam).toUpperCase() == GetDriveName(Number(oSys.Call("User32::GetFocus") == aWnd[IDDRIVECB1][HWND])).charAt(0))
        AkelPad.SendMessage(oSys.Call("User32::GetFocus"), 256 /*WM_KEYDOWN*/, 13 /*VK_RETURN*/, 0);
    }
  }

  else if (uMsg == 260 /*WM_SYSKEYDOWN*/)
  {
    if (wParam == 0x2E /*VK_DELETE*/)
    {
      if (AkelPad.SendMessage(aWnd[IDFILTERCB0][HWND], 0x0157 /*CB_GETDROPPEDSTATE*/, 0, 0))
        DeleteFilterCB(aWnd[IDFILTERCB0][HWND]);
      else if (AkelPad.SendMessage(aWnd[IDFILTERCB1][HWND], 0x0157 /*CB_GETDROPPEDSTATE*/, 0, 0))
        DeleteFilterCB(aWnd[IDFILTERCB1][HWND]);
    }
  }

  else if (uMsg == 0x0138) //WM_CTLCOLORSTATIC
  {
    if (lParam == aWnd[IDDIRS0 + nCurPan][HWND])
    {
      oSys.Call("Gdi32::SetTextColor", wParam, oSys.Call("User32::GetSysColor", 14 /*COLOR_HIGHLIGHTTEXT*/));
      oSys.Call("Gdi32::SetBkColor", wParam, oSys.Call("User32::GetSysColor", 13 /*COLOR_HIGHLIGHT*/));
      return oSys.Call("User32::GetSysColorBrush", 13 /*COLOR_HIGHLIGHT*/);
    }
  }

  else if ((uMsg == 0x004E /*WM_NOTIFY*/) && (wParam >= IDFILELV0) && (wParam <= IDSTREAMLV1))
  {
    switch (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 8) /*code*/, DT_DWORD))
    {
      case -101 : //LVN_ITEMCHANGED
        if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 32 : 20), DT_DWORD) == 0x3 /*LVIS_SELECTED|LVIS_FOCUSED*/) //uNewState
        {
          if (wParam <= IDFILELV1)
            FillStreamList(wParam - IDFILELV0, aCurDir[wParam - IDFILELV0][aCurDrive[wParam - IDFILELV0]].Stream);

          QuickView((wParam - IDFILELV0) % 2);
        }
        break;

      case -3 : //NM_DBLCLK
        if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_DWORD) == -1) //iItem
        {
          SetCurSelLV(aWnd[wParam][HWND], GetCurFocLV(aWnd[wParam][HWND]));
          break;
        }
      case -4 : //NM_RETURN
        if ((! Ctrl()) && (! Shift()) && (! Alt()))
          Open(nCurPan, 0);
        if ((! Ctrl()) && Shift() && (! Alt()))
          OpenIn(4);
        else if (Ctrl() && (! Shift()) && (! Alt()))
          RunAkelScript(0);
        else if (Ctrl() && Shift() && (! Alt()))
          RunAkelScript(1);
        else if ((! Ctrl()) && (! Shift()) && Alt())
          Properties();
        break;

      case -2 : //NM_CLICK
        if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_DWORD) == -1) //iItem
          SetCurSelLV(aWnd[wParam][HWND], GetCurFocLV(aWnd[wParam][HWND]));
        break;

      case -5 : //NM_RCLICK
      case -6 : //NM_RDBLCLK
        if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_DWORD) == -1) //iItem
          SetCurSelLV(aWnd[wParam][HWND], GetCurFocLV(aWnd[wParam][HWND]));
        else
          ContextMenu(AkelPad.MemRead(lParam, DT_QWORD) /*hwndFrom*/, lParam + (_X64 ? 44 : 32) /*ptAction*/);
        break;

      case -155 : //LVN_KEYDOWN
        if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12) /*wVKey*/, DT_WORD) == 9 /*VK_TAB*/) && (! Alt()))
        {
          if (Ctrl() || Shift())
            aCurWnd[nCurPan] = Number(! aCurWnd[nCurPan]);
          else if (bDualPan)
            nCurPan = Number(! nCurPan);
          oSys.Call("User32::SetFocus", aWnd[IDFILELV0 + nCurPan + aCurWnd[nCurPan] * 2][HWND]);
        }
        else if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x70 /*VK_F1*/)
        {
          if ((! Ctrl()) && (! Shift()) && (! Alt()))
            MainMenu();
          else if ((! Ctrl()) && (! Shift()) && Alt())
          {
            if (bDualPan || (nCurPan == 0))
              oSys.Call("User32::SetFocus", aWnd[IDDRIVECB0][HWND]);
          }
          else if ((! Ctrl()) && Shift() && (! Alt()))
            ShowColumn(1);
          else if (Ctrl() && (! Shift()) && (! Alt()))
            ShowPanel(0);
        }
        else if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x71 /*VK_F2*/)
        {
          if ((! Ctrl()) && (! Shift()) && Alt())
          {
            if (bDualPan || (nCurPan == 1))
              oSys.Call("User32::SetFocus", aWnd[IDDRIVECB1][HWND]);
          }
          else if ((! Ctrl()) && (! Shift()) && (! Alt()))
            Rename();
          else if ((! Ctrl()) && Shift() && (! Alt()))
            ShowColumn(2);
          else if (Ctrl() && (! Shift()) && (! Alt()))
            ShowPanel(1);
        }
        else if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x72 /*VK_F3*/)
        {
          if ((! Ctrl()) && (! Shift()) && (! Alt()))
            OpenIn(0, 1);
          else if (Ctrl() && (! Shift()) && (! Alt()))
            OpenIn(0, 2);
          else if (Ctrl() && Shift() && (! Alt()))
            SetExternalApp(0, 1);
          else if (Ctrl() && (! Shift()) && Alt())
            SetExternalApp(0, 2);
          else if ((! Ctrl()) && Shift() && (! Alt()))
            ShowColumn(3);
        }
        else if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x73 /*VK_F4*/)
        {
          if ((! Ctrl()) && (! Shift()) && (! Alt()))
            OpenIn(1, 1);
          else if (Ctrl() && (! Shift()) && (! Alt()))
            OpenIn(1, 2);
          else if (Ctrl() && Shift() && (! Alt()))
            SetExternalApp(1, 1);
          else if (Ctrl() && (! Shift()) && Alt())
            SetExternalApp(1, 2);
          else if ((! Ctrl()) && Shift() && (! Alt()))
            ShowColumn(4);
        }
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x74 /*VK_F5*/) &&
                 (! Ctrl()) && (! Alt()))
          Copy(0, Shift());

        //VK_F6 in ListCallback() -> Copy(1, 0)

        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x76 /*VK_F7*/) &&
                 (! Ctrl()) && (! Alt()))
          Create(! Shift());
        else if (((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x77 /*VK_F8*/) ||
                  (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x2E /*VK_DELETE*/)) &&
                 (! Ctrl()) && (! Alt()))
          Delete(! Shift());
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x78 /*VK_F9*/) &&
                 (! Ctrl()) && (! Shift()) && (! Alt()))
          RefreshPanel(2);
        else if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x7B /*VK_F12*/)
        {
          if ((! Ctrl()) && (! Shift()) && (! Alt()))
            Compare(1);
          else if (Ctrl() && (! Shift()) && (! Alt()))
            Compare(2);
          else if (Ctrl() && Shift() && (! Alt()))
            SetExternalApp(2, 1);
          else if (Ctrl() && (! Shift()) && Alt())
            SetExternalApp(2, 2);
        }
        else if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x25 /*VK_LEFT*/)
        {
          if ((! Ctrl()) && (! Shift()) && (! Alt()))
            Open(nCurPan, -1);
          else if (Ctrl() && (! Shift()) && (! Alt()))
            ClonePanel(0);
          else if ((! Ctrl()) && (! Shift()) && Alt())
            ChangeDirFromHistory(nCurPan, 0, -1);
          else if ((! Ctrl()) && Shift() && Alt())
            MoveDialog("L");
        }
        else if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x27 /*VK_RIGHT*/)
        {
          if ((! Ctrl()) && (! Shift()) && (! Alt()))
            Open(nCurPan, 1);
          else if (Ctrl() && (! Shift()) && (! Alt()))
            ClonePanel(1);
          else if ((! Ctrl()) && (! Shift()) && Alt())
            ChangeDirFromHistory(nCurPan, 0, 1);
          else if ((! Ctrl()) && Shift() && Alt())
            MoveDialog("R");
        }
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x26 /*VK_UP*/) &&
                 (! Ctrl()) && Shift() && Alt())
          MoveDialog("U");
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x28 /*VK_DOWN*/) &&
                 (! Ctrl()) && Shift() && Alt())
          MoveDialog("D");
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x23 /*VK_END*/) &&
                 (! Ctrl()) && Shift() && Alt())
          MoveDialog("E");
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x24 /*VK_HOME*/) &&
                 (! Ctrl()) && Shift() && Alt())
          MoveDialog("H");
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x21 /*VK_PRIOR*/) &&
                 (! Ctrl()) && Shift() && Alt())
          MoveDialog("T");
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x22 /*VK_NEXT*/) &&
                 (! Ctrl()) && Shift() && Alt())
          MoveDialog("B");
        else if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x2D /*VK_INSERT*/)
          CopyNameToCB(Number(Ctrl()) + Number(Shift()) * 2 + Number(Alt()) * 4);
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x31 /*1 key*/) &&
                 (! Ctrl()) && (! Shift()) && Alt())
        {
          if (bDualPan || (nCurPan == 0))
            oSys.Call("User32::SetFocus", aWnd[IDFILTERCB0][HWND]);
        }
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x32 /*2 key*/) &&
                 (! Ctrl()) && (! Shift()) && Alt())
        {
          if (bDualPan || (nCurPan == 1))
            oSys.Call("User32::SetFocus", aWnd[IDFILTERCB1][HWND]);
        }
        else if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x43 /*C key*/)
        {
          if ((! Ctrl()) && Shift() && Alt())
            MoveDialog("C");
          else if (Ctrl() && (! Shift()) && (! Alt()))
            CopyListToCB(0);
          else if ((! Ctrl()) && (! Shift()) && Alt())
            CopyListToCB(1);
        }
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x46 /*F key*/) &&
                 (! Ctrl()) && (! Shift()) && Alt())
          FavoriteFolders(nCurPan);
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x48 /*H key*/) &&
                 (! Ctrl()) && (! Shift()) && Alt())
          History(nCurPan);
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x4D /*M key*/) &&
                 (! Ctrl()) && Shift() && Alt())
          MoveDialog("M");
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x51 /*Q key*/) &&
                 Ctrl() && (! Shift()) && (! Alt()))
          ShowQuickView();
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x53 /*S key*/) &&
                 (! Ctrl()) && (! Shift()) && Alt())
          SpecialFolders(nCurPan);
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x55 /*U key*/) &&
                 Ctrl() && (! Shift()) && (! Alt()))
          SwapPanels();
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0xDC /*VK_OEM_4 == backslash*/) &&
                 Ctrl() && (! Shift()) && (! Alt()))
          Open(nCurPan, -2);
        else if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 0x5D /*VK_APPS*/)
          ContextMenu(AkelPad.MemRead(lParam, DT_QWORD) /*hwndFrom*/);
        else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_WORD) == 27 /*VK_ESCAPE*/) &&
                 (! Ctrl()) && (! Shift()) && (! Alt()))
          oSys.Call("User32::PostMessageW", hWnd, 16 /*WM_CLOSE*/, 0, 0);
        break;

      case -12 : //NM_CUSTOMDRAW
        if ((wParam == IDFILELV0 + Number(! nCurPan) + aCurWnd[Number(! nCurPan)] * 2) ||
            ((wParam == IDFILELV0 + nCurPan + aCurWnd[nCurPan] * 2) &&
             (oSys.Call("User32::GetFocus") != aWnd[IDFILELV0][HWND]) &&
             (oSys.Call("User32::GetFocus") != aWnd[IDFILELV1][HWND]) &&
             (oSys.Call("User32::GetFocus") != aWnd[IDSTREAMLV0][HWND]) &&
             (oSys.Call("User32::GetFocus") != aWnd[IDSTREAMLV1][HWND])))
        {
          AkelPad.MemCopy(_PtrAdd(lParam, _X64 ? 64 : 40) /*uItemState*/, 0x20 /*CDIS_DEFAULT*/, DT_DWORD);

          if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12) /*dwDrawStage*/, DT_DWORD) == 0x1 /*CDDS_PREPAINT*/)
            return 0x20; //CDRF_NOTIFYITEMDRAW
          else if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_DWORD) == 0x10001 /*CDDS_ITEMPREPAINT*/)
            return 0x20; //CDRF_NOTIFYSUBITEMDRAW
          else if ((AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12), DT_DWORD) == 0x30001 /*CDDS_ITEMPREPAINT|CDDS_SUBITEM*/) &&
                   (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 56 : 36) /*dwItemSpec*/, DT_DWORD) == GetCurSelLV(aWnd[wParam][HWND])))
          {
            if (wParam == IDFILELV0 + Number(! nCurPan) + aCurWnd[Number(! nCurPan)] * 2)
            {
              AkelPad.MemCopy(_PtrAdd(lParam, _X64 ? 80 : 48) /*clrText*/, oSys.Call("User32::GetSysColor", 3 /*COLOR_INACTIVECAPTION*/), DT_DWORD);
              AkelPad.MemCopy(_PtrAdd(lParam, _X64 ? 84 : 52) /*clrTextBk*/, oSys.Call("User32::GetSysColor", 19 /*COLOR_INACTIVECAPTIONTEXT*/), DT_DWORD);
            }
            else
            {
              AkelPad.MemCopy(_PtrAdd(lParam, _X64 ? 80 : 48) /*clrText*/, oSys.Call("User32::GetSysColor", 14 /*COLOR_HIGHLIGHTTEXT*/), DT_DWORD);
              AkelPad.MemCopy(_PtrAdd(lParam, _X64 ? 84 : 52) /*clrTextBk*/, oSys.Call("User32::GetSysColor", 13 /*COLOR_HIGHLIGHT*/), DT_DWORD);
            }
            return 0x10; //CDRF_NOTIFYPOSTPAINT
          }
        }
        break;

      case -7 : //NM_SETFOCUS
        nCurPan = (wParam - IDFILELV0) % 2;
        aCurWnd[nCurPan] = Number(wParam > IDFILELV1);

        SetWndText(aWnd[IDDIRS0 + Number(! nCurPan)][HWND], aCurDir[Number(! nCurPan)][aCurDrive[Number(! nCurPan)]].Path);
        SetWndText(aWnd[IDDIRS0 + nCurPan][HWND], aCurDir[nCurPan][aCurDrive[nCurPan]].Path);

        for (var i = IDFILELV0; i <= IDSTREAMLV1; ++i)
          AkelPad.SendMessage(aWnd[i][HWND], 0x1015 /*LVM_REDRAWITEMS*/, GetCurSelLV(aWnd[i][HWND]), GetCurSelLV(aWnd[i][HWND]));

        QuickView(nCurPan);
        break;

      case -108 : //LVN_COLUMNCLICK
        if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 28 : 16) /*iSubItem*/, DT_DWORD) < 4)
        {
          SetSortInHeader(AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 8 : 4) /*idFrom*/, DT_QWORD), AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 28 : 16) /*iSubItem*/, DT_DWORD));
          SortList(AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 8 : 4) /*idFrom*/, DT_QWORD));
        }
    }
  }

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

    if ((nLowParam == IDDRIVECB0) || (nLowParam == IDDRIVECB1))
    {
      if (nHiwParam == 3 /*CBN_SETFOCUS*/)
      {
        FillDriveList(nLowParam - IDDRIVECB0);
        oSys.Call("User32::PostMessageW", lParam, 0x014F /*CB_SHOWDROPDOWN*/, 1, 0);
      }
      else if (nHiwParam == 9 /*CBN_SELENDOK*/)
      {
        if (ChangeDrive(nLowParam - IDDRIVECB0))
          oSys.Call("User32::SetFocus", aWnd[IDFILELV0 + nCurPan + aCurWnd[nCurPan] * 2][HWND]);
      }
      else if (nHiwParam == 10 /*CBN_SELENDCANCEL*/)
      {
        oSys.Call("User32::SetFocus", aWnd[IDFILELV0 + nCurPan + aCurWnd[nCurPan] * 2][HWND]);
        SelCurDriveCB(nLowParam - IDDRIVECB0);
      }
    }
    else if ((nLowParam == IDFILTERCB0) || (nLowParam == IDFILTERCB1))
    {
      if (nHiwParam == 3 /*CBN_SETFOCUS*/)
      {
        AkelPad.SendMessage(lParam, 0x0142 /*CB_SETEDITSEL*/, 0, MkLong(0, -1));
        oSys.Call("User32::PostMessageW", lParam, 0x014F /*CB_SHOWDROPDOWN*/, 1, 0);
      }
      else if (nHiwParam == 4 /*CBN_KILLFOCUS*/)
      {
        SetCurFilter(nLowParam - IDFILTERCB0);
        oSys.Call("User32::SetFocus", aWnd[IDFILELV0 + nCurPan + aCurWnd[nCurPan] * 2][HWND]);
      }
    }
    else if ((nLowParam >= IDMAINDIRB0) && (nLowParam <= IDCOMPAREB))
    {
      AkelPad.SendMessage(lParam, 0x00F4 /*BM_SETSTYLE*/, 0 /*BS_PUSHBUTTON*/, 0);

      if ((nLowParam == IDMAINDIRB0) || (nLowParam == IDMAINDIRB1))
        Open(nLowParam - IDMAINDIRB0, -2);
      else if ((nLowParam == IDUPDIRB0) || (nLowParam == IDUPDIRB1))
        Open(nLowParam - IDUPDIRB0, -1);
      else if ((nLowParam == IDFAVFOLDB0) || (nLowParam == IDFAVFOLDB1))
        FavoriteFolders(nLowParam - IDFAVFOLDB0);
      else if ((nLowParam == IDSPECFOLDB0) || (nLowParam == IDSPECFOLDB1))
        SpecialFolders(nLowParam - IDSPECFOLDB0);
      else if ((nLowParam == IDHISTORYB0) || (nLowParam == IDHISTORYB1))
        History(nLowParam - IDHISTORYB0);
      else if ((nLowParam == IDLEFTB) || (nLowParam == IDRIGHTB))
        ClonePanel(nLowParam - IDLEFTB)
      else if (nLowParam == IDMENUB)
        MainMenu();
      else if (nLowParam == IDRENAMEB)
        Rename();
      else if (nLowParam == IDVIEWB)
        OpenIn(0, 1);
      else if (nLowParam == IDEDITB)
        OpenIn(1, 1);
      else if (nLowParam == IDCOPYB)
        Copy(0, 0);
      else if (nLowParam == IDMOVEB)
        Copy(1, 0);
      else if (nLowParam == IDCREATEB)
        Create(1);
      else if (nLowParam == IDDELETEB)
        Delete(1);
      else if (nLowParam == IDREFRESHB)
        RefreshPanel(2);
      else if (nLowParam == IDCOMPAREB)
        Compare(1);

      oSys.Call("User32::SetFocus", aWnd[IDFILELV0 + nCurPan + aCurWnd[nCurPan] * 2][HWND]);
    }
  }

  else if (uMsg == 123) //WM_CONTEXTMENU
  {
    switch (wParam)
    {
      case aWnd[IDVIEWB][HWND] : OpenIn(0, 2);
        break;
      case aWnd[IDEDITB][HWND] : OpenIn(1, 2);
        break;
      case aWnd[IDCOPYB][HWND] : Copy(0, 1);
        break;
      case aWnd[IDCREATEB][HWND] : Create(0);
        break;
      case aWnd[IDDELETEB][HWND] : Delete(0);
        break;
      case aWnd[IDCOMPAREB][HWND] : Compare(2);
    }
  }

  else if (uMsg == 16) //WM_CLOSE
  {
    for (var i = IDFILELV0; i <= IDSTREAMLV1; ++i)
      AkelPad.WindowUnsubClass(aWnd[i][HWND]);

    ReadWriteIni(true);
    oSys.Call("User32::DestroyWindow", hWnd); //Destroy dialog
  }

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

  return 0;
}

function ListCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 0x87) //WM_GETDLGCODE
  {
    AkelPad.WindowNoNextProc(aSubClassHand[oSys.Call("User32::GetDlgCtrlID", hWnd)]);
    return 0x4; //DLGC_WANTALLKEYS
  }
  else if ((uMsg == 257 /*WM_KEYUP*/) && (wParam == 0x75 /*VK_F6*/) &&
           (! Ctrl()) && (! Shift()) && (! Alt()))
    Copy(1, 0);

  return 0;
}

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

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

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

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

function Ctrl()
{
  return Boolean(oSys.Call("User32::GetKeyState", 0x11 /*VK_CONTROL*/) & 0x8000);
}

function Alt()
{
  return Boolean(oSys.Call("User32::GetKeyState", 0x12 /*VK_MENU*/) & 0x8000);
}

function PaintPanelFrame(hWnd)
{
  var lpPaint = AkelPad.MemAlloc(_X64 ? 72 : 64); //sizeof(PAINTSTRUCT)
  var lpRect  = AkelPad.MemAlloc(16); //sizeof(RECT)
  var hDC     = oSys.Call("User32::BeginPaint", hWnd, lpPaint);
  var nW;
  var nH;

  oSys.Call("User32::GetClientRect", hWnd, lpRect);
  nW = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD);
  nH = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD);

  AkelPad.MemCopy(_PtrAdd(lpRect,  0), 2, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpRect,  4), 5, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpRect,  8), (bDualPan ? Math.round(nW / 2) : nW) - 2, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpRect, 12), nH - 21 - 7, DT_DWORD);
  oSys.Call("User32::DrawEdge", hDC, lpRect, 0x9 /*EDGE_BUMP*/, 0x800F /*BF_MONO|BF_RECT*/);

  if (bDualPan)
  {
    AkelPad.MemCopy(lpRect, nW - Math.round(nW / 2) + 2, DT_DWORD);
    AkelPad.MemCopy(_PtrAdd(lpRect, 8), nW - 2, DT_DWORD);
    oSys.Call("User32::DrawEdge", hDC, lpRect, 0x9 /*EDGE_BUMP*/, 0x800F /*BF_MONO|BF_RECT*/);
  }

  oSys.Call("User32::EndPaint", hWnd, lpPaint);

  AkelPad.MemFree(lpPaint);
  AkelPad.MemFree(lpRect);
}

function ResizeWindow(hWnd)
{
  var lpRect    = AkelPad.MemAlloc(16); //sizeof(RECT)
  var aRect     = [{}, {}];
  var aColWidth = [0, 0, 0, 0];
  var nW, nH;
  var i, n;

  oSys.Call("User32::GetClientRect", hWnd, lpRect);
  nW = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD);
  nH = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD);
  AkelPad.MemFree(lpRect);

  aRect[0].X = 2;
  aRect[0].Y = 5;
  aRect[0].W = (bDualPan ? Math.round(nW / 2) : nW) - 2;
  aRect[0].H = nH - 21 - 7;
  aRect[1].X = bDualPan ? (nW - Math.round(nW / 2) + 2) : 2;
  aRect[1].Y = aRect[0].Y;
  aRect[1].W = nW - 2;
  aRect[1].H = aRect[0].H;

  for (i = IDDRIVECB0; i <= IDDRIVECB1; ++i)
    oSys.Call("User32::SetWindowPos",
              aWnd[i][HWND], 0,
              aRect[i - IDDRIVECB0].X + 3,
              10,
              37,
              21,
              0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/);

  for (i = IDMAINDIRB0; i <= IDRIGHTB; ++i)
    oSys.Call("User32::SetWindowPos",
              aWnd[i][HWND], 0,
              aRect[(i - IDMAINDIRB0) % 2].X + 42 + 21 * (((i - IDMAINDIRB0) - (i - IDMAINDIRB0) % 2) / 2),
              10,
              21,
              21,
              0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/);

  for (i = IDFILTERS0; i <= IDFILTERS1; ++i)
    oSys.Call("User32::SetWindowPos",
              aWnd[i][HWND], 0,
              aRect[i - IDFILTERS0].W - 55 - 100 - 5,
              13,
              55,
              13,
              0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/);

  for (i = IDFILTERCB0; i <= IDFILTERCB1; ++i)
    oSys.Call("User32::SetWindowPos",
              aWnd[i][HWND], 0,
              aRect[i - IDFILTERCB0].W - 100 - 3,
              10,
              100,
              21,
              0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/);

  for (i = IDDIRS0; i <= IDDIRS1; ++i)
    oSys.Call("User32::SetWindowPos",
              aWnd[i][HWND], 0,
              aRect[i - IDDIRS0].X,
              35,
              aRect[i - IDDIRS0].W - aRect[i - IDDIRS0].X,
              16,
              0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/);

  for (i = IDFILELV0; i <= IDFILELV1; ++i)
    oSys.Call("User32::SetWindowPos",
              aWnd[i][HWND], 0,
              aRect[i - IDFILELV0].X,
              50,
              aRect[i - IDFILELV0].W - aRect[i - IDFILELV0].X,
              aRect[i - IDFILELV0].H - (bQuickView ? 224 : 224 - 68),
              0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/);

  for (i = IDSTREAMLV0; i <= IDSTREAMLV1; ++i)
    oSys.Call("User32::SetWindowPos",
              aWnd[i][HWND], 0,
              aRect[i - IDSTREAMLV0].X,
              aRect[i - IDSTREAMLV0].H - (bQuickView ? 175 : 175 - 68),
              aRect[i - IDSTREAMLV0].W - aRect[i - IDSTREAMLV0].X,
              108,
              0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/);

  for (i = IDQUICKVIEWS0; i <= IDQUICKVIEWS1; ++i)
    oSys.Call("User32::SetWindowPos",
              aWnd[i][HWND], 0,
              aRect[i - IDQUICKVIEWS0].X,
              aRect[i - IDQUICKVIEWS0].H - 68,
              aRect[i - IDQUICKVIEWS0].W - aRect[i - IDQUICKVIEWS0].X,
              68,
              0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/);

  for (i = IDMENUB; i <= IDCOMPAREB; ++i)
    oSys.Call("User32::SetWindowPos",
              aWnd[i][HWND], 0,
              2 + (i - IDMENUB) * ((nW - (IDCOMPAREB - IDMENUB + 2) * 2) / (IDCOMPAREB - IDMENUB + 1) + 2),
              nH - 21 - 2,
              (nW - (IDCOMPAREB - IDMENUB + 2) * 2) / (IDCOMPAREB - IDMENUB + 1),
              21,
              0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/);

  oSys.Call("User32::SetWindowPos",
            aWnd[IDWAIT][HWND], 0,
            nW / 2 - 140,
            nH / 2 - 50,
            280,
            100,
            0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/);

  if (bColSize)
    aColWidth[1] = 72;
  if (bColTime)
    aColWidth[2] = 96;
  if (bColAttr)
    aColWidth[3] = 52;

  for (i = IDFILELV0; i <= IDFILELV1; ++i)
  {
    aColWidth[0] = aRect[i - IDFILELV0].W - aRect[i - IDFILELV0].X - aColWidth[1] - aColWidth[2] - aColWidth[3] - 17;

    for (n = 0; n < 4; ++n)
      AkelPad.SendMessage(aWnd[i][HWND], 0x101E /*LVM_SETCOLUMNWIDTH*/, n, aColWidth[n]);
  }

  for (i = IDSTREAMLV0; i <= IDSTREAMLV1; ++i)
  {
    aColWidth[0] = aRect[i - IDSTREAMLV0].W - aRect[i - IDSTREAMLV0].X - aColWidth[1] - 17;

    for (n = 0; n < 2; ++n)
      AkelPad.SendMessage(aWnd[i][HWND], 0x101E /*LVM_SETCOLUMNWIDTH*/, n, aColWidth[n]);
  }

  for (i = IDFILELV0; i <= IDSTREAMLV1; ++i)
    AkelPad.SendMessage(aWnd[i][HWND], 0x1013 /*LVM_ENSUREVISIBLE*/, GetCurSelLV(aWnd[i][HWND]), false);

  oSys.Call("user32::InvalidateRect", hWnd, 0, true);
}

function ShowControlsInPanel()
{
  var bVisible;

  if (bDualPan || (nCurPan == 0))
    bVisible = 1;
  else
    bVisible = 0;

  for (i = IDFILTERS0; i <= IDLEFTB; i += 2)
    oSys.Call("User32::ShowWindow", aWnd[i][HWND], (i == IDQUICKVIEWS0) ? (bVisible && bQuickView) : bVisible);

  if (bDualPan || (nCurPan == 1))
    bVisible = 1;
  else
    bVisible = 0;

  for (i = IDFILTERS1; i <= IDRIGHTB; i += 2)
    oSys.Call("User32::ShowWindow", aWnd[i][HWND], (i == IDQUICKVIEWS1) ? (bVisible && bQuickView) : bVisible);
}

function ShowPanel(nPan)
{
  if (bDualPan || (nPan != nCurPan))
  {
    var nFrameX = oSys.Call("User32::GetSystemMetrics", 32 /*SM_CXSIZEFRAME*/);
    var oRect   = {};

    GetWindowPos(hWndDlg, oRect);

    bDualPan = ! bDualPan;

    if (nPan == nCurPan)
    {
      nCurPan = Number(! nCurPan);
      oSys.Call("User32::SetFocus", aWnd[IDFILELV0 + nCurPan + aCurWnd[nCurPan] * 2][HWND]);
    }

    if (bDualPan)
    {
      if (nCurPan == 1)
        oRect.X = (oRect.X + oRect.W) - 2 * (oRect.W - nFrameX);

      oRect.W   = 2 * (oRect.W - nFrameX);
      oWndMin.W = 2 * (oWndMin.W - nFrameX);
    }
    else
    {
      if (nCurPan == 1)
        oRect.X = (oRect.X + oRect.W) - (Math.round((oRect.W - 2 * nFrameX) / 2) + 2 * nFrameX);

      oRect.W   = Math.round((oRect.W - 2 * nFrameX) / 2) + 2 * nFrameX;
      oWndMin.W = Math.round((oWndMin.W - 2 * nFrameX) / 2) + 2 * nFrameX;
    }

    oSys.Call("User32::MoveWindow", hWndDlg, oRect.X, oRect.Y, oRect.W, oRect.H, 1);
    ShowControlsInPanel();
    oSys.Call("User32::InvalidateRect", hWndDlg, 0, true);
    ResizeWindow(hWndDlg);
  }
}

function ShowQuickView()
{
  bQuickView = ! bQuickView;

  QuickView(0);
  QuickView(1);

  ShowControlsInPanel();
  ResizeWindow(hWndDlg);
}

function ShowColumn(nCol)
{
  if (nCol == 1)
  {
    if (bColSize || bColTime || bColAttr)
    {
      bColSize = false;
      bColTime = false;
      bColAttr = false;
    }
    else
    {
      bColSize = true;
      bColTime = true;
      bColAttr = true;
    }
  }
  else if (nCol == 2)
    bColSize = ! bColSize;
  else if (nCol == 3)
    bColTime = ! bColTime;
  else if (nCol == 4)
    bColAttr = ! bColAttr;

  ResizeWindow(hWndDlg);
}

function MoveDialog(sAction)
{
  if (sAction == "M")
  {
    if (oSys.Call("User32::IsZoomed", hWndDlg))
      oSys.Call("User32::ShowWindow", hWndDlg, 9 /*SW_RESTORE*/);
    else
      oSys.Call("User32::ShowWindow", hWndDlg, 3 /*SW_MAXIMIZE*/);
  }

  else if (! oSys.Call("User32::IsZoomed", hWndDlg))
  {
    var oRectDesk = {};
    var oRect     = {};

    GetWindowPos(oSys.Call("User32::GetDesktopWindow"), oRectDesk);
    GetWindowPos(hWndDlg, oRect);

    if (sAction == "R") //Right
      oRect.X = oRect.X + ((oRect.X < oRectDesk.X + oRectDesk.W - 50) ? 20 : 0);
    else if (sAction == "L") //Left
      oRect.X = oRect.X - ((oRect.X + oRect.W > oRectDesk.X + 50) ? 20 : 0);
    else if (sAction == "D") //Down
      oRect.Y = oRect.Y + ((oRect.Y < oRectDesk.Y + oRectDesk.H - 50) ? 20 : 0);
    else if (sAction == "U") //Up
      oRect.Y = oRect.Y - ((oRect.Y + oRect.H > oRectDesk.Y + 50) ? 20 : 0);
    else if (sAction == "E") //End (to right edge)
      oRect.X = oRectDesk.X + oRectDesk.W - oRect.W;
    else if (sAction == "H") //Home (to left edge)
      oRect.X = oRectDesk.X;
    else if (sAction == "B") //Bottom edge
      oRect.Y = oRectDesk.Y + oRectDesk.H - oRect.H;
    else if (sAction == "T") //Top edge
      oRect.Y = oRectDesk.Y;
    else if (sAction == "C") //Center
    {
      oRect.X = oRectDesk.X + (oRectDesk.W - oRect.W) / 2;
      oRect.Y = oRectDesk.Y + (oRectDesk.H - oRect.H) / 2;
    }

    oSys.Call("User32::SetWindowPos", hWndDlg, 0, oRect.X, oRect.Y, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
  }
}

function GetWindowPos(hWnd, oRect)
{
  var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)

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

  oRect.X = AkelPad.MemRead(_PtrAdd(lpRect,  0), DT_DWORD);
  oRect.Y = AkelPad.MemRead(_PtrAdd(lpRect,  4), DT_DWORD);
  oRect.W = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD) - oRect.X;
  oRect.H = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD) - oRect.Y;

  AkelPad.MemFree(lpRect);
}

function GetControlPos(hWnd, hControl, oRect)
{
  var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)

  oSys.Call("User32::GetWindowRect", hControl, lpRect);
  oRect.W = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD) - AkelPad.MemRead(_PtrAdd(lpRect, 0), DT_DWORD);
  oRect.H = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD) - AkelPad.MemRead(_PtrAdd(lpRect, 4), DT_DWORD);

  oSys.Call("User32::ScreenToClient", hWnd, lpRect);
  oRect.X = AkelPad.MemRead(_PtrAdd(lpRect, 0), DT_DWORD);
  oRect.Y = AkelPad.MemRead(_PtrAdd(lpRect, 4), DT_DWORD);

  AkelPad.MemFree(lpRect);
}

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

function SetWndText(hWnd, sText)
{
  oSys.Call("User32::SetWindowTextW", hWnd, sText);
}

function ShowWaitWindow(bShow)
{
  oSys.Call("User32::ShowWindow", aWnd[IDWAIT][HWND], bShow);

  if (bShow)
    SetWndText(aWnd[IDWAIT][HWND], "\n\n\n" + sTxtWait);
}

function InsertColumnsLV()
{
  var lpLVCOLUMN = AkelPad.MemAlloc(_X64 ? 56 : 44) //sizeof(LVCOLUMN)
  var nMask      = 7; //LVCF_FMT|LVCF_WIDTH|LVCF_TEXT
  var aFmt       = [0 /*LVCFMT_LEFT*/, 1 /*LVCFMT_RIGHT*/, 0, 0, 0]; //Alignment of the column header
  var aText      = [AkelPad.MemStrPtr(sTxtFileName), AkelPad.MemStrPtr(sTxtSize), AkelPad.MemStrPtr(sTxtTime), AkelPad.MemStrPtr(sTxtAttrib), AkelPad.MemStrPtr("")];
  var i, n;

  AkelPad.MemCopy(lpLVCOLUMN, nMask, DT_DWORD);

  for (i = IDFILELV0; i <= IDFILELV1; ++i)
  {
    AkelPad.SendMessage(aWnd[i][HWND], 0x1036 /*LVM_SETEXTENDEDLISTVIEWSTYLE*/, 0x0020 /*LVS_EX_FULLROWSELECT*/, 0x0020);

    for (n = 0; n < aFmt.length; ++n)
    {
      AkelPad.MemCopy(_PtrAdd(lpLVCOLUMN, 4), aFmt[n], DT_DWORD);
      AkelPad.MemCopy(_PtrAdd(lpLVCOLUMN, _X64 ? 16 : 12), aText[n], DT_QWORD);

      AkelPad.SendMessage(aWnd[i][HWND], 0x1061 /*LVM_INSERTCOLUMNW*/, n, lpLVCOLUMN);
    }
  }

  aFmt  = aFmt.slice(0,2);
  aText = [AkelPad.MemStrPtr(sTxtStrName), AkelPad.MemStrPtr(sTxtSize)];

  for (i = IDSTREAMLV0; i <= IDSTREAMLV1; ++i)
  {
    AkelPad.SendMessage(aWnd[i][HWND], 0x1036 /*LVM_SETEXTENDEDLISTVIEWSTYLE*/, 0x0020 /*LVS_EX_FULLROWSELECT*/, 0x0020);

    for (n = 0; n < aFmt.length; ++n)
    {
      AkelPad.MemCopy(_PtrAdd(lpLVCOLUMN, 4), aFmt[n], DT_DWORD);
      AkelPad.MemCopy(_PtrAdd(lpLVCOLUMN, _X64 ? 16 : 12), aText[n], DT_QWORD);

      AkelPad.SendMessage(aWnd[i][HWND], 0x1061 /*LVM_INSERTCOLUMNW*/, n, lpLVCOLUMN);
    }
  }

  AkelPad.MemFree(lpLVCOLUMN);
}

Last edited by KDJ on Wed Jan 07, 2015 8:07 pm, edited 26 times in total.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Manager of files and NTFS streams - Part Two.
See next post.

Code: Select all

function SetSortInHeader(nID, nCol)
{
  var HDF_SORTDOWN = 0x0200;
  var HDF_SORTUP   = 0x0400;
  var lpHDITEM     = AkelPad.MemAlloc(_X64 ? 72 : 48); //sizeof(HDITEM)
  var hHeader;
  var nFmt;

  AkelPad.MemCopy(lpHDITEM, 0x04 | 0x02 /*HDI_FORMAT|HDI_TEXT*/, DT_DWORD); //mask
  AkelPad.MemCopy(_PtrAdd(lpHDITEM, 8), lpBuffer, DT_QWORD); //pszText
  AkelPad.MemCopy(_PtrAdd(lpHDITEM, _X64 ? 24 : 16), nBufSize, DT_DWORD); //cchTextMax

  if (nID == -1)
  {
    for (nID = IDFILELV0; nID <= IDSTREAMLV1; ++nID)
    {
      hHeader = AkelPad.SendMessage(aWnd[nID][HWND], 0x101F /*LVM_GETHEADER*/, 0, 0);

      for (nCol = 0; nCol < AkelPad.SendMessage(hHeader, 0x1200 /*HDM_GETITEMCOUNT*/, 0, 0) - ((nID <= IDFILELV1) ? 1 : 0); ++nCol)
      {
        AkelPad.SendMessage(hHeader, 0x120B /*HDM_GETITEMW*/, nCol, lpHDITEM);

        nFmt = AkelPad.MemRead(_PtrAdd(lpHDITEM, _X64 ? 28 : 20), DT_DWORD); //fmt
        if (nFmt & HDF_SORTDOWN)
          nFmt ^= HDF_SORTDOWN;
        if (nFmt & HDF_SORTUP)
          nFmt ^= HDF_SORTUP;

        if (aSort[nID - IDFILELV0][0] == nCol)
          nFmt |= aSort[nID - IDFILELV0][1] ? HDF_SORTDOWN : HDF_SORTUP;

        AkelPad.MemCopy(_PtrAdd(lpHDITEM, _X64 ? 28 : 20), nFmt, DT_DWORD);
        AkelPad.SendMessage(hHeader, 0x120C /*HDM_SETITEMW*/, nCol, lpHDITEM);
      }
    }
  }
  else
  {
    hHeader = AkelPad.SendMessage(aWnd[nID][HWND], 0x101F /*LVM_GETHEADER*/, 0, 0);

    AkelPad.SendMessage(hHeader, 0x120B /*HDM_GETITEMW*/, aSort[nID - IDFILELV0][0], lpHDITEM);

    nFmt = AkelPad.MemRead(_PtrAdd(lpHDITEM, _X64 ? 28 : 20), DT_DWORD); //fmt
    if (nFmt & HDF_SORTDOWN)
      nFmt ^= HDF_SORTDOWN;
    if (nFmt & HDF_SORTUP)
      nFmt ^= HDF_SORTUP;

    AkelPad.MemCopy(_PtrAdd(lpHDITEM, _X64 ? 28 : 20), nFmt, DT_DWORD);
    AkelPad.SendMessage(hHeader, 0x120C /*HDM_SETITEMW*/, aSort[nID - IDFILELV0][0], lpHDITEM);

    if (aSort[nID - IDFILELV0][0] == nCol)
      aSort[nID - IDFILELV0][1] = Number(! aSort[nID - IDFILELV0][1]);
    else
    {
      aSort[nID - IDFILELV0][0] = nCol;
      aSort[nID - IDFILELV0][1] = 0;
    }

    AkelPad.SendMessage(hHeader, 0x120B /*HDM_GETITEMW*/, nCol, lpHDITEM);

    nFmt = AkelPad.MemRead(_PtrAdd(lpHDITEM, _X64 ? 28 : 20), DT_DWORD); //fmt
    AkelPad.MemCopy(_PtrAdd(lpHDITEM, _X64 ? 28 : 20), nFmt | ((aSort[nID - IDFILELV0][1]) ? HDF_SORTDOWN : HDF_SORTUP), DT_DWORD);
    AkelPad.SendMessage(hHeader, 0x120C /*HDM_SETITEMW*/, nCol, lpHDITEM);
  }

  AkelPad.MemFree(lpHDITEM);
}

function SortList(nID)
{
  var lpCallback;

  if (aSort[nID - IDFILELV0][0] == 0)
    lpCallback = oSys.RegisterCallback(CompareNameCallback);
  else if (aSort[nID - IDFILELV0][0] == 1)
    lpCallback = oSys.RegisterCallback(CompareSizeCallback);
  else if (aSort[nID - IDFILELV0][0] == 2)
    lpCallback = oSys.RegisterCallback(CompareTimeCallback);
  else
    lpCallback = oSys.RegisterCallback(CompareAttrCallback);

  hWndSort = aWnd[nID][HWND];

  AkelPad.SendMessage(hWndSort, 0x1051 /*LVM_SORTITEMSEX*/, aSort[nID - IDFILELV0][1], lpCallback);

  AkelPad.SendMessage(hWndSort, 0x1013 /*LVM_ENSUREVISIBLE*/, GetCurSelLV(hWndSort), false);

  oSys.UnregisterCallback(lpCallback);
}

function CompareNameCallback(nItem1, nItem2, bDescending)
{
  var sName1  = GetTextLV(hWndSort, nItem1, 0);
  var sName2  = GetTextLV(hWndSort, nItem2, 0);
  var bIsDir1 = (GetTextLV(hWndSort, nItem1, 1).substr(0, 1) == "<");
  var bIsDir2 = (GetTextLV(hWndSort, nItem2, 1).substr(0, 1) == "<");

  if ((sName1 == "..") || ((bIsDir1) && (! bIsDir2)))
    return -1;
  else if ((sName2 == "..") || ((! bIsDir1) && (bIsDir2)))
    return 1;
  else
  {
    if (sName1 == sTxtMainStream)
      sName1 = "";
    if (sName2 == sTxtMainStream)
      sName2 = "";
    return (bDescending ? -1 : 1) * oSys.Call("Kernel32::lstrcmpiW", sName1, sName2);
  }
}

function CompareSizeCallback(nItem1, nItem2, bDescending)
{
  var sName1  = GetTextLV(hWndSort, nItem1, 0);
  var sName2  = GetTextLV(hWndSort, nItem2, 0);
  var sSize1  = GetTextLV(hWndSort, nItem1, 1);
  var sSize2  = GetTextLV(hWndSort, nItem2, 1);
  var bIsDir1 = (sSize1.substr(0, 1) == "<");
  var bIsDir2 = (sSize2.substr(0, 1) == "<");

  if ((sName1 == "..") || ((bIsDir1) && (! bIsDir2)))
    return -1;
  else if ((sName2 == "..") || ((! bIsDir1) && (bIsDir2)))
    return 1;
  else if (bIsDir1 && bIsDir2)
    return oSys.Call("Kernel32::lstrcmpiW", sName1, sName2);
  else
  {
    if (Number(sSize1) < Number(sSize2))
      return (bDescending ? 1 : -1);
    else if (Number(sSize1) > Number(sSize2))
      return (bDescending ? -1 : 1);
    else
    {
      if (sName1 == sTxtMainStream)
        sName1 = "";
      if (sName2 == sTxtMainStream)
        sName2 = "";
      return oSys.Call("Kernel32::lstrcmpiW", sName1, sName2);
    }
  }
}

function CompareTimeCallback(nItem1, nItem2, bDescending)
{
  var sName1  = GetTextLV(hWndSort, nItem1, 0);
  var sName2  = GetTextLV(hWndSort, nItem2, 0);
  var nTime1  = parseInt(GetTextLV(hWndSort, nItem1, 4), 16);
  var nTime2  = parseInt(GetTextLV(hWndSort, nItem2, 4), 16);
  var bIsDir1 = (GetTextLV(hWndSort, nItem1, 1).substr(0, 1) == "<");
  var bIsDir2 = (GetTextLV(hWndSort, nItem2, 1).substr(0, 1) == "<");

  if ((sName1 == "..") || ((bIsDir1) && (! bIsDir2)))
    return -1;
  else if ((sName2 == "..") || ((! bIsDir1) && (bIsDir2)))
    return 1;
  else
  {
    if (nTime1 < nTime2)
      return (bDescending ? 1 : -1);
    else if (nTime1 > nTime2)
      return (bDescending ? -1 : 1);
    else
      return oSys.Call("Kernel32::lstrcmpiW", sName1, sName2);
  }
}

function CompareAttrCallback(nItem1, nItem2, bDescending)
{
  var sName1  = GetTextLV(hWndSort, nItem1, 0);
  var sName2  = GetTextLV(hWndSort, nItem2, 0);
  var sAttr1  = GetTextLV(hWndSort, nItem1, 3);
  var sAttr2  = GetTextLV(hWndSort, nItem2, 3);
  var bIsDir1 = (GetTextLV(hWndSort, nItem1, 1).substr(0, 1) == "<");
  var bIsDir2 = (GetTextLV(hWndSort, nItem2, 1).substr(0, 1) == "<");

  if ((sName1 == "..") || ((bIsDir1) && (! bIsDir2)))
    return -1;
  else if ((sName2 == "..") || ((! bIsDir1) && (bIsDir2)))
    return 1;
  else
  {
    if (sAttr1 < sAttr2)
      return (bDescending ? 1 : -1);
    else if (sAttr1 > sAttr2)
      return (bDescending ? -1 : 1);
    else
      return oSys.Call("Kernel32::lstrcmpiW", sName1, sName2);
  }
}

function GetItemCountLV(hWndLV)
{
  return AkelPad.SendMessage(hWndLV, 0x1004 /*LVM_GETITEMCOUNT*/, 0, 0);
}

function GetCurFocLV(hWndLV)
{
  return AkelPad.SendMessage(hWndLV, 0x100C /*LVM_GETNEXTITEM*/, -1, 0x0001 /*LVNI_FOCUSED*/);
}

function GetCurSelLV(hWndLV)
{
  return AkelPad.SendMessage(hWndLV, 0x100C /*LVM_GETNEXTITEM*/, -1, 0x0002 /*LVNI_SELECTED*/);
}

function SetCurSelLV(hWndLV, nItem)
{
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 12 /*state*/),     0x0003 /*LVIS_SELECTED|LVIS_FOCUSED*/, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 16 /*stateMask*/), 0x0003 /*LVIS_SELECTED|LVIS_FOCUSED*/, DT_DWORD);
  AkelPad.SendMessage(hWndLV, 0x102B /*LVM_SETITEMSTATE*/, nItem, lpLVITEM);
  AkelPad.SendMessage(hWndLV, 0x1013 /*LVM_ENSUREVISIBLE*/, nItem, false);
}

function GetTextLV(hWndLV, nItem, nSubItem)
{
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 8 /*iSubItem*/), nSubItem, DT_DWORD);
  AkelPad.SendMessage(hWndLV, 0x1073 /*LVM_GETITEMTEXTW*/, nItem, lpLVITEM);
  return AkelPad.MemRead(lpBuffer, _TSTR);
}

function InsertItemLV(hWndLV, nItem, aItems)
{
  var i;

  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 4), nItem, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 8),     0, DT_DWORD);
  AkelPad.MemCopy(lpBuffer, aItems[0], _TSTR);
  AkelPad.SendMessage(hWndLV, 0x104D /*LVM_INSERTITEMW*/, 0, lpLVITEM);

  for (i = 1; i < aItems.length; ++i)
  {
    AkelPad.MemCopy(_PtrAdd(lpLVITEM, 8), i, DT_DWORD);
    AkelPad.MemCopy(lpBuffer, aItems[i], _TSTR);
    AkelPad.SendMessage(hWndLV, 0x1074 /*LVM_SETITEMTEXTW*/, nItem, lpLVITEM);
  }
}

function RefreshPanel(nPan)
{
  var nStart = nPan;
  var nEnd   = nPan;
  var nSelPosFile;
  var nSelPosStr;
  var i;

  if (nPan == 2)
  {
    nStart = 0;
    nEnd   = 1;
  }

  for (i = nStart; i <= nEnd; ++i)
  {
    nSelPosFile = GetCurSelLV(aWnd[IDFILELV0 + i][HWND]);
    nSelPosStr  = GetCurSelLV(aWnd[IDSTREAMLV0 + i][HWND]);

    FillDriveList(i);
    GetCurFile(i);
    SetWndText(aWnd[IDDIRS0 + i][HWND], aCurDir[i][aCurDrive[i]].Path);
    FillFileList(i, aCurDir[i][aCurDrive[i]].File, nSelPosFile);
    FillStreamList(i, aCurDir[i][aCurDrive[i]].Stream, nSelPosStr);
    QuickView(i);
  }
}

function RefreshStreamList(nPan)
{
  GetCurFile(nPan);
  FillStreamList(nPan, aCurDir[nPan][aCurDrive[nPan]].Stream, GetCurSelLV(aWnd[IDSTREAMLV0 + nPan][HWND]));
  QuickView(nPan);
}

function ClonePanel(nPan1)
{
  var nPan0  = Number(! nPan1);
  var hWndF0 = aWnd[IDFILELV0 + nPan0][HWND];
  var hWndF1 = aWnd[IDFILELV0 + nPan1][HWND];
  var hWndS0 = aWnd[IDSTREAMLV0 + nPan0][HWND];
  var hWndS1 = aWnd[IDSTREAMLV0 + nPan1][HWND];
  var i;

  GetCurFile(nPan1);
  aHistory[nPan1][aCurHist[nPan1]][1] = aCurDir[nPan1][aCurDrive[nPan1]].File;
  aHistory[nPan1][aCurHist[nPan1]][2] = aCurDir[nPan1][aCurDrive[nPan1]].Stream;

  aCurFilter[nPan1] = aCurFilter[nPan0];
  aCurDrive[nPan1]  = aCurDrive[nPan0];
  aSort[nPan1]      = aSort[nPan0];
  aSort[nPan1 + 2]  = aSort[nPan0 + 2];

  SetSortInHeader(-1);

  if (! aCurDir[nPan1][aCurDrive[nPan1]])
    AddCurDir(nPan1, "");

  aCurDir[nPan1][aCurDrive[nPan1]].Path = aCurDir[nPan0][aCurDrive[nPan0]].Path;
  AddHistory(nPan1, aCurDir[nPan1][aCurDrive[nPan1]].Path);

  FillFilterList();
  FillDriveList(nPan1);
  SetWndText(aWnd[IDDIRS0 + nPan1][HWND], aCurDir[nPan1][aCurDrive[nPan1]].Path);

  AkelPad.SendMessage(hWndF1, 0x000B /*WM_SETREDRAW*/, false, 0);
  AkelPad.SendMessage(hWndS1, 0x000B /*WM_SETREDRAW*/, false, 0);
  AkelPad.SendMessage(hWndF1, 0x1009 /*LVM_DELETEALLITEMS*/, 0, 0);
  AkelPad.SendMessage(hWndS1, 0x1009 /*LVM_DELETEALLITEMS*/, 0, 0);

  for (i = 0; i < GetItemCountLV(hWndF0); ++i)
    InsertItemLV(hWndF1, i, [GetTextLV(hWndF0, i, 0), GetTextLV(hWndF0, i, 1), GetTextLV(hWndF0, i, 2), GetTextLV(hWndF0, i, 3), GetTextLV(hWndF0, i, 4)]);

  for (i = 0; i < GetItemCountLV(hWndS0); ++i)
    InsertItemLV(hWndS1, i, [GetTextLV(hWndS0, i, 0), GetTextLV(hWndS0, i, 1)]);

  SetCurSelLV(hWndF1, GetCurSelLV(hWndF0));
  SetCurSelLV(hWndS1, GetCurSelLV(hWndS0));
  AkelPad.SendMessage(hWndF1, 0x000B /*WM_SETREDRAW*/, true, 0);
  AkelPad.SendMessage(hWndS1, 0x000B /*WM_SETREDRAW*/, true, 0);
}

function SwapPanels()
{
  var oRect0 = {};
  var oRect1 = {};
  var sPath0;
  var sPath1;
  var vTmp;
  var i;

  nCurPan = Number(! nCurPan);

  if (bDualPan)
  {
    sPath0 = aCurDir[0][aCurDrive[0]].Path;
    sPath1 = aCurDir[1][aCurDrive[1]].Path;

    vTmp = aCurDrive[0];
    aCurDrive[0] = aCurDrive[1];
    aCurDrive[1] = vTmp;

    if (! aCurDir[0][aCurDrive[0]])
      AddCurDir(0, "");
    if (! aCurDir[1][aCurDrive[1]])
      AddCurDir(1, "");

    aCurDir[0][aCurDrive[0]].Path = sPath1;
    aCurDir[1][aCurDrive[1]].Path = sPath0;

    vTmp = aCurHist[0];
    aCurHist[0] = aCurHist[1];
    aCurHist[1] = vTmp;

    vTmp = aHistory[0];
    aHistory[0] = aHistory[1];
    aHistory[1] = vTmp;

    vTmp = aSort[0];
    aSort[0] = aSort[1];
    aSort[1] = vTmp;

    vTmp = aSort[2];
    aSort[2] = aSort[3];
    aSort[3] = vTmp;

    vTmp = aCurWnd[0];
    aCurWnd[0] = aCurWnd[1];
    aCurWnd[1] = vTmp;

    vTmp = aCurFilter[0];
    aCurFilter[0] = aCurFilter[1];
    aCurFilter[1] = vTmp;

    vTmp = hWndFilterEdit0;
    hWndFilterEdit0 = hWndFilterEdit1;
    hWndFilterEdit1 = vTmp;

    for (i = IDDRIVECB0; i <= IDQUICKVIEWS0; i += 2)
    {
      vTmp = aWnd[i][HWND];
      aWnd[i][HWND] = aWnd[i + 1][HWND];
      aWnd[i + 1][HWND] = vTmp;

      oSys.Call("User32::SetWindowLongW", aWnd[i    ][HWND], -12 /*GWL_ID*/, i);
      oSys.Call("User32::SetWindowLongW", aWnd[i + 1][HWND], -12 /*GWL_ID*/, i + 1);

      GetControlPos(hWndDlg, aWnd[i][HWND], oRect0);
      GetControlPos(hWndDlg, aWnd[i + 1][HWND], oRect1);

      oSys.Call("User32::MoveWindow", aWnd[i    ][HWND], oRect1.X, oRect1.Y, oRect1.W, oRect1.H, 1);
      oSys.Call("User32::MoveWindow", aWnd[i + 1][HWND], oRect0.X, oRect0.Y, oRect0.W, oRect0.H, 1);
    }
  }
  else
  {
    oSys.Call("User32::SetFocus", aWnd[IDFILELV0 + nCurPan + aCurWnd[nCurPan] * 2][HWND]);
    ShowControlsInPanel();
  }
}

function FillFilterList(sFilter)
{
  var i;

  for (i = aFilter.length - 1; i >= 0; --i)
  {
    if ((aFilter[i] == sFilter) || (aFilter[i] == "*.*"))
      aFilter.splice(i, 1);
  }

  if ((sFilter) && (sFilter != "*.*"))
    aFilter.push(sFilter);

  aFilter.sort();
  aFilter.unshift("*.*");

  if (aFilter.length > 25)
    aFilter.length = 25;

  AkelPad.SendMessage(aWnd[IDFILTERCB0][HWND], 0x014B /*CB_RESETCONTENT*/, 0, 0);
  AkelPad.SendMessage(aWnd[IDFILTERCB1][HWND], 0x014B /*CB_RESETCONTENT*/, 0, 0);

  for (i = 0; i < aFilter.length; ++i)
  {
    AkelPad.SendMessage(aWnd[IDFILTERCB0][HWND], 0x0143 /*CB_ADDSTRING*/, 0, aFilter[i]);
    AkelPad.SendMessage(aWnd[IDFILTERCB1][HWND], 0x0143 /*CB_ADDSTRING*/, 0, aFilter[i]);
  }

  SetWndText(aWnd[IDFILTERCB0][HWND], aCurFilter[0]);
  SetWndText(aWnd[IDFILTERCB1][HWND], aCurFilter[1]);
}

function DeleteFilterCB(hWndCB)
{
  var nPos = AkelPad.SendMessage(hWndCB, 0x0147 /*CB_GETCURSEL*/, 0, 0);

  if ((aFilter[nPos] != aCurFilter[0]) && (aFilter[nPos] != aCurFilter[1]))
  {
    aFilter.splice(nPos, 1);
    FillFilterList();

    if (nPos > aFilter.length - 1)
      nPos = aFilter.length - 1;

    AkelPad.SendMessage(hWndCB, 0x014E /*CB_SETCURSEL*/, nPos, 0);
    AkelPad.SendMessage(hWndCB, 0x014F /*CB_SHOWDROPDOWN*/, 1, 0);
  }
}

function SetCurFilter(nPan)
{
  oSys.Call("User32::GetWindowTextW", aWnd[IDFILTERCB0 + nPan][HWND], lpBuffer, nBufSize);

  if (aCurFilter[nPan] != AkelPad.MemRead(lpBuffer, _TSTR))
  {
    if (AkelPad.MemRead(lpBuffer, _TSTR))
      aCurFilter[nPan] = AkelPad.MemRead(lpBuffer, _TSTR);
    else
      aCurFilter[nPan] = "*.*";

    FillFilterList(aCurFilter[nPan]);
    RefreshPanel(nPan);
  }
}

function FillDriveList(nPan)
{
  var sLogDrives = oSys.Call("Kernel32::GetLogicalDrives", 0).toString(2);
  var sDir;
  var sDrive;
  var nPos;
  var i;

  AkelPad.SendMessage(aWnd[IDDRIVECB0 + nPan][HWND], 0x014B /*CB_RESETCONTENT*/, 0, 0);

  if ((! aCurDrive[nPan]) || (! IsDriveExists(aCurDrive[nPan])))
  {
    oSys.Call("Kernel32::GetCurrentDirectoryW", nBufSize / _TSIZE, lpBuffer);
    sDir = AkelPad.MemRead(lpBuffer, _TSTR);
    aCurDrive[nPan] = sDir.substr(0, 2);

    if (! aCurDir[nPan][aCurDrive[nPan]])
    {
      if (sDir.slice(-1) != "\\")
        sDir += "\\";

      AddCurDir(nPan, sDir);
    }
  }

  for (i = 0; i <= sLogDrives.length; ++i)
  {
    if (sLogDrives.charAt(sLogDrives.length - i - 1) == "1")
    {
      sDrive = String.fromCharCode("A".charCodeAt(0) + i) + ":";
      nPos   = AkelPad.SendMessage(aWnd[IDDRIVECB0 + nPan][HWND], 0x0143 /*CB_ADDSTRING*/, 0, sDrive);

      if (sDrive == aCurDrive[nPan])
      {
        AkelPad.SendMessage(aWnd[IDDRIVECB0 + nPan][HWND], 0x014E /*CB_SETCURSEL*/, nPos, 0);

        if ((! aCurDir[nPan][aCurDrive[nPan]]) || (! IsDirExists(aCurDir[nPan][aCurDrive[nPan]].Path)))
          AddCurDir(nPan, sDrive + "\\");
      }
    }
  }
}

function FillFileList(nPan, sSelFile, nSelPos, bCheckFilter)
{
  var bResult   = false;
  var hFindFile = oSys.Call("Kernel32::FindFirstFileW", aCurDir[nPan][aCurDrive[nPan]].Path + "*.*", lpBuffer);
  var aDirs     = [];
  var aFiles    = [];
  var lpLocalFileTime;
  var lpSysTime;
  var lpDateStr;
  var lpTimeStr;
  var sFile;
  var nSizeLo;
  var nSizeHi;
  var sSize;
  var aTime;
  var nAttr;
  var aTimeParentDir;
  var sAttrParentDir;
  var nPos;
  var sPattern;
  var rFilter;
  var i;

  AkelPad.SendMessage(aWnd[IDFILELV0 + nPan][HWND], 0x000B /*WM_SETREDRAW*/, false, 0);

  if (hFindFile != -1) //INVALID_HANDLE_VALUE
  {
    lpLocalFileTime = AkelPad.MemAlloc(8);  //FILETIME
    lpSysTime       = AkelPad.MemAlloc(16); //SYSTEMTIME
    lpDateStr       = AkelPad.MemAlloc(64 * _TSIZE);
    lpTimeStr       = AkelPad.MemAlloc(64 * _TSIZE);

    AkelPad.SendMessage(aWnd[IDFILELV0 + nPan][HWND], 0x1009 /*LVM_DELETEALLITEMS*/, 0, 0);

    do
    {
      nAttr = AkelPad.MemRead(lpBuffer, DT_DWORD);

      if (nAttr & 16 /*FILE_ATTRIBUTE_DIRECTORY*/)
      {
        sFile = AkelPad.MemRead(_PtrAdd(lpBuffer, 44 /*offsetof(WIN32_FIND_DATAW, cFileName)*/), _TSTR);
        sFile = sFile.substr(sFile.lastIndexOf("\\") + 1);

        if (sFile != ".")
        {
          if (sFile == "..")
          {
            aTimeParentDir = FileTimeToString(_PtrAdd(lpBuffer, 20), lpLocalFileTime, lpSysTime, lpDateStr, lpTimeStr);
            sAttrParentDir = AttrToString(nAttr);
          }
          else
          {
            if (nAttr & 1024 /*FILE_ATTRIBUTE_REPARSE_POINT*/)
              sSize = "<LNK>";
            else
              sSize = "<DIR>";

            aTime = FileTimeToString(_PtrAdd(lpBuffer, 20), lpLocalFileTime, lpSysTime, lpDateStr, lpTimeStr);
            aDirs.push([sFile, sSize, aTime[0], AttrToString(nAttr), aTime[1]]);
          }
        }
      }
    }
    while (oSys.Call("Kernel32::FindNextFileW", hFindFile, lpBuffer));

    oSys.Call("Kernel32::FindClose", hFindFile);

    if (aDirs.length)
      SortFiles(aDirs, nPan);

    if (aCurDir[nPan][aCurDrive[nPan]].Path.length > 3)
      aDirs.unshift(["..", "<DIR>", aTimeParentDir[0], sAttrParentDir, aTimeParentDir[1]]);

    //Check filter
    if (bCheckFilter && sSelFile && IsFileExists(aCurDir[nPan][aCurDrive[nPan]].Path + sSelFile))
    {
      sPattern = aCurFilter[nPan].replace(/[\\\/.^$+|()\[\]{}]/g, "\\$&").replace(/[?*]/g, ".$&");
      rFilter  = new RegExp(sPattern);
      if (! rFilter.test(sSelFile))
      {
        AkelPad.SendMessage(aWnd[IDFILTERCB0 + nPan][HWND], 0x014E /*CB_SETCURSEL*/, 0, 0);
        aCurFilter[nPan] = "*.*"
      }
    }

    hFindFile = oSys.Call("Kernel32::FindFirstFileW", aCurDir[nPan][aCurDrive[nPan]].Path + aCurFilter[nPan], lpBuffer);

    if (hFindFile != -1) //INVALID_HANDLE_VALUE
    {
      do
      {
        nAttr = AkelPad.MemRead(lpBuffer, DT_DWORD);

        if (! (nAttr & 16 /*FILE_ATTRIBUTE_DIRECTORY*/))
        {
          sFile = AkelPad.MemRead(_PtrAdd(lpBuffer, 44 /*offsetof(WIN32_FIND_DATAW, cFileName)*/), _TSTR);
          sFile = sFile.substr(sFile.lastIndexOf("\\") + 1);

          // http://mcdrummerman.wordpress.com/2010/07/13/win32_find_data-and-negative-file-sizes/
          nSizeHi = AkelPad.MemRead(_PtrAdd(lpBuffer, 28 /*offsetof(WIN32_FIND_DATAW, nFileSizeHigh)*/), DT_DWORD);
          nSizeLo = AkelPad.MemRead(_PtrAdd(lpBuffer, 32 /*offsetof(WIN32_FIND_DATAW, nFileSizeLow)*/), DT_DWORD);

          if (nSizeLo < 0)
            nSizeLo = nSizeLo + (0xFFFFFFFF + 1);

          aTime = FileTimeToString(_PtrAdd(lpBuffer, 20), lpLocalFileTime, lpSysTime, lpDateStr, lpTimeStr);
          aFiles.push([sFile, String(nSizeHi * (0xFFFFFFFF + 1) + nSizeLo), aTime[0], AttrToString(nAttr), aTime[1]]);
        }
      }
      while (oSys.Call("Kernel32::FindNextFileW", hFindFile, lpBuffer));

      oSys.Call("Kernel32::FindClose", hFindFile);
    }

    if (aFiles.length)
      SortFiles(aFiles, nPan);

    aFiles = aDirs.concat(aFiles);

    if (aFiles.length)
    {
      if (sSelFile)
        sSelFile = sSelFile.toUpperCase();

      for (i = 0; i < aFiles.length; ++i)
      {
        InsertItemLV(aWnd[IDFILELV0 + nPan][HWND], i, aFiles[i]);

        if (aFiles[i][0].toUpperCase() == sSelFile)
          SetCurSelLV(aWnd[IDFILELV0 + nPan][HWND], i);
      }
    }
    else
      InsertItemLV(aWnd[IDFILELV0 + nPan][HWND], 0, [sTxtNoFiles, "", "", "", ""]);

    if (GetCurSelLV(aWnd[IDFILELV0 + nPan][HWND]) < 0)
    {
      if (! nSelPos)
        nSelPos = 0;
      else if (nSelPos > aFiles.length - 1)
        nSelPos = aFiles.length - 1;

      SetCurSelLV(aWnd[IDFILELV0 + nPan][HWND], nSelPos);
    }

    AkelPad.MemFree(lpLocalFileTime);
    AkelPad.MemFree(lpSysTime);
    AkelPad.MemFree(lpDateStr);
    AkelPad.MemFree(lpTimeStr);
    bResult = true;
  }

  else if (aCurDir[nPan][aCurDrive[nPan]].Path.length == 3)
  {
    AkelPad.SendMessage(aWnd[IDFILELV0 + nPan][HWND], 0x1009 /*LVM_DELETEALLITEMS*/, 0, 0);
    InsertItemLV(aWnd[IDFILELV0 + nPan][HWND], 0, [sTxtNoFiles, "", "", "", ""]);
    SetCurSelLV(aWnd[IDFILELV0 + nPan][HWND], 0);
    bResult = true;
  }

  AkelPad.SendMessage(aWnd[IDFILELV0 + nPan][HWND], 0x000B /*WM_SETREDRAW*/, true, 0);
  return bResult;
}

function FileTimeToString(lpFileTime, lpLocalFileTime, lpSysTime, lpDateStr, lpTimeStr)
{
  oSys.Call("Kernel32::FileTimeToLocalFileTime", lpFileTime, lpLocalFileTime);
  oSys.Call("Kernel32::FileTimeToSystemTime", lpLocalFileTime, lpSysTime);

  oSys.Call("Kernel32::GetDateFormatW",
            0x400, //LOCALE_USER_DEFAULT
            0x1,   //DATE_SHORTDATE
            lpSysTime,
            0,
            lpDateStr,
            64);
  oSys.Call("Kernel32::GetTimeFormatW",
            0x400, //LOCALE_USER_DEFAULT
            0xA,   //TIME_FORCE24HOURFORMAT|TIME_NOSECONDS
            lpSysTime,
            0,
            lpTimeStr,
            64);

  return [AkelPad.MemRead(lpDateStr, _TSTR) + " " + AkelPad.MemRead(lpTimeStr, _TSTR),
          (AkelPad.MemRead(lpLocalFileTime, DT_DWORD) +
          AkelPad.MemRead(_PtrAdd(lpLocalFileTime, 4), DT_DWORD) * (0xFFFFFFFF + 1)).toString(16)];
}

function AttrToString(nAttr)
{
  var  sAttr = "";

  if (nAttr & 32 /*FILE_ATTRIBUTE_ARCHIVE*/)
    sAttr += "A";
  if (nAttr & 2 /*FILE_ATTRIBUTE_HIDDEN*/)
    sAttr += "H";
  if (nAttr & 1 /*FILE_ATTRIBUTE_READONLY*/)
    sAttr += "R";
  if (nAttr & 4 /*FILE_ATTRIBUTE_SYSTEM*/)
    sAttr += "S";

  return sAttr;
}

function SortFiles(aFiles, nPan)
{
  var bDescending = aSort[nPan][1];
  var bIsDir      = (aFiles[0][1].substr(0, 1) == "<");

  if ((aSort[nPan][0] == 0) || ((aSort[nPan][0] == 1) && bIsDir))
    aFiles.sort(
      function(aA, aB)
      {
        return (bDescending ? -1 : 1) * oSys.Call("Kernel32::lstrcmpiW", aA[0], aB[0]);
      });
  else if (aSort[nPan][0] == 1)
    aFiles.sort(
      function(aA, aB)
      {
        if (Number(aA[1]) < Number(aB[1]))
          return (bDescending ? 1 : -1);
        else if (Number(aA[1]) > Number(aB[1]))
          return (bDescending ? -1 : 1);
        else
          return oSys.Call("Kernel32::lstrcmpiW", aA[0], aB[0]);
      });
  else if (aSort[nPan][0] == 2)
    aFiles.sort(
      function(aA, aB)
      {
        if (parseInt(aA[4], 16) < parseInt(aB[4], 16))
          return (bDescending ? 1 : -1);
        else if (parseInt(aA[4], 16) > parseInt(aB[4], 16))
          return (bDescending ? -1 : 1);
        else
          return oSys.Call("Kernel32::lstrcmpiW", aA[0], aB[0]);
      });
  else
    aFiles.sort(
      function(aA, aB)
      {
        if (aA[3] < aB[3])
          return (bDescending ? 1 : -1);
        else if (aA[3] > aB[3])
          return (bDescending ? -1 : 1);
        else
          return oSys.Call("Kernel32::lstrcmpiW", aA[0], aB[0]);
      });
}

function FillStreamList(nPan, sSelStream, nSelPos)
{
  var aStreams = [];
  var nPos;
  var i;

  GetCurFile(nPan);
  AkelPad.SendMessage(aWnd[IDSTREAMLV0 + nPan][HWND], 0x000B /*WM_SETREDRAW*/, false, 0);
  AkelPad.SendMessage(aWnd[IDSTREAMLV0 + nPan][HWND], 0x1009 /*LVM_DELETEALLITEMS*/, 0, 0);

  if (IsSupportStreams(aCurDrive[nPan]))
  {
    if (aCurDir[nPan][aCurDrive[nPan]].File && (aCurDir[nPan][aCurDrive[nPan]].File != ".."))
    {
      aStreams = EnumStreams(aCurDir[nPan][aCurDrive[nPan]].Path + aCurDir[nPan][aCurDrive[nPan]].File);

      if (aStreams.length)
      {
        if (! aStreams[0][0])
          aStreams[0][0] = sTxtMainStream;

        SortStreams(aStreams, nPan);
      }
    }
  }
  else
    aStreams[0] = [sTxtNoSupport, ""];

  if (! aStreams.length)
    aStreams[0] = [sTxtNoStreams, ""];

  if (sSelStream)
    sSelStream = sSelStream.toUpperCase();
  else
    sSelStream = sTxtMainStream.toUpperCase();

  for (i = 0; i < aStreams.length; ++i)
  {
    InsertItemLV(aWnd[IDSTREAMLV0 + nPan][HWND], i, [aStreams[i][0], aStreams[i][1].toString(), 0]);

    if (aStreams[i][0].toUpperCase() == sSelStream)
      SetCurSelLV(aWnd[IDSTREAMLV0 + nPan][HWND], i);
  }

  if (GetCurSelLV(aWnd[IDSTREAMLV0 + nPan][HWND]) < 0)
  {
    if (! nSelPos)
      nSelPos = 0;
    else if (nSelPos > aStreams.length - 1)
      nSelPos = aStreams.length - 1;

    SetCurSelLV(aWnd[IDSTREAMLV0 + nPan][HWND], nSelPos);
  }

  AkelPad.SendMessage(aWnd[IDSTREAMLV0 + nPan][HWND], 0x000B /*WM_SETREDRAW*/, true, 0);
}

function SortStreams(aStreams, nPan)
{
  var bDescending = aSort[nPan + 2][1];

  if (aSort[nPan + 2][0] == 0)
    aStreams.sort(
      function(aA, aB)
      {
        if (aA[0] == sTxtMainStream)
          return (bDescending ? 1 : -1);
        else if (aB[0] == sTxtMainStream)
          return (bDescending ? -1 : 1);
        else
          return (bDescending ? -1 : 1) * oSys.Call("Kernel32::lstrcmpiW", aA[0], aB[0]);
      });
  else
    aStreams.sort(
      function(aA, aB)
      {
        if (aA[1] < aB[1])
          return (bDescending ? 1 : -1);
        else if (aA[1] > aB[1])
          return (bDescending ? -1 : 1);
        else
        {
          if (aA[0] == sTxtMainStream)
            return -1;
          else if (aB[0] == sTxtMainStream)
            return 1;
          return oSys.Call("Kernel32::lstrcmpiW", aA[0], aB[0]);
        }
      });
}

function QuickView(nPan)
{
  if (bQuickView)
  {
    var sText = "";

    GetCurFile(nPan);

    if (aCurDir[nPan][aCurDrive[nPan]].File)
    {
      var sFile        = aCurDir[nPan][aCurDrive[nPan]].Path + aCurDir[nPan][aCurDrive[nPan]].File;
      var lpDetectFile = AkelPad.MemAlloc(_X64 ? 24 : 20); //sizeof(DETECTFILEW)
      var nDetectFile;

      if ((aCurWnd[nPan] == 1) && aCurDir[nPan][aCurDrive[nPan]].Stream)
        sFile += ":" + aCurDir[nPan][aCurDrive[nPan]].Stream;

      AkelPad.MemCopy(lpBuffer, sFile, 1 /*DT_UNICODE*/);
      AkelPad.MemCopy(lpDetectFile, lpBuffer, DT_QWORD); //*pFile
      AkelPad.MemCopy(_PtrAdd(lpDetectFile, _X64 ?  8 : 4), 1024, DT_DWORD); //dwBytesToCheck
      AkelPad.MemCopy(_PtrAdd(lpDetectFile, _X64 ? 12 : 8), 0x1D, DT_DWORD); //dwFlags=ADT_NOMESSAGES|ADT_DETECT_BOM|ADT_DETECT_CODEPAGE|ADT_BINARY_ERROR

      nDetectFile = AkelPad.SendMessage(AkelPad.GetMainWnd(), 1177 /*AKD_DETECTFILEW*/, 0, lpDetectFile);

      if (nDetectFile == 0 /*EDT_SUCCESS*/)
        sText = AkelPad.ReadFile(sFile, 0, AkelPad.MemRead(_PtrAdd(lpDetectFile, _X64 ? 16 : 12), DT_DWORD) /*nCodePage*/, AkelPad.MemRead(_PtrAdd(lpDetectFile, _X64 ? 20 : 16), DT_DWORD) /*bBOM*/, 2048);
      else if (nDetectFile == -4 /*EDT_BINARY*/)
        sText = AkelPad.ReadFile(sFile, 0, 0, 0, 2048).replace(/\0/g, "\x01");

      AkelPad.MemFree(lpDetectFile);
    }

    SetWndText(aWnd[IDQUICKVIEWS0 + nPan][HWND], sText);
  }
}

function ChangeDrive(nPan)
{
  var sDrive = GetDriveName(nPan);

  GetCurFile(nPan);

  if (IsDriveExists(sDrive))
  {
    aHistory[nPan][aCurHist[nPan]][1] = aCurDir[nPan][aCurDrive[nPan]].File;
    aHistory[nPan][aCurHist[nPan]][2] = aCurDir[nPan][aCurDrive[nPan]].Stream;

    aCurDrive[nPan] = sDrive;

    if ((! aCurDir[nPan][aCurDrive[nPan]]) || (! IsDirExists(aCurDir[nPan][aCurDrive[nPan]].Path)))
      AddCurDir(nPan, sDrive + "\\");

    SetWndText(aWnd[IDDIRS0 + nPan][HWND], aCurDir[nPan][aCurDrive[nPan]].Path);
    if (! FillFileList(nPan, aCurDir[nPan][aCurDrive[nPan]].File))
    {
      AddCurDir(nPan, sDrive + "\\");
      SetWndText(aWnd[IDDIRS0 + nPan][HWND], aCurDir[nPan][aCurDrive[nPan]].Path);
      FillFileList(nPan);
    }

    AddHistory(nPan, aCurDir[nPan][aCurDrive[nPan]].Path);
    return true;
  }
  else
  {
    MessageNoDrive(nPan, sDrive);
    return false;
  }
}

function GetDriveName(nPan)
{
  AkelPad.SendMessage(aWnd[IDDRIVECB0 + nPan][HWND], 0x0148 /*CB_GETLBTEXT*/, AkelPad.SendMessage(aWnd[IDDRIVECB0 + nPan][HWND], 0x0147 /*CB_GETCURSEL*/, 0, 0), lpBuffer);

  return AkelPad.MemRead(lpBuffer, _TSTR);
}

function SelCurDriveCB(nPan)
{
  var i;

  for (i = 0; i < AkelPad.SendMessage(aWnd[IDDRIVECB0 + nPan][HWND], 0x0146 /*CB_GETCOUNT*/, 0, 0); ++i)
  {
    AkelPad.SendMessage(aWnd[IDDRIVECB0 + nPan][HWND], 0x0148 /*CB_GETLBTEXT*/, i, lpBuffer);

    if (AkelPad.MemRead(lpBuffer, _TSTR) == aCurDrive[nPan])
    {
      AkelPad.SendMessage(aWnd[IDDRIVECB0 + nPan][HWND], 0x014E /*CB_SETCURSEL*/, i, 0);
      break;
    }
  }
}

function AddCurDir(nPan, sDir)
{
  aCurDir[nPan][aCurDrive[nPan]] = {Path : sDir, File : "", Stream : ""};
}

function GetCurFile(nPan)
{
  var nPos = GetCurSelLV(aWnd[IDFILELV0 + nPan][HWND]);

  if ((nPos > -1) && GetTextLV(aWnd[IDFILELV0 + nPan][HWND], nPos, 1))
    aCurDir[nPan][aCurDrive[nPan]].File = GetTextLV(aWnd[IDFILELV0 + nPan][HWND], nPos, 0);
  else
    aCurDir[nPan][aCurDrive[nPan]].File = "";

  nPos = GetCurSelLV(aWnd[IDSTREAMLV0 + nPan][HWND]);
  if ((nPos > -1) && GetTextLV(aWnd[IDSTREAMLV0 + nPan][HWND], nPos, 1) &&
      (GetTextLV(aWnd[IDSTREAMLV0 + nPan][HWND], nPos, 0) != sTxtMainStream))
    aCurDir[nPan][aCurDrive[nPan]].Stream = GetTextLV(aWnd[IDSTREAMLV0 + nPan][HWND], nPos, 0);
  else
    aCurDir[nPan][aCurDrive[nPan]].Stream = "";
}

function CurFileIsDir(nPan)
{
  var sType = GetTextLV(aWnd[IDFILELV0 + nPan][HWND], GetCurSelLV(aWnd[IDFILELV0 + nPan][HWND]), 1);

  return ((sType == "<DIR>") || (sType == "<LNK>"));
}

function ChangeDir(nPan, sPath)
{
  var sOldDrive = aCurDrive[nPan];
  var sOldPath  = aCurDir[nPan][aCurDrive[nPan]].Path;

  GetCurFile(nPan);

  aHistory[nPan][aCurHist[nPan]][1] = aCurDir[nPan][aCurDrive[nPan]].File;
  aHistory[nPan][aCurHist[nPan]][2] = aCurDir[nPan][aCurDrive[nPan]].Stream;

  sPath = ExpandFileName(sPath);
  aCurDrive[nPan] = sPath.substr(0, 2);
  SelCurDriveCB(nPan);

  if (aCurDir[nPan][aCurDrive[nPan]])
    aCurDir[nPan][aCurDrive[nPan]].Path = sPath;
  else
    AddCurDir(nPan, sPath);

  SetWndText(aWnd[IDDIRS0 + nPan][HWND], sPath);

  if (FillFileList(nPan, aCurDir[nPan][aCurDrive[nPan]].File))
    AddHistory(nPan, sPath);
  else
  {
    aCurDrive[nPan] = sOldDrive;
    SelCurDriveCB(nPan);
    aCurDir[nPan][aCurDrive[nPan]].Path = sOldPath;
    SetWndText(aWnd[IDDIRS0 + nPan][HWND], sOldPath);
    WarningBox(hWndDlg, sPath + "\n\n" + sTxtNoDirAcc, sScriptName);
  }
}

function ExpandFileName(sFile)
{
  sFile = sFile.replace(/%a\\/g, AkelPad.GetAkelDir() + "\\");
  sFile = sFile.replace(/%.+?%/g, ExpandEnvironmentString);

  if (oSys.Call("Kernel32::GetFullPathNameW", sFile, nBufSize / 2, lpBuffer, 0))
    sFile = AkelPad.MemRead(lpBuffer, _TSTR);

  return sFile;
}

function ExpandEnvironmentString(sEnvironmentStr)
{
  if (oSys.Call("Kernel32::ExpandEnvironmentStringsW", sEnvironmentStr, lpBuffer, nBufSize / 2))
    sEnvironmentStr = AkelPad.MemRead(lpBuffer, _TSTR);

  return sEnvironmentStr;
}

function ChangeDirFromHistory(nPan, nInd, nShift)
{
  var sOldDrive = aCurDrive[nPan];
  var sOldPath  = aCurDir[nPan][aCurDrive[nPan]].Path;
  var sPath;

  //undo/redo
  if (nShift)
    nInd = aCurHist[nPan] + nShift;

  GetCurFile(nPan);

  aHistory[nPan][aCurHist[nPan]][1] = aCurDir[nPan][aCurDrive[nPan]].File;
  aHistory[nPan][aCurHist[nPan]][2] = aCurDir[nPan][aCurDrive[nPan]].Stream;

  while (true)
  {
    if (nShift)
    {
      if ((nInd < 0) || (nInd >= aHistory[nPan].length))
        return;

      while (! IsDirExists(aHistory[nPan][nInd][0]))
      {
        nInd += nShift;
        if ((nInd < 0) || (nInd >= aHistory[nPan].length))
          return;
      }
    }

    sPath = aHistory[nPan][nInd][0];
    aCurDrive[nPan] = sPath.substr(0, 2);
    SelCurDriveCB(nPan);

    if (aCurDir[nPan][aCurDrive[nPan]])
      aCurDir[nPan][aCurDrive[nPan]].Path = sPath;
    else
      AddCurDir(nPan, sPath);

    aCurDir[nPan][aCurDrive[nPan]].File   = aHistory[nPan][nInd][1];
    aCurDir[nPan][aCurDrive[nPan]].Stream = aHistory[nPan][nInd][2];

    SetWndText(aWnd[IDDIRS0 + nPan][HWND], sPath);

    if (FillFileList(nPan, aCurDir[nPan][aCurDrive[nPan]].File))
    {
      aCurHist[nPan] = nInd;
      break;
    }
    else
    {
      aCurDrive[nPan] = sOldDrive;
      SelCurDriveCB(nPan);
      aCurDir[nPan][aCurDrive[nPan]].Path = sOldPath;
      SetWndText(aWnd[IDDIRS0 + nPan][HWND], sOldPath);

      if (nShift)
        nInd += nShift;
      else
      {
        WarningBox(hWndDlg, sPath + "\n\n" + sTxtNoDirAcc, sScriptName);
        break;
      }
    }
  }
}

function Open(nPan, nAction)
{
  var sOldPath = aCurDir[nPan][aCurDrive[nPan]].Path;
  var sSelFile;

  if (! OpenAvailable(nPan, nAction))
    return;

  if (! IsDriveExists(aCurDrive[nPan]))
  {
    MessageNoDrive(nPan, aCurDrive[nPan]);
    return;
  }

  if ((nAction == 0) && (! CurFileIsDir(nPan)))
  {
    if (IsFileExists(aCurDir[nPan][aCurDrive[nPan]].Path + aCurDir[nPan][aCurDrive[nPan]].File))
      AkelPad.Exec("rundll32.exe shell32, ShellExec_RunDLL " + aCurDir[nPan][aCurDrive[nPan]].Path + aCurDir[nPan][aCurDrive[nPan]].File);
    else
      MessageNoFile(nPan);
  }

  else
  {
    aHistory[nPan][aCurHist[nPan]][1] = aCurDir[nPan][aCurDrive[nPan]].File;
    aHistory[nPan][aCurHist[nPan]][2] = aCurDir[nPan][aCurDrive[nPan]].Stream;

    //parent dir
    if (((nAction == 0) && (aCurDir[nPan][aCurDrive[nPan]].File == "..")) ||
        ((nAction == -1)))
    {
      aCurDir[nPan][aCurDrive[nPan]].Path = aCurDir[nPan][aCurDrive[nPan]].Path.slice(0, -1);
      sSelFile = aCurDir[nPan][aCurDrive[nPan]].Path.substr(aCurDir[nPan][aCurDrive[nPan]].Path.lastIndexOf("\\") + 1);
      aCurDir[nPan][aCurDrive[nPan]].Path = aCurDir[nPan][aCurDrive[nPan]].Path.substr(0, aCurDir[nPan][aCurDrive[nPan]].Path.lastIndexOf("\\") + 1);
    }
    //sub dir
    else if (nAction >= 0)
    {
      aCurDir[nPan][aCurDrive[nPan]].Path = aCurDir[nPan][aCurDrive[nPan]].Path + aCurDir[nPan][aCurDrive[nPan]].File + "\\";
      sSelFile = "..";
    }
    //main dir
    else
    {
      sSelFile = aCurDir[nPan][aCurDrive[nPan]].Path.substr(3);
      sSelFile = sSelFile.substr(0, sSelFile.indexOf("\\"));
      aCurDir[nPan][aCurDrive[nPan]].Path = aCurDrive[nPan] + "\\";
    }

    if (! IsDirExists(aCurDir[nPan][aCurDrive[nPan]].Path))
    {
      MessageNoFile(nPan, 1, 1);
      return;
    }

    SetWndText(aWnd[IDDIRS0 + nPan][HWND], aCurDir[nPan][aCurDrive[nPan]].Path);

    if (FillFileList(nPan, sSelFile))
      AddHistory(nPan, aCurDir[nPan][aCurDrive[nPan]].Path);
    else
    {
      aCurDir[nPan][aCurDrive[nPan]].Path = sOldPath;
      SetWndText(aWnd[IDDIRS0 + nPan][HWND], sOldPath);
      WarningBox(hWndDlg, aCurDir[nPan][aCurDrive[nPan]].Path + "\n\n" + sTxtNoDirAcc, sScriptName);
    }
  }
}

function OpenAvailable(nPan, nAction)
{
  GetCurFile(nPan);

  return aCurDir[nPan][aCurDrive[nPan]].File &&
         (((nAction == 0) && (aCurWnd[nPan] == 0)) ||
          ((nAction < 0) && (aCurDir[nPan][aCurDrive[nPan]].Path.length > 3)) ||
          ((nAction == 1) &&  CurFileIsDir(nPan) && (aCurDir[nPan][aCurDrive[nPan]].File != "..")));
}

Last edited by KDJ on Wed Jan 07, 2015 8:08 pm, edited 19 times in total.
Post Reply