Page 93 of 97

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


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

Code: Select all

nCaretPos = GetOffset(hWndEdit, 5 /*AEGI_CARETCHAR*/, -1);
если nCaretPos возвращает то же самое, что и AkelPad.GetSelStart()?

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

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

Posted: Tue Jul 26, 2011 11:28 pm
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;
}

Posted: Wed Jul 27, 2011 7:11 am
by Fr0sT
nSize=(nFileSizeHigh * (0xFFFFFFFF + 1)) + nFileSizeLow;
А nFileSizeHigh << 8 не сработает?

Posted: Wed Jul 27, 2011 7:47 pm
by FeyFre
Fr0sT
Нужно умножить на 2^32 а не на 2^8. Наверное не сработает, раз Инструктор так показал(наверное уже пробовал).

Posted: Thu Jul 28, 2011 9:24 am
by VladSh
FeyFre, Instructor
Спасибо!

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

Code: Select all

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

Posted: Thu Jul 28, 2011 2:55 pm
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 будет совпадать).

Posted: Sat Jul 30, 2011 7:19 pm
by Fr0sT
FeyFre
ага, напутал с разрядами. Но принцип ведь такой же, да и логичнее выглядит. Если только в JS не возникнет траблы с целочисленными типами

Posted: Sat Jul 30, 2011 10:47 pm
by Xephon
В последнем SearchReplace.js высота диалогового окна не меняется, вне зависимости от того, какое число стоит в строке "ScaleY(200) + sizeNonClient.cy, //nHeight". На 120 dpi диалог получается обрезанным снизу.

Posted: Sun Jul 31, 2011 3:50 am
by Instructor
Xephon
Исправлено. Будет доступно после релиза.

Posted: Sun Jul 31, 2011 9:04 am
by Xephon
Спасибо. Еще пара пожеланий по SearchReplace.js:

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

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

Posted: Sun Jul 31, 2011 3:34 pm
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

Posted: Sun Jul 31, 2011 3:52 pm
by Infocatcher
Xephon wrote:Писать каждый раз "(.|\n)+" ...
Еще можно [\s\S] писать.

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

Posted: Mon Aug 01, 2011 6:15 am
by Instructor
Xephon
Опцию конечно можно, но многострочные поиск/замена не будут работать.