в процедуры
Код:
procedure OnConnect(WithClient: Boolean);
procedure OnDisconnect(WithClient: Boolean);
передается всегда WithClient = False. Проверьте скриптом.
причем, основное тело скрипта выполняется в контексте основного потока (реализовано с помощью SendMessage), а Onсonnect и OnDisconnect выполняются в контексте сетевых потоков.
Куча лишних критических секций. Для потокобезопасности в данном случае достаточно не
обращаться к VCL-контролам не из мейн нити, также продублировать все чекбоксы и прочие настройки глобальными переменными. Это важный момент - большая часть критикалов пакетхака именно из-за этого.
Не понятно почему автор не использует динамические массивы для Scripts, и не полностью их поддерживает для Thread (жесткое количество соединений). Это глупо...
Улыбнуло то, что при включенном сохранении пакетов каждый из них читает инфу о себе из ини файла. ИМХО верней было бы сделать один раз сделать массив при запуске проги и сделать кнопку "Перечитать из ини", как это было сделано в хлапексе. Производительность на лицо.
Для меня остается тайной, почему используется TTime вместо TDateTime, если уж на то пошло...
Также не понимаю смысл JVCL, все вещи которые с помощью них реализованы можно сделать RichEdit'ом и fsSyntaxMemo (которая так или иначе все-равно цепляется к проекту) и не тащить за собой лишние 400 кб.
Да, кстати, и прекрати юзать WM_USER+77 и WM_USER+45, для приложений создана специально зона WM_APP и выше.
Чтобы длл не ошибалась в выборе окна, которому отправлять инфу о коннекте предлагаю юзать FileMapping'и...
Если ListView5 заменить ListBox'ом со своим OnDrawItem можно добиться оптимизации загрузки лога раз в 40...
(попробуйте 20ти-метровый файл лога загрузить в пакетхак...если он не повиснет xD... в листбокс у меня грузится 4 секунды)
Ссылку на строку в Thread[].Dump можно хранить так:
Код:
lbPckList.Items.AddObject('', TObject(msg.LParam));
т.е. строк как таковых в ListBoxe не будет, будет в Object храниться integer = номеру строки в Thread[].Dump, а в OnDrawItem уже отрисовывать иконку и текст, читая целиком пакет из Thread[].Dump.
Да и вообще есть куча мелочей, которые хкор успешно игнорит...
что-нить ужасное типа:
Код:
CheckListBox2.Items.Strings[CheckListBox2.ItemIndex]:=scripts[CheckListBox2.ItemIndex].Name;
CheckListBox2.Items.Strings[CheckListBox2.ItemIndex-1]:=scripts[CheckListBox2.ItemIndex-1].Name;
tmp:=CheckListBox2.Checked[CheckListBox2.ItemIndex];
CheckListBox2.Checked[CheckListBox2.ItemIndex]:=CheckListBox2.Checked[CheckListBox2.ItemIndex-1];
CheckListBox2.Checked[CheckListBox2.ItemIndex-1]:=tmp;
можно заменить банальным
Код:
CheckListBox2.Items.Move(ItemIndex, ItemIndex-1);
вместо
Код:
if CheckBox7.Checked then
begin
ListView5.ItemIndex:=ListView5.Items.Count-1;
PostMessage(ListView5.Handle, WM_VSCROLL, SB_BOTTOM, 0);
// ListView1Click(Self);
end;
логичней написать
не будет мерцать при скролле.
ну и подобные вещи, которые не критичны, но в целом определяют стиль и быстродействие кода.
Из пожеланий и рекомендаций предлагаю добавить
Код:
fsScript.AddMethod('procedure log(msg:String):String', CallMethod);
Код:
procedure log(const Msg: string);
const
WM_COPYDATA=$004A;
var
CD: TCopyDataStruct;
begin
CD.dwData:=0;
CD.cbData:=Length(Msg);
if CD.cbData=0 then
CD.lpData:=nil
else
CD.lpData:=@Msg[1];
SendMessage(MainHWND, WM_COPYDATA, 0, integer(@CD));
end;
а в основном окне обрабатывать WM_Copydata и вытаскивать то, о чем нам хотел сообщить скрипт и отображать в ListBox3.
также предлагаю ввести прототипы функций:
Код:
function ReadS(packet: string; var index: integer; NoInc: Boolean=false): string;
function ReadD(packet: string; var index: integer; NoInc: Boolean=false): integer;
function ReadC(packet: string; var index: integer; NoInc: Boolean=false): char;
function ReadF(packet: string; var index: integer; NoInc: Boolean=false): double;
function ReadQ(packet: string; var index: integer; NoInc: Boolean=false): int64;
function ReadH(packet: string; var index: integer; NoInc: Boolean=false): word;
procedure WriteC(var destination: string; source: char);
procedure WriteH(var destination: string; source: word);
procedure WriteD(var destination: string; source: integer);
procedure WriteF(var destination: string; source: double);
procedure WriteQ(var destination: string; source: int64);
procedure WriteS(var destination: string; source: widestring);
procedure WriteZ(var destination: string; source: array of byte; size: integer);
в которых задается откуда читать и писать, не ограничиваясь pck и buf. NoInc=true в данном случае - не увеличивать index.
пример реализации
Код:
function ReadD(packet: string; var index: integer; NoInc: Boolean=false): integer;
begin
Result:=-1;
if Length(packet)<index then exit;
Move(packet[index], Result, SizeOf(Result));
if not NoInc then Inc(index, SizeOf(Result));
end;
вместо ужастного (правда это было у Хинта)
Код:
function ReadIntFromStr(str:string;index:integer):integer;
var
ab:array [1..4] of char;
ai:integer absolute ab;
i:integer;
begin
Result:=-1;
if Length(str)<index+3 then exit;
for i:=1 to 4 do ab[i]:=str[index+i-1];
Result:=ai;
end;