Scripts discussion (1)

Discuss and announce AkelPad plugins
Locked
  • Author
  • Message
Offline
Posts: 3234
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

Конечно изменилось, - переменной-то нет, значит память не занимается ))
Делается для того, чтобы понять:
- файл существует или нет;
- есть в файле что-то или нет.
ReadFile все эти проверки делает сам.
Если я буду создавать объект fso, а затем File, чтобы проверить его объём, то выйдет шило на мыло. + (вернее минус) лишние строки кода.


Вопрос по скрипту GetOffset.js.
В чём смысл строки

Code: Select all

nCaretPos = GetOffset(hWndEdit, 5 /*AEGI_CARETCHAR*/, -1);
если nCaretPos возвращает то же самое, что и AkelPad.GetSelStart()?
Last edited by VladSh on Thu Jul 28, 2011 9:23 am, edited 3 times in total.

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

Post by FeyFre »

VladSh, насчет AkelPad.ReadFile
1. Сначала выполняется определение кодировки, для этого читается кусочек файла(тратим время на файловый I/O).
2. Потом выполняется полное чтение файла в память, при этом выделяется память под содержимое(сколько - зависит от кодировки, время на файловый I/O)
3. Потом заносится текст в скрипт: для этого выполняется выделение памяти опять, и копирование туда ранее прочитанного текста из п.2
4. Потом освобождаем выделенную память в п.2
5. Потом выполняется возврат из функции в скрипт, с преобразованием COM-прелставления строки в JScript/VBScript(освобождение памяти из п.3 и создание памяти под строчный объект, который создается несмотря на то что никто на него явно не держит ссылки - условный оператор держит)
6. Потом выполняется вычисление условного выражения - проверяется кол-во букв в строке.
7. И вот аж сейчас освобождается память из п.5

Самим содержимым памяти мы никогда не пользуемся, но как видите мы его читаем(время тратим, почитайте так с дискеты) и дважды копируем(одновременно дважды полностью выделяем под него память), да и ещё свопинг от этого страдает(но это уже на любителя). Не лучше ли напрямую спросить ФС о таком то файле, без лишних телодвижений? Будет и быстрее и меньше памяти скушаем.

Offline
Site Admin
Posts: 6403
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Получение размера файла двумя способами:

Code: Select all

var oSys=AkelPad.SystemFunction();

WScript.Echo("API:" + GetFileSizeAPI("c:\\NTDETECT.COM") + "\nWSH:" + GetFileSizeWSH("c:\\NTDETECT.COM"));

function GetFileSizeAPI(pFile)
{
  var lpFindData;
  var hFind;
  var nSize=-1;

  if (lpFindData=AkelPad.MemAlloc(592 /*sizeof(WIN32_FIND_DATAW)*/))
  {
    if ((hFind=oSys.Call("kernel32::FindFirstFile" + _TCHAR, pFile, lpFindData)) != -1 /*INVALID_HANDLE_VALUE*/)
    {
      var dwAttributes=AkelPad.MemRead(lpFindData /*offsetof(WIN32_FIND_DATAW, dwAttributes)*/, 3 /*DT_DWORD*/);
  
      if (!(dwAttributes & 0x10 /*FILE_ATTRIBUTE_DIRECTORY*/))
      {
        var nFileSizeHigh=AkelPad.MemRead(lpFindData + 28 /*offsetof(WIN32_FIND_DATAW, nFileSizeHigh)*/, 3 /*DT_DWORD*/);
        var nFileSizeLow=AkelPad.MemRead(lpFindData + 32 /*offsetof(WIN32_FIND_DATAW, nFileSizeLow)*/, 3 /*DT_DWORD*/);
  
        nSize=(nFileSizeHigh * (0xFFFFFFFF + 1)) + nFileSizeLow;
      }
      oSys.Call("kernel32::FindClose", hFind);
    }
    AkelPad.MemFree(lpFindData);
  }
  return nSize;
}

function GetFileSizeWSH(pFile)
{
   var fso=new ActiveXObject("Scripting.FileSystemObject");
   var oFile;

   if (oFile = fso.GetFile(pFile))
     return oFile.size;
   return -1;
}

Offline
Posts: 876
Joined: Tue Jul 24, 2007 8:54 am

Post by Fr0sT »

nSize=(nFileSizeHigh * (0xFFFFFFFF + 1)) + nFileSizeLow;
А nFileSizeHigh << 8 не сработает?

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

Post by FeyFre »

Fr0sT
Нужно умножить на 2^32 а не на 2^8. Наверное не сработает, раз Инструктор так показал(наверное уже пробовал).

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

Post by VladSh »

FeyFre, Instructor
Спасибо!

И всё-таки вопрос: зачем нужна строка

Code: Select all

nCaretPos = GetOffset(hWndEdit, 5 /*AEGI_CARETCHAR*/, -1);
если это значение можно взять из GetSelStart?

Offline
Site Admin
Posts: 6403
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

FeyFre wrote:...(наверное уже пробовал).
Просто взял код со страницы MSDN :)
http://msdn.microsoft.com/en-us/library ... s.85).aspx
VladSh wrote:И всё-таки вопрос: зачем нужна строка

Code: Select all

nCaretPos = GetOffset(hWndEdit, 5 /*AEGI_CARETCHAR*/, -1);
если это значение можно взять из GetSelStart?
Например делать выделение мы можем как с конца в начало (тогда GetSelStart будет совпадать), так и с начала в конец (тогда GetSelEnd будет совпадать).

Offline
Posts: 876
Joined: Tue Jul 24, 2007 8:54 am

Post by Fr0sT »

FeyFre
ага, напутал с разрядами. Но принцип ведь такой же, да и логичнее выглядит. Если только в JS не возникнет траблы с целочисленными типами

Offline
Posts: 124
Joined: Tue Jun 03, 2008 10:32 pm

Post by Xephon »

В последнем SearchReplace.js высота диалогового окна не меняется, вне зависимости от того, какое число стоит в строке "ScaleY(200) + sizeNonClient.cy, //nHeight". На 120 dpi диалог получается обрезанным снизу.

Offline
Site Admin
Posts: 6403
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Xephon
Исправлено. Будет доступно после релиза.

Offline
Posts: 124
Joined: Tue Jun 03, 2008 10:32 pm

Post by Xephon »

Спасибо. Еще пара пожеланий по SearchReplace.js:

- Текст поиска и замены сохраняется с использованием буфера в 256 байт. Иногда такого размера бывает недостаточно. Хотелось бы, чтобы длина текста определялась сначала через WM_GETTEXTLENGTH и память под буфер выделялась динамически. Или, хотя бы, чтобы в первых строчках файла появилась переменная, отвечающая за размер буфера.

- Из-за "AkelPad.GetSelText(2 /*\n*/);" регулярное выражение ".+" находит соответствие только до конца строки. Писать каждый раз "(.|\n)+" весьма неудобно. Было бы неплохо сделать опцию, определяющую аргумент GetSelText. Либо просто заменить везде "AkelPad.GetSelText(2 /*\n*/);" на "AkelPad.GetSelText();".

Offline
Site Admin
Posts: 6403
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Xephon wrote:Хотелось бы, чтобы длина текста определялась сначала через WM_GETTEXTLENGTH и память под буфер выделялась динамически.
Реализовано.
- Из-за "AkelPad.GetSelText(2 /*\n*/);" регулярное выражение ".+" находит соответствие только до конца строки. Писать каждый раз "(.|\n)+" весьма неудобно.
MSDN wrote:. Matches any single character except the newline character \n.
http://msdn.microsoft.com/en-us/library ... s.85).aspx

Offline
Posts: 1873
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Xephon wrote:Писать каждый раз "(.|\n)+" ...
Еще можно [\s\S] писать.

Offline
Posts: 124
Joined: Tue Jun 03, 2008 10:32 pm

Post by Xephon »

Instructor, спасибо, я знаю, что "." не должна соответствовать "\n" и не утверждаю, что это ошибка в скрипте. Я говорю лишь о том, что было бы удобно исключить символ "\n" из текста, возвращаемого GetSelText, т.к. ".+" банально гораздо короче, чем "(.|\n)+" или чем предложенный Infocatcher-ом "[\s\S]+". А т.к. кому-то может быть удобно существующее поведение, я предложил сделать опцию, определяющую аргумент GetSelText, чтобы после каждого обновления не искать нужные строчки в файле и не исправлять их вручную.

Offline
Site Admin
Posts: 6403
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Xephon
Опцию конечно можно, но многострочные поиск/замена не будут работать.
Locked