Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

KOL 3.23 [Delphi, Windows]


Vladimir Kladov ©   (21.02.15 10:24

[-] Исправления в KOL: WStrRScan - код скопирован из StrRScan. Исходная версия WStrRScan работала некорректно в случае отсутствия искомого образца.
[-] Исправления в обработчике WM_NCDESTROY для корректного уничтожения меню (не мог быть разрушен после разрушения окна-владельца).
[*] Улучшена функция ClipboardHasText - удален ненужный код.
[+] Метод TBitmap.CopyToClipboard переименован в CopyToClipboardAsDIB, добавлена другая версия CopyToClipboard, использующая формат CF_BITMAP (существенно более короткий код).


QAZ   (21.02.15 14:00[1]


> для корректного уничтожения меню

и какие такие дефины в проекте должны стоять, чтоб до этого исправления дошёл код вообще????

при закрытии в тестовом приложении как были утечки меню из под дельфи, так и остались, а в крупном проекте еще и ошибки памяти вылезли, попытка модификации после освобождения


QAZ   (21.02.15 14:05[2]

какая связь между этими адресами?
http://sourceforge.net/projects/kolmck/
http://sourceforge.net/projects/keyobjectslibrary/


Vladimir Kladov ©   (21.02.15 19:29[3]


> чтоб до этого исправления дошё

Да, я забыл про kol_asm.inc. Перевыложил, заодно и в kol.pas пару исправлений внес. В частности, добавил, что по заклинанию LET_MENU_LEAK все будет как раньше. Еще раз проверил в MemProof 0.9.4.8 и с FastMM3. Все чисто.


> какая связь между этими адресами?http://sourceforge.net/projects/kolmck/http:
> //sourceforge.net/projects/keyobjectslibrary/

Один из них не мой.


QAZ   (21.02.15 19:59[4]


> Один из них не мой.

не ну я так-то догадался, просто они тож чето там улучшают
вы типа не скооперированы вообще?


QAZ   (21.02.15 20:08[5]


> Да, я забыл про kol_asm.inc. Перевыложил, заодно и в kol.
> pas пару исправлений внес. В частности, добавил, что по
> заклинанию LET_MENU_LEAK все будет как раньше. Еще раз проверил
> в MemProof 0.9.4.8 и с FastMM3. Все чисто.

не, не работает
вот проверь тут полный комплект https://yadi.sk/d/1JxuHV9kedCXf запускай из под среды


QAZ   (21.02.15 20:22[6]

если это - это, то это копец, такая куча дефинов что до Final вообще недоходит

   WM_NCDESTROY:
                      {$IFnDEF SMALLER_CODE}
                      if  fHandle = Msg.hwnd then
                      {$ENDIF}
                      begin
                          {$IFNDEF LET_MENU_LEAK}
                          if  IsForm then
                          begin
                              {$IFNDEF SMALLER_CODE}
                              Hide;  // VK: to destroy form visually faster, 18.02.2015
                              {$ENDIF}
                              {$IFNDEF SMALLEST_CODE}
                              Final; // VK: to provide correct menu destroying, 18.02.2015
                              {$ENDIF}
                          end;
                          {$ENDIF}
                          {$IFnDEF SMALLER_CODE}
                              {$IFDEF USE_PROP}
                              RemoveProp( fHandle, ID_SELF ); //********* Added By M.Gerasimov
                              {$ELSE}
                              SetWindowLong( fHandle, GWL_USERDATA, 0 ); // VK + Alexey Kirov, 23.02.2012
                              {$ENDIF}
                          {$ENDIF} //-------------------------------------------
                          Default;
                          Exit;
                      end;


с PAS_VERSION вообще ниодна строчка в function TControl.WndProc( var Msg: TMsg ): Integer; неактивна в KOL.Pas


Vladimir Kladov ©   (22.02.15 10:52[7]

Вообще-то, все доходит. Это у Вас что-то неправильно. Например, не та версия исходников компилируется.

Мои исправления вообще не касались утечек памяти. FastMM3 их не показывал. Я решал проблему утечки ресурса меню. Пытался решить. Сейчас выкладываю новое исправление. На этот раз удалось лучше. И заодно проблемы с FastMM4 устраняются. Но исправление слишком радикальное, меняется порядок уничтожения окон. Может вылезти что угодно. Поэтому все можно будет вернуть по заклинанию LET_MENU_LEAK.

Уже выложил.


QAZ   (22.02.15 11:18[8]

ну во первых в комплекте отсутствует koladd.pas хотя требуется для установки


QAZ   (22.02.15 11:30[9]

во вторых чую придется снимать кино....


QAZ   (22.02.15 12:40[10]

в третьих вот видео (15Мб) https://yadi.sk/d/NLj7kB7NeppV9
а вот фастмм из видео https://yadi.sk/d/zqkEhLZbeppNk
условия съемки - чистая ХРшка + нулевая 5ка
что я там делаю не так?


Vladimir Kladov ©   (22.02.15 13:12[11]

Сразу: FastMM я скачал сам, версия 4.991, ваша 4.97. Вряд ли много отличий, но лучше, если Вы обновитесь. Дальше: я использовал Delphi7 под XP SP3 (виртуалка) со всеми обновлениями. delphi5 я давно не использую, но даже если с ней работать, для нее есть обновления. Слово нулевая нехорошо звучит.

Далее, для проверки с FastMM он должен быть первым в проекте. Рекомендую проверять это перед каждым билдом. MCK любит ссылку на KOL ставить на первое место.

Кроме того, для лучшей диагностики надо править опции проекта, убирать оптимизацию, добавлять в линкере символы TD32, тогда диагностика показывает красивше. Если до нее доходит дело, конечно.


QAZ   (22.02.15 14:03[12]


> нулевая нехорошо звучит

это звучит как "с обновой, без экспертов, без компонентов, с дефолтными настройками"
XP SP3 (виртуалка) со всеми обновлениями  - тоже самое
рабочий Delphi7 + полуживая Win7x64 - тот же результат
кудаб не писал FastMM, даже в сам кол.пас - никакой разницы
хоть с какими настройками отладки
версию FastMM попробую канешн обновить, но веть логично, что если  например в 2.79 такого не происходит, то проблема не в FastMM?


Vladimir Kladov ©   (22.02.15 14:25[13]

Да, не в нем. Потому что я уже попробовал и с вашей версией FastMM, и с Delphi5 уже (и даже без обновлений). И у меня все чисто. Еще подумал, может, FastMM молча падает. Нет, останавливается на строке кода FinalizeMemoryManager, по F8, выполняет и хочет работать дальше. Ни сообщений, ни логов. Добавляю опцию LET_MENU_LEAK, сообщения про утечки есть.

Проверьте, что с сайта KOL скачалась именно версия 3.23 (в начале kol.pas  VERSION 3.23+). MCK я не менял с июня.

Если не компилятор (версия Delphi), остается только железо и ОС, а это очень странно.


QAZ   (22.02.15 14:31[14]

вобщем с "новым" фастмм и всеми дебугами без оптимизаций
без LET_MENU_LEAK без среде в винде также ошибка
с LET_MENU_LEAK в винде без ошибки, а в среде вот такой вот файл с номерами строк, все по ГОСТу
https://yadi.sk/i/znRAQNpxepuP4


Vladimir Kladov ©   (22.02.15 17:42[15]

Обновил только что, 3.23++. Удалось получить сообщения под win7. Не знаю, виртуалка виновата, или еще что, но под XP оно как-то не детектило.


QAZ   (22.02.15 17:52[16]

если DEP включен для всех прог и делфи с проектным файлом не внесено в исключения, тогда может проглатывать


QAZ   (22.02.15 19:22[17]

так так так...
с меню вроде норм стало, по крайней мере, тестовый примитив и прога средней сложности молчит
однако в навороченной есть косяк. но уже не с меню, а похоже на Tlist, тоже из под делфи


QAZ   (22.02.15 19:42[18]

чет не пойму толи он врет с номерами строк толи с названием функций, причем через раз
глянь лог может поймешь https://yadi.sk/i/0Qq_PaHaeqA7T


QAZ   (22.02.15 20:11[19]

о еще косяк в другой поделке
если я впихиваю формы-фрэймы в таб контрол вот так (может это через Ж..)

NewForm2(Form2,TabControl1.Pages[2]);
NewForm3(Form3,TabControl1.Pages[1]);

то из под делфи опятьже утечка по этим 2м вкладкам или фрэмам, когда табконтроле были панели такого не было
https://yadi.sk/i/2iRkCf-NeqC5P
с какой версии эти глюки не скажу, ибо они прятались среди громадья глюков меню


Vladimir Kladov ©   (22.02.15 20:12[20]

Вот здесь полезная информация:
Текущий дамп памяти из 256 байт начиная с адреса 7EF43120:

Запускаем программу (F8), в Watches добавляем PDWORD($7EF43120), ставим "Break when changed", и каждый раз, когда первые 4 байта меняются, будет останов. Тут можно посмотреть, кто выделил.

Вообще похоже на то, что было добавление в TList, сам TList никто не освободил.


Vladimir Kladov ©   (22.02.15 20:18[21]

Фреймы даже не буду сейчас смотреть, уже просто не помню, что там и как.

Я вообще не вижу проблемы с утечками памяти. Если не мегабайтами течет. В современных приложениях вообще всё течет. Вин-8 - это просто одна сплошная протечка. Проги на шарпах со сборщиками мусора - там вообще не поймешь, то ли они текут беспрерывно, то ли это стратегия такая - мусор собирать раз в сутки.

Вот утечки ресурсов - это серьезно. Можно винду завалить, даже и 7-ку. 8-ку не пробовал (мало я с ней работал), но почему-то есть подозрение, что там ничего не изменилось.


QAZ   (22.02.15 20:26[22]


> Проги на шарпах

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

для меня утечка это как минимум сигнал что что то не так, а если что то не так, то в итоге накопится куча неразгребешь
вот с меню разобрались, сразу стали видны "скрытые" им другие проблемы

про фреймы хотяб скажи правильно ли им так назначать "родителя" и как их освобождать, просто фри или еще чего надо?


QAZ   (22.02.15 20:42[23]


> [+] Метод TBitmap.CopyToClipboard переименован в CopyToClipboardAsDIB,
>  добавлена другая версия CopyToClipboard, использующая формат
> CF_BITMAP (существенно более короткий код).

и пока я шарю в клипбордах :)
CopyToClipboardAsDIB - вообще нафиг не нужна
CF_DIB, CF_DIBV5 и CF_BITMAP взаимно конвертируются самой виндой при запросе конкретного варианта, а в 8ке вся эта метрошная лабуда вообще только CF_BITMAP должна посылать в буфер


Vladimir Kladov ©   (22.02.15 21:17[24]


> правильно ли им так назначать "родителя" и как их освобождать

Я сейчас точно уже не скажу как. В свете сегодняшних рытьёв наверное правильно сказать MyFrame.Form.Close; И да, я знаю, что это не форма, а, в общем-то, панель. Просто отправляется WM_CLOSE, дальше все по свистку от винды.


> CopyToClipboardAsDIB - вообще нафиг не нужна

Пусть останется. Я работал с битмапами, которые бывают только в DIB'е, потому что handle винде выделить не получается, слишком большой. И для совместимости.


Thaddy ©   (23.02.15 17:34[25]

I've merged 3.23++ into 64 bit unofficial. Plz test.
Link is:
http://thaddy.org/kol323-x64-unofficial.7z


Thaddy ©   (23.02.15 17:47[26]

This also contains function format for Freepascal and updated koldef.inc for Freepascal 3.0.1/3.1.1


Vladimir Kladov ©   (24.02.15 11:09[27]


> merged 3.23++

too fast. An error in asm version of run. it should be:

procedure Run( var AppletCtl: PControl );
asm
//----- if  AppletCtl = nil then Exit;
       TEST      EAX, EAX
       JZ        @@exit
       PUSH      EBX
       XCHG      EBX, EAX

//----- AppletRunning := TRUE;
       INC       [AppletRunning]

//----- Applet := AppletCtl;
       MOV       EAX, [EBX]
       MOV       [Applet], EAX

//----- AppletCtl.CreateWindow;
       CALL      CallTControlCreateWindow

//----- WHILE NOT AppletTerminated DO
@@loop: CMP       [AppletTerminated], 0
       JNZ       @@end_loop

//----- WaitMessage;
       CALL      WaitMessage

//----- AppletCtl.ProcessMessages;
       MOV       EAX, [EBX]
       CALL      TControl.ProcessMessages

       {$IFDEF   USE_OnIdle}
//----- ProcessIdle(AppletCtl);
       MOV       EAX, [EBX]
       CALL      [ProcessIdle]
       {$ENDIF}

       JMP       @@loop
@@end_loop:

       {$IFDEF LET_MENU_LEAK}
       MOV       ECX, [EBX]
       XCHG      EAX, EBX
       POP       EBX
       JECXZ     @@exit
       {$ELSE}
       POP       EBX
       LEA       EAX, [Applet]
       CMP       [EAX], 0

       JZ        @@exit
       {$ENDIF}
       CALL      TerminateExecution
@@exit:
end;


QAZ   (24.02.15 11:20[28]


>  Но исправление слишком радикальное, меняется порядок уничтожения
> окон. Может вылезти что угодно. Поэтому все можно будет
> вернуть по заклинанию LET_MENU_LEAK.

в общем печаль-тоска подобралась незаметно, есть новый виновник утечек и вылетов ---- KOLApplet
обнаружил при попытке разборок с фреймами, мысль была что может без него им плохо живется, ну типа по аналогии с несколькими формами
ток положил на форму и хобана + еще 8 утечек

потом
1)беру болванку эксперимента с меню, что выкладывал здесь, для приличия добавил 2ю форму, без апплета, запустил\закрыл - чисто
2) кладу аплет, запустил\закрыл - стоп в CPU-окне отладчика на user32.DestroyWindow
3) думаю, предупреждал же...
4) ставлю дефин LET_MENU_LEAK, удалил меню, для чистоты эксперимента, запустил\закрыл - 9 утечек, включая те самые Тлисты....
5) убираю аплетт, , запустил\закрыл - портянка на весь экран ошибка памяти
6) убираю дефин LET_MENU_LEAK, запустил\закрыл - чисто

кино ннада?


QAZ   (24.02.15 11:26[29]


> беру болванку эксперимента с меню

с дефином PAS_VERSION, чудеса не менее интересные, включая "рунтаймеррор"


Thaddy ©   (24.02.15 12:31[30]

Package is now updated as per Vladimir's change. (kol_asm.inc)


Vladimir Kladov ©   (24.02.15 13:08[31]

Вот где ошибка:

procedure TerminateExecution( var AppletCtl: PControl );
var App: PControl;
   Appalreadyterminated: Boolean;
begin
 Appalreadyterminated := AppletTerminated;
 AppletTerminated := TRUE;
 AppletRunning := FALSE;
 App := Applet;
 Applet := nil;
 if (App <> nil) {and (App.RefCount >= 0)} then
 begin
   {$IFDEF LET_MENU_LEAK} //was IFNDEF !!!
   App.RefInc;
   {$ENDIF}
   if not Appalreadyterminated then
   begin
     App.ProcessMessages;
     App.Perform( WM_CLOSE, 0, 0 );
   end;
   AppletCtl := nil;
   {$IFNDEF LET_MENU_LEAK}            //   версия KOL 3.23+:
           DestroyWindow(App.Handle); //** В этом варианте вызывается не деструктор
   {$ELSE}                            //   объекта, а функция закрытия окна. Вызов
           App.Free;
           App.RefDec;                //   деструктора выполнится в обработчике
   {$ENDIF}                           //   события WM_DESTROY. В результате, сначала
 end;                                 //   успешно разрушится меню формы. 22.02.2015
end;


и вот тут, соответственно (kol_asm.inc, + перенос кода за скобки ifdef'а, так что лучше всю процедуру заменить):
procedure TerminateExecution( var AppletCtl: PControl );
asm
         PUSH EBX
         PUSH ESI
         MOV  BX, $0100
         XCHG BX, word ptr [AppletRunning]
         XOR  ECX, ECX
         XCHG ECX, [Applet]
         JECXZ @@exit

         PUSH EAX

         {$IFDEF LET_MENU_LEAK} // Was IFNDEF !!!
         XCHG EAX, ECX
         MOV  ESI, EAX
         CALL TObj.RefInc
         {$ENDIF}

         TEST BH, BH
         JNZ  @@closed

         MOV  EAX, ESI
         CALL TControl.ProcessMessages
         PUSH 0
         PUSH 0
         PUSH WM_CLOSE
         PUSH ESI
         CALL TControl.Perform
@@closed:
         POP  EAX
         XOR  ECX, ECX
         MOV  dword ptr [EAX], ECX
         {$IFDEF LET_MENU_LEAK}
              MOV  EAX, ESI
              CALL TObj.RefDec
              XCHG EAX, ESI
              CALL TObj.RefDec
         {$ELSE}
              PUSH [ESI].TControl.FHandle
              CALL Windows.DestroyWindow
         {$ENDIF}
@@exit:
         POP  ESI
         POP  EBX
end;


Vladimir Kladov ©   (24.02.15 13:10[32]


> Package is now updated as per Vladimir's change. (kol_asm.
> inc)

Thaddy, you are still too fast! :)


QAZ   (24.02.15 15:41[33]


> Vladimir Kladov ©   (24.02.15 13:08) [31]

да-да по крайней мере паскальный вариант, самый большой проект, где был Tlist в логе - это и было изза апплета, сейчас все чисто

остался только косяк с фреймами (или табами) в другом

> Запускаем программу (F8), в Watches добавляем PDWORD($7EF43120),
>  ставим "Break when changed", и каждый раз, когда первые
> 4 байта меняются, будет останов. Тут можно посмотреть, кто
> выделил.

чет в 7ке нет такого "Break when changed" и пролетает мимо ненаходит


Vladimir Kladov ©   (24.02.15 15:59[34]

PDWORD(адрес)^ - разыменовать надо.


Vladimir Kladov ©   (24.02.15 16:07[35]

Обновил KOL.zip на kolmck.net.


QAZ   (24.02.15 20:40[36]

табконтрол вроде не причём, на панелях также
фастмм указывает на создание фрейма в файлах типа Unit2_1.inc
procedure NewForm2( var Result: PForm2; AParent: PControl );
begin

 {$IFDEF KOLCLASSES}
 Result := PForm2.Create;
 {$ELSE OBJECTS}
 New( Result, Create );<<<<<<<<<<<<<<<<<<<<<<<<<<
 {$ENDIF KOL CLASSES/OBJECTS}
 Result.Form := NewPanel( AParent, esNone ).MarkPanelAsForm;
 Result.Form.DF.FormAddress := @ Result.Form;
 Result.Form.DF.FormObj := Result;
   Result.Form.SetClientSize( 468, 278 );
   Result.EditBox1 := NewEditBox( Result.Form, [  ] ).SetPosition( 168, 104 );
   Result.EditBox1.Text := 'EditBox1';
   Result.EditBox1.Color := TColor(clWindow);
   Result.Form.CreateWindow;

end;

показано <<<<<<<<<<<<<
хоть free, хоть close - одинаково


Dimaxx ©   (25.02.15 00:43[37]

KOL_asm.inc:

procedure Run( var AppletCtl: PControl );
asm
//----- if  AppletCtl = nil then Exit;
      TEST      EAX, EAX
      JZ        @@exit
      PUSH      EBX
      XCHG      EBX, EAX

//----- AppletRunning := TRUE;
      INC       [AppletRunning]

//----- Applet := AppletCtl;
      MOV       EAX, [EBX]
      MOV       [Applet], EAX

//----- AppletCtl.CreateWindow;
      CALL      CallTControlCreateWindow

//----- WHILE NOT AppletTerminated DO
@@loop: CMP       [AppletTerminated], 0
      JNZ       @@end_loop

//----- WaitMessage;
      CALL      WaitMessage

//----- AppletCtl.ProcessMessages;
      MOV       EAX, [EBX]
      CALL      TControl.ProcessMessages

      {$IFDEF   USE_OnIdle}
//----- ProcessIdle(AppletCtl);
      MOV       EAX, [EBX]
      CALL      [ProcessIdle]
      {$ENDIF}

      JMP       @@loop
@@end_loop:

      {$IFDEF LET_MENU_LEAK}
      MOV       ECX, [EBX]
      XCHG      EAX, EBX
      POP       EBX
      JECXZ     @@exit
      {$ELSE}
      POP       EBX
      LEA       EAX, [Applet]
      CMP       [EAX], 0         <-ОШИБКА!!!!
      JZ        @@exit
      {$ENDIF}
      CALL      TerminateExecution
@@exit:
end;


Dimaxx ©   (25.02.15 00:46[38]

В destructor TMenu.Destroy не используется (но определяется) Next.


Vladimir Kladov ©   (25.02.15 05:35[39]


> CMP       [EAX], 0         <-ОШИБКА!!!!

Какая? В Delphi7 ошибки нет. У вас что, Free Pascal? Delphi 201x? Пишите яснее.


> В destructor TMenu.Destroy не используется (но определяется)
> Next.


destructor TMenu.Destroy;
var Next, Prnt: PMenu;
   {$IFNDEF LET_MENU_LEAK}
   Save_Ref: Integer;
   {$ENDIF}
begin
 {$IFDEF DEBUG_MENU_DESTROY}
 LogFileOutput( GetStartDir + 'TMenu.Destroy.txt',
   Int2Hex( DWORD( @ Self ), 6 ) + ' ' + Int2Str( RefCount ) );
 {$ENDIF}
 if Count > 0 then
 begin
   FMenuItems.ReleaseObjects;
   FMenuItems := NewList;
 end;
 if FParentMenu <> nil then
 begin
   {$IFNDEF LET_MENU_LEAK}
   Save_Ref := Self.fRefCount; //** Очень грязный хак, конечно. Цель: предотвратить
   Self.fRefCount := 17;       //   попытку повторного уничтожения этого объекта меню.
   {$ENDIF}
       Prnt := FParentMenu;
       Next := Prnt.RemoveSubMenu( FId );
       FParentMenu := nil;
       Prnt.FMenuItems.Remove( @ Self );
   {$IFNDEF LET_MENU_LEAK}
       Self.fRefCount := Save_Ref; //** Можно было бы и не восстанавливать.
   {$ELSE}
       if Next = nil then Exit;    //** Пришлось закомментарить. Вызывало утечку.
   {$ENDIF}
 end;
  if (FControl <> nil) and (FControl.fMenu = FHandle) and (FHandle <> 0) then
  begin
    if  {$IFDEF USE_FLAGS} not (G2_Destroying in FControl.fFlagsG2)
        {$ELSE} not FControl.fDestroying {$ENDIF} then //!!!fix by Galkov
    begin
      Windows.SetMenu( FControl.fHandle, 0 );
      // this removes main menu from window, but does not destroy it
    end;
    FControl.fMenu := 0;
    Next := PMenu( FControl.fMenuObj );
    while Next <> nil  do
    begin
      if Next.fNextMenu = @Self then
      begin
        Next.fNextMenu := fNextMenu;
        break;
      end;
      Next := Next.fNextMenu;
    end;
  end;
  Next := fNextMenu;
  if FBitmap <> 0 then
    Bitmap := 0;
  if FHandle <> 0 then
  begin
    //if not
    DestroyMenu( FHandle )
    // then LogFileOutput( GetStartDir + 'err.log.txt', SysErrorMessage( GetLastError ) )
    ;
  end;
  FCaption := '';
  FMenuItems.Free;
  Next.Free;
  inherited;
  // all later created (popup) menus (of the same control)
  // are destroyed too
end;

Расскажите уже, каким компилятором пользуетесь, что он такую чушь сказал.


Vladimir Kladov ©   (25.02.15 05:48[40]

Во вчерашнем обновлении не довставил новый TerminateExecution в KOL_ASM.INC. Поправить смогу только вечером. Берите код, что я здесь привел вчера, и вставьте сами (отличается комментариями с паскаль-кодом). Либо включите PAS_VERSION.


QAZ   (25.02.15 11:07[41]

в фрейме видимо не освобождается сама форма или как там ее назвать
если делать так, уничтожая по клику кнопки
procedure TForm1.KOLFormFormCreate(Sender: PObj);
begin
NewForm2(Form2,form1.Panel1);
NewForm3(Form3,form1.Panel2);
end;

procedure TForm1.Button1Click(Sender: PObj);
begin
Form2.Form.Free;
Form3.Form.Free;
Free_And_Nil(Form2);
Free_And_Nil(Form3);
end;

то случайным образом в 4 из 5 случаев, потом, приложение закроется молча, а в 1 случае портянка на весь экран, без Free_And_Nil "корневой" формы стабильно небольшая утечка


QAZ   (25.02.15 11:47[42]

обнаружил также избыточную генерацию бесполезного кода со стороны MCK в *.inc файлах
простой пример, главная форма с центрированием по эрану + панели с выравниванием
procedure NewForm1( var Result: PForm1; AParent: PControl );
begin

 {$IFDEF KOLCLASSES}
 Result := PForm1.Create;
 {$ELSE OBJECTS}
 New( Result, Create );
 {$ENDIF KOL CLASSES/OBJECTS}
 Result.Form := NewForm( AParent, 'Form1' ).SetPosition( 333, 228 );
 Applet :=  Result.Form;
 Result.Form.Add2AutoFree( Result );
   Result.Form.SetClientSize( 649, 361 );
   Result.Form.Font.FontHeight := -11;
   Result.Panel1 := NewPanel( Result.Form, esRaised ).SetAlign ( caBottom ).SetSize( 0, 191 );
   Result.Panel2 := NewPanel( Result.Form, esRaised ).SetAlign ( caRight ).SetSize( 305, 0 );
   Result.Button1 := NewButton( Result.Form, 'Button1' ).SetPosition( 128, 16 );
     Result.Button1.OnClick := Result.Button1Click;
   Result.Form.CenterOnParent;
   Result.KOLFormFormCreate( Result );

end;

сначала форма создается с координатами дизайнтайма SetPosition( 333, 228 );
потом уже под конец центруется на десктопе Result.Form.CenterOnParent;
понятно что при включеных свойствах CenterOnScreen и CenterOnCurrentScreen генерация кода вызова SetPosition( 333, 228 ) нафиг не нужна

панели SetAlign ( caBottom ).SetSize( 0, 191 )
при  наличии включенного свойства выравнивания, должен генерироваться только код SetSize( 0, 191 ), т.к. стартовый размер уже расчивается сразу в дезайнтайме, а SetAlign ( caBottom ) интерактивная рунтайм процедура, которая при создании формы конкретного стартового размера не имеет смысла

думаю таких моментов можно найти еще много при желании
итог - весь тот код что пытаемся экономить в KOL, транжирит MCK


QAZ   (25.02.15 12:48[43]


> а SetAlign ( caBottom ) интерактивная рунтайм процедура

пардон SetAlign странная процедура, ее логичней перевести исключительно в установщик флага выравнивания, без последующего вызова AlignChildrenProc
или выделить подобные функции каким нибуть префиксом типа MCK_UseOnly_ чтобы они только отвечали за установку свойств без интерактива, который при запуске приложения не имеет смысла


Vladimir Kladov ©   (25.02.15 19:46[44]

Обновил.


> избыточную генерацию бесполезного кода

Тоже мне новость. Кому нужен супер-компактный код, пишет "на чистом KOL".


Dimaxx ©   (25.02.15 21:41[45]

2 Vladimir Kladov: Delphi 5

[Error] KOL_ASM.inc(773): Invalid combination of opcode and operands.

По поводу Next - [Hint] KOL.pas(28984): Value assigned to 'Next' never used
при клике ссылается на Next := Prnt.RemoveSubMenu( FId ); в деструкторе.


Dimaxx ©   (25.02.15 21:46[46]

CMP dword ptr [EAX], 0 прокатывает, но я не знаю какая именно разрядность используется - byte/word/dword.


Vladimir Kladov ©   (26.02.15 18:39[47]

Добрался до Delphi5.


> Next - [Hint] KOL.pas(28984): Value assigned to 'Next' never
> used

Хорошо, это есть в Delphi5, согласен. Но это ни на что не влияет. Присваивается, дальше не используется, неприятность -только само сообщение.

Ошибка в CMP [EAX], 0 -- да, пока не поставил Update1, не показывал и компилировал правильно. Конечно, правильно CMP dword ptr [EAX], 0
Ведь в EAX был загружен адрес указателя (LEA EAX, Applet), и этот указатель сравнивается с NIL. Размер указателя в 32-битной платформе был DWORD.

Сейчас буду обновлять версию на сайте.


Dimaxx ©   (26.02.15 22:46[48]

Я проверил в портабельной Д7: CMP [EAX],0 в дизассемблированном виде как раз CMP dword ptr [EAX], 0.

Насчет хинта про неиспользованность - да, этим Д5 частит (а иногда задалбывает). Чем ей не нравится, что переменная используется только в левой части? Я понимаю, когда объявлена переменная, но ее ни разу не использовали в коде. А чем тут не понравилось, хз?


ParanoiS ©   (03.03.15 21:02[49]

Первым делом при получении новой версии KOL.pas изменяю в нем ParamStr и ParamCount.

var
 CmdLineParams: array of String;

function CommandLineToArgvW(lpCmdLine: PWideChar; var pNumArgs: Integer): PPWideChar;
 stdcall; external 'shell32.dll';

function ParamStr( Idx: Integer ): KOLString;
begin
 if (Idx in [0..ParamCount]) then
 Result:=CmdLineParams[Idx] else
 Result:='';
end;

function ParamCount: Integer;
var
 i:Integer;
 p:PPWideChar;
 c:PWideChar;
begin
 if Length(CmdLineParams)=0 then begin
   p:=CommandLineToArgvW(GetCommandLineW,i);
   while p^<>'' do begin
     SetLength(CmdLineParams,Length(CmdLineParams)+1);
     c:=p^;
     CmdLineParams[Length(CmdLineParams)-1]:=KOLString(c);//(OleStrToString(c));
     inc(p);
   end;
 end;
 Result:=Length(CmdLineParams)-1;
end;


Dimaxx ©   (13.04.15 20:21[50]

KOL 3.23.4
Ни с того, ни с сего стал выеживаться StrList. Любой. То постоянно падал на AddStrings - причем и в асме, и в паскалевской реализации. Создал пустой проект для проверки, все работает. O_o. Пересоздал проект заново, глюк исчез. Но когда скомпилировал проект оказалось, что StrList не видит текст внутри себя. Текст грузится из Stream (я для контроля сохранил в промежуточный файл - текст на месте, какой и должен быть). Но Count=0, соответственно цикл перебора строк не начинается, а сразу завершается. Кто-нить сталкивался с подобным? Я впервые столкнулся за много лет использования KOL...


DWorker   (17.04.15 10:03[51]

Давно столкнулся с этим - TStrList.AddStrings асм-версия приводила к падению(кстати подобное было еще у каких-то асм-функций).. Проблему не искал, просто отключил асм версию(на свне отключена до сих пор), пас-версия вроде не падает..


alexacolor   (29.04.15 18:49[52]

пора бы обновить TWindowsVersion, уже есть 8, 8.1, 10!


Владимир Кладов   (05.05.15 21:10[53]

2 alexcolor
До Win8 - можно использовать старый GetVersion[Ex]. Дальше начинаются проблемы. Чтобы просто проверить версию, надо такого нагородить... Рука-лицо, в общем. Смотрю, народ уже сильно не заморачиваясь, просто проверяет ветку реестра. Или версию kernel32.dll. Я пока до проверки Win8 догоню в следующем выпуске, а дальше посмотрим.

Предложения на самый короткий код, решающий эту задачу, принимаются. Можно здесь.

Пока код такой (Паскаль):
function WinVer : TWindowsVersion;
var MajorVersion, MinorVersion: Byte;
   dwVersion, tstVersion: Integer;
begin
 if SaveWinVer <> $FF then Result := TWindowsVersion( SaveWinVer )
 else
 begin
   dwVersion := GetVersion;
   MajorVersion := LoByte( dwVersion );
   MinorVersion := HiByte( LoWord( dwVersion ) );
   tstVersion := ((MajorVersion and 127) shl 8) or MinorVersion;
   {$IFDEF SUPPORT_WIN9X}
   if dwVersion < 0 then
   begin
     case tstVersion of
       $000..$3FF: Result := wv31;
       $400..$409: Result := wv95;
     //$40A..$459: Result := wv98;
       $45A:       Result := wvME;
       else        Result := wv98;
     end;
   end;
   SaveWinVer := Ord( Result );
   Exit;
   {$ENDIF}
   case tstVersion of
   $000..$499: Result := wvNT;
   $500:       Result := wvY2K;
   $501:       Result := wvXP;
   $502..$5FF: Result := wvServer2003;
   $600:       Result := wvVista;
   $601:       Result := wvSeven;
   $602:       Result := wvEight;
   $603:       Result := wvEight_1;
   else        Result := wvTen;
   end;
   SaveWinVer := Ord( Result );
 end;
end;


DWorker   (06.05.15 09:19[54]

Код получился типа такого же, только без SaveWinVer. Только проблема в том что на 8.1 и 10 винде показывает wvEight


Владимир Кладов   (07.05.15 16:33[55]

Я в курсе. Начиная с Windows 8.1, GetVersion/GetVersionEx объявлена устаревшей. Для того, чтобы приложение правильно определяло версию, к нему нужен специально оформленный манифест.


DWorker   (07.05.15 18:12[56]

Короткий вариант, определяет до 10 версии (9х поддержки нет):


function WinVerShort: TWindowsVersion;
begin
 case LoWord(GetVersion) of
   $0005: Result := wvY2K;
   $0105: Result := wvXP;
   $0205: Result := wvServer2003;
   $0006: Result := wvVista;
   $0106: Result := wvSeven;
   $0206: Result := wvEight;
   $0306: Result := wvEight_1;
   $000A: Result := wvTen;
   else
     Result := wvNT;
 end;
end;


Нужен подобный манифест:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
   <assemblyIdentity
       type="win32"
       name="DelphiApplication"
       version="1.0.0.0"
       processorArchitecture="*"
   />
   <description> my foo exe </description>
   <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
       <security>
           <requestedPrivileges>
               <requestedExecutionLevel
                   level="asInvoker"
                   uiAccess="false"
               />
           </requestedPrivileges>
       </security>
   </trustInfo>
   <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
       <application>
           <!-- Windows 10 -->
           <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
           <!-- Windows 8.1 -->
           <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
           <!-- Windows Vista -->
           <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
           <!-- Windows 7 -->
           <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
           <!-- Windows 8 -->
           <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
       </application>
   </compatibility>
</assembly>


alexacolor   (08.05.15 11:06[57]

актуальный манифест нынче очень полезен.

функция _WStrLComp в паскалевском исполнении за гранью добра и зла
из за неё не работают Name Value в WStrList, например


alexacolor   (08.05.15 14:09[58]

p.s. Ну не то что бы за гранью, но может запилить SVN комюнити?
Образовалось ещё одно применение для KOL: firemonkey программы для Windows. Всякие Tray Icon, tree и прочее


Dimaxx ©   (11.05.15 22:12[59]

При создании приложения в KOLProject меняем шрифт - в проекте в файле .inc меняются параметры любые, кроме имени шрифта. В итоге шрифт ВСЕГДА System независимо от заданного. Эта шляпа тянется уже давно - то работает, то после очередного обновления КОЛ опять не работает.


Thaddy ©   (26.05.15 12:20[60]


   Form.Font.ReleaseHandle;
   Form.Font.AssignHandle(GetStockObject(DEFAULT_GUI_FONT));


But I also have a better, but more complicated solution.


Netspirit   (10.03.17 12:59[61]

Ошибка в PAS_ONLY версии функции StrScan - функция никогда не возвращает nil, что приводит к ошибке, если символ не найден. Правильный код:


function StrScan(Str: PAnsiChar; Chr: AnsiChar): PAnsiChar;
begin
 Result := nil;
 if Str = nil then Exit;
 
 while Str^ <> #0 do
 begin
   if Str^ = Chr then
   begin
     Result := Str;
     Break;
   end;
   Inc(Str);
 end;
end;


DKOL   (16.03.17 13:06[62]

А если StrScan исправить, то другие функции начнут глючить... Во многих местах не проверки на nil

ps. вроде как то обсуждалось уже, надо поискать..


Netspirit   (16.03.17 15:11[63]


> А если StrScan исправить, то другие функции начнут глючить.

Нет, в том то и смысл, что из описания этой функции следует, что она должна вернуть nil, если символ не найден. Соответственно, весь код и так проверяет возвращаемый результат. И в случае PAS_ONLY успешно падает при ненахождении символа. Когда-то в старых версиях этот же баг был и в ASM-версии, но его исправили, а в PAS - забыли.


> вроде как то обсуждалось уже, надо поискать

Сравнительно недавно то же обсуждали и правили в WStrScan. Так сказать, по образу и подобию...


Netspirit   (16.03.17 15:32[64]

Напомню. Оригинал выглядит так:
function StrScan(Str: PAnsiChar; Chr: AnsiChar): PAnsiChar;
begin
   while Str^ <> Chr do
   begin
       if Str^ = #0 then break;
       inc(Str);
   end;
   Result := Str;
end;

В случае ненахождения символа возвращается не nil, а указатель на терминирующий #0.

Ну, и без проверки if Str = nil then Exit сама функция StrScan не падает только потому, что при вызове её обычно как if StrScan(PChar(S), 'A') <> nil then, Delphi при приведении строки к PChar вставляет ещё один вызов функции, которая проверяет строку на пустоту и для пустой строки возвращает действительный указатель на заранее заготовленный символ #0, лежащий где-то в области констант или глобальных переменных.
Так вот, если захочется ускориться, чтобы Delphi не вызывал дополнительную функцию, и вызвать StrScan как if StrScan(Pointer(S), 'A') <> nil then, то без проверки параметра Str на nil функция упадёт.

Я только что глянул, WStrScan тоже надо поправлять.


DKOL   (17.03.17 08:06[65]


> Нет, в том то и смысл, что из описания этой функции следует,
>  что она должна вернуть nil, если символ не найден.

Например функция StrScan, проверок нету.


> function StrScan(Str: PAnsiChar; Chr: AnsiChar): PAnsiChar;
.....

Изменения на svn внёс, StrScan пофиксил заодно.

WStrScan и ASM версии - не смотрел...


DKOL   (17.03.17 08:07[66]


> Например функция StrScan, проверок нету.


Имелась ввиду функция StrCat, копи-паста она такая)


Netspirit   (17.03.17 12:57[67]

А-а-а, там ещё и StrCat есть. А может кто-то на пальцах объяснить логику этой функции? Как я понимаю, эта функция объединяет две строки в одну, результат заносит по указателю в Dest, в качестве результата возвращает указатель на Dest. Типа, так?

procedure Test;
var
 Src, Dst: string;
begin
 Dst := 'ABC';
 Src := 'DEF';
 
 MessageBox(0, StrCat(PAnsiChar(Dst), PAnsiChar(Src)), '', 0);
 // PS: Этот код выдаёт ошибку!
end;


Вопрос: а кто ж в этой фунции занимается выделением памяти под результат объединения, а затем должен освободить эту память?
Чтоб далеко не ходили, приведу оригиналы этих функций:

function StrScan(Str: PAnsiChar; Chr: AnsiChar): PAnsiChar;
begin
   while Str^ <> Chr do
   begin
       if Str^ = #0 then break;
       inc(Str);
   end;
   Result := Str;
end;

function StrCopy( Dest, Source: PAnsiChar ): PAnsiChar;
var L: Integer;
begin
   L := StrLen(Source);
   Move(Source^, Dest^, L+1);
   Result := Dest;
end;

function StrCat( Dest, Source: PAnsiChar ): PAnsiChar;
begin
 // Итак. Оригинальная StrScan найдёт #0 в конце Dest
 // и вернёт нам указатель на конец Dest
 // Функция StrCopy должна скопировать Source в конец Dest
 // Спрашивается: а кто должен дать гарантию, что после
 // оригинального Dest есть свободное место, откуда оно взялось,
 // и кто отвечает за его освобождение?
 StrCopy( StrScan( Dest, #0 ), Source );
 Result := Dest;
end;


Исходя из выше озвученных рассуждений правильное использование должно выглядеть так:

procedure Test;
var
 Src, Dst: string;
begin
 Dst := 'ABC';
 Src := 'DEF';
 SetLength(Dst, Length(Dst)+Length(Src)); // Выделили память в Dst, чтобы уместить Dst+Src
 
 MessageBox(0, StrCat(PAnsiChar(Dst), PAnsiChar(Src)), '', 0);
end;


Где в цепочке вызовов StrCat->StrCopy+StrLen->StrScan находится термин "fast" из описания функции StrCat (в отличие от обычного Dst := Dst + Src;)?

Нюанс: в моей поправке StrScan символ #0 не найдётся. Потому что этот символ - это ограничитель null-terminated строки (используемой с типом PChar). Он не может являться частью строки (в отличие от дельфийского string). Единственная необходимость в получении указателя на #0 - это определение конца строки. И зачем это необходимо? Для определения количества символов, расположенных по указателю PChar (до терминирующего #0), используется функция StrLen().


DKOL   (23.03.17 12:01[68]


> Нюанс: в моей поправке StrScan символ #0 не найдётся.

Ну вот, как и говорил, исправили одно - сломали другое...


> Единственная необходимость в получении указателя на #0 -
>  это определение конца строки. И зачем это необходимо? Для
> определения количества символов, расположенных по указателю
> PChar (до терминирующего #0), используется функция StrLen().
>

В StrCat же и используется.


> Где в цепочке вызовов StrCat->StrCopy+StrLen->StrScan находится
> термин "fast" из описания функции StrCat (в отличие от обычного
> Dst := Dst + Src;)?

Не совсем понимаю, а зачем здесь термин fast?


> // Спрашивается: а кто должен дать гарантию, что после
>   // оригинального Dest есть свободное место, откуда оно
> взялось,
>   // и кто отвечает за его освобождение?


Гарантий никто не дает. Просто бывает с PChar строками так работают. Выделяют память с запасом, а потом через StrCat клеят.


Netspirit   (23.03.17 16:20[69]


> исправили одно - сломали другое...

Описание StrScan():
{* Fast search of given character in a string. Pointer to found character  (or nil) is returned. }

То-есть, должна вернуть nil, если искомый символ не найден. А условием ненахождения искомого символа является достижение символа #0. Тогда для поиска #0 нужно добавлять ещё условие. Например, так:
function StrScan(Str: PAnsiChar; Chr: AnsiChar): PAnsiChar;
begin
 Result := nil;
 if Str = nil then Exit;
 
 while Str^ <> #0 do
 begin
   if Str^ = Chr then
   begin
     Result := Str;
     Exit;
   end;
   Inc(Str);
 end;
 
 if (Chr = #0) and (Str^ = #0) then Result := Str;  
end;



> а зачем здесь термин fast?

Я ни при чем. Описание функции StrCat:
{* Append source string to destination (fast). Pointer to Dest is returned. }


> Выделяют память с запасом, а потом через StrCat клеят.

Я бы использовал Move() и не заморачивался (тем более, что вызывающему обычно точно известно, сколько места уже занято в том участке памяти, и сколько его выделено, следовательно, лишние StrLen ему не нужны).

Сделайте эту StrCat так:

function StrCat(Dest, Source: PAnsiChar): PAnsiChar;
begin
 Result := Dest;
 if (Dest = nil) or (Source = nil) then Exit;
 Move(Source^, Dest[StrLen(Dest)], StrLen(Source)+1);
end;


Netspirit   (23.03.17 17:02[70]

PS: условие and (Str^ = #0) в вышеприведенному коде StrScan, наверное, можно выбросить.


Dimaxx ©   (23.03.17 21:07[71]

>> Сделайте эту StrCat так:
Вкорне неверно. У вас не выделена память для строки Dest, чтобы принять Source простым копированием данных. Для начала нужно выделить память, а уж после копировать.


Dimaxx ©   (23.03.17 21:16[72]

Я чет ваще не тащу - зачем так сделано?

function StrCopy( Dest, Source: PAnsiChar ): PAnsiChar;
var L: Integer;
begin
   L := StrLen(Source);
   Move(Source^, Dest^, L+1);
   Result := Dest;
end;


Это ж бред. К примеру, есть у нас две строки "AAA" и "BBB". Мы передаем указатели в StrCopy и что получается? "BBB" копируется после "AAA" и получится "AAABBB". Но! Память для строки "AAA" у нас выделена только на три(!!) символа! А мы тупо копируем в область после первой строки (которая по идее ей еще не принадлежит) вторую строку. Это все равно что пытаться копировать один массив, выделенный GetMem, в конец второго массива. Но память-то выделена только под каждый размер массивов раздельно! Для слияния массивов нам надо Realloc памяти первого массива, с размером суммарных размеров массивов.


Dimaxx ©   (23.03.17 21:21[73]

И еще. Move(Source^, Dest^, L+1) скопирует содержимое Source в НАЧАЛО Dest!!! Разве это верно?


Dimaxx ©   (23.03.17 21:24[74]

Тьфу, я все напутал - думаю про StrCat, а пишу про StrCopy...

StrCopy должна сначала сделать длину Dest равной длине Source, а потом копировать. Ведь размеры строк могут различаться.

А вот в [72] все сказанное верно для StrCat в [69].


Netspirit   (24.03.17 11:40[75]


> StrCopy должна сначала сделать длину Dest равной длине Source

Ну, мы выше выяснили, что для этих функций вызывающий сам должен беспокоиться куда будут помещаться новые данные. Либо вообще не пользоваться этими функциями. Но то, что они должны как минимум работать согласно их описанию, - обязательно.


> скопирует содержимое Source в НАЧАЛО Dest

Это так и задумано - вызывающий сам передаёт указатель, по которому нужно записать данные. А указывать этот указатель может куда угодно. Например, StrCat находит указатель на завершающий #0 и передаёт его в эту функцию.

Напоминаю: если вы пользуетесь типом string, то вместо StrCat лучше использовать Dst := Dst + Src, а если таких операций много (типа, for i := 1 to 100000 do S := S + S2;) то такой код заменяется на такой:
L := Length(S2);
if L = 0 then Exit;
SetLength(S, 100000 * L);
i := 1;
while i <= 100000 do
begin
 Move(S2[1], S[i], L);
 Inc(i, L);
end;


Dimaxx ©   (24.03.17 23:53[76]

>> для этих функций вызывающий сам должен беспокоиться куда будут помещаться новые данные
Не соглашусь. Я, к примеру, этими функциями не пользовался и если бы стал - даже не подумал бы, что я сам должен чего-то увеличивать, прежде чем вызывать. Это все должно делаться внутри функции, а не до ее вызова.


Netspirit   (27.03.17 11:16[77]

Так и я тоже не подозревал о существовании этих функций. Просто пришлось делать выводы, глядя на их код.


Dimaxx ©   (09.04.17 10:54[78]

Еще один момент. Интенсивное использование Stream (проверял на открытом большом файле и из него копировал подряд куски в другие файлы - порядка 1000+ файлов) роняет приложение. Сначала все идет норм, потом АВ. То же самое на стандартном дельфевом TFileStream без проблем и падений.


DKOL   (10.04.17 08:33[79]

Dimaxx, а как то отладчиком реально поймать? или тулзами типа madExcept?


Netspirit   (10.04.17 10:40[80]

Dimaxx, ты бы выложил минимальную процедурку, которая делает что надо. Может быть, где-то с указателями на буфер и размером данных напутал.


Dimaxx ©   (10.04.17 23:49[81]

>> а как то отладчиком реально поймать? или тулзами типа madExcept?
По идее при АВ выдается адрес исключения. Надо по нему прыгнуть в код и увидеть где произошло исключение.

>> ты бы выложил минимальную процедурку, которая делает что надо. Может быть, где-то с указателями на буфер и размером данных напутал.
Я ж говорю - дельфевый выполняет ту же операцию без проблем. Размеры файлов все известны - они в виде списка типа "имя-размер":

SomeDir/SomeFile.dat 12345

Сами файлы все слиты один за одним в один огромный файл без заголовков. По сути различия только в коде со Stream. В выходные постараюсь найти код и опробовать, я уже не помню что и как делал.


PrnZ   (12.04.17 05:01[82]

Насчёт Stream. Адаптировал на КОЛ библиотеки NewAC и LZMA2 - может конечно я чёто неправильно делаю - смысл такой -

type PA=^TA;
TA=object(TObj)
...
FStream:PStream;
...
// etc
end;

Ну и соответственно процедуры типа ReadLZMA(...) SeekLZMA(...) etc в соответствующей структуре.

ДАК ВОТ - пишу прогу с использованием оригинальных классов LZMA и соответственно с моим объектом. Разница - 160К. НО!!! прога с классами быстрее раз в 5. всё делал вроде бы по закону. Такое же наблюдается с адаптационными объектами NewAC (при чтении и распаковке файлов, но там возможно ДЛЛ гонит... но в классах же не гонит... хз), и не только. Некоторые адаптации с сайта (DlUCL напр.) тоже тормозят в сравнении с классом.

Делал тестовый класс/объект с рандомным потоком - вроде всё норм... хз...


Netspirit   (12.04.17 14:35[83]

Не представляю что там может тормозить. Сколько там того объекта?
Может где-то в часто вызываемые процедуры объект передаётся не по ссылке, а по значению? Всё равно, разница в скорости вряд-ли была бы больше 20%, хотя зависит от кода...


Dimaxx ©   (12.04.17 23:07[84]

Вопрос по падение снимается. Нашел старый проект, скомпилировал - 2 гиговый файл "разложился" без проблем.


PrnZ   (15.04.17 10:13[85]

to:Netspirit
Вот и я не могу понять. Оригинальный класс наследуется от TFileStream. Я же делаю объект от KOL.TObj, делаю поле Stream:PStream; делаю в конструкторе NewStream(ProcRec), где ProcRec - record ReadProc, WriteProc, SeekProc etc. end; соответственно перевожу методы из оригинального класса в функции Read,Write,Seek итд. Короче вроде всё правильно. О том что "вызываемые процедуры объект передаётся не по ссылке, а по значению" - не, я уже забыл когда на ВЦЛ писАл. Да и компилятор не позволит. ХЗ чё за фигня... Могу выложить модуль на справедливый народный суд. Модуль сколько весит - не помню, не от себя сейчас сижу. Чё-то около 2000-2500 строк.


Dimaxx ©   (18.04.17 20:32[86]

Шрифт в КОЛ уже реально выбешивает.

Задаешь шрифт (Tahoma, height=-11, он по умолчанию), в дизайнере все нормально. Компиляция, запуск. Какого хрена??? Шрифт, мать его, System (корявый растровый .fon), размер, мать его, 10. В unit1_1.inc про шрифт вообще ни строчки. Ничего не меняется, даже если в коде руками поставить имя шрифта (Tahoma) и высоту (-11). Ставишь -12 - шрифт Tahoma, высота -12 - все верно, но мне надо стандартный. Любое FontQuality не меняет ничего. Выставляешь fqProof - в unit1_1.inc ко всем контролам формы прописывается высота шрифта, но не та, что я задал (-11), а -13. Опять-таки WTF?? В итоге шрифт все же становится Tahoma, но размер неверный. И после возвращения FontQuality=fqDefault ничего не меняется, потому что весь unit1_1.inc испещрен FontHeight:=-13. Убрал руками все. Скомпилировал - шрифт опять System. То есть КОЛ игнорирует заданное и пихает свое. DefFont в KOL.pas установлен точно также - Tahoma, -11. Пишу руками в unit1_1.inc - FontHeight:=-11. Компилирую и все становится на свои места, но! После закрытия и открытия проекта файл unit1_1.inc перегенерируется заново и снова все через опу. Почему игнорит КОЛ - я хз. Имхо при записи кода создания формы в unit1_1.inc надо принудительно выставить параметры шрифта, либо искать где он гадит, если шрифт не задан и используется дефолтный.

Далее: в dfm объект формы стоит первым. У всех контролов в dfm Font.FontHeight = -13. Откуда??? Я не задавал -13 вообще. С какого потолка оно взято? И почему KOL берет значения свойств из TForm, а не из TKOLForm???

Помогло только принудительное создание шрифта DefFont

procedure TForm1.KOLForm1BeforeCreateWindow(Sender: PObj);
begin
 DeleteObject(Form.Font.ReleaseHandle);
 Form.Font.Assign(NewFont);
end;


DKOL   (13.05.17 18:09[87]

Если вдруг интересно кому - то вырезал кучу старого хлама из KOL.pas (типа нерабочей Linux поддержки, "очень важной" поддержки делфи 2 и т.д).
Cкинул на свн https://sourceforge.net/projects/kolmck/

зы. возможно что отвалилось\сломалось...


Vladimir Kladov ©   (17.05.17 21:15[88]

http://clavier.link (язык AL-IV - АЛФОР):
18.05.2017 v0.62 Добавлена поддержка платформы Win32/Delphi/KOL (версия KOL 3.23) - на данный момент только не визуальной его части (работа продолжается).


Dimaxx ©   (01.07.17 19:05[89]

Столкнулся с глюком TBitmap. Гружу 24-битное, преобразовываю дизерингом в 8-битное. Затем мне надо, чтобы размеры (если они меньше заданных) были подогнаны под один и тот же размер (добавляются поля черного). Так вот после увеличения только ширины картинки изображение становится 32-битным (с какого перепугу??). Если сначала увеличить высоту, а потом ширину, то изображение остается 8-битным.


QAZ   (07.07.17 19:38[90]


> Vladimir Kladov ©   (17.05.17 21:15) [88]

регистрозависимость это дичь ....
нет элементарной документации аля "хеловёрд" по спецификациям начать что то писать невозможно


sheleh   (21.07.17 20:02[91]

Привет спецам!
Помогите пжлст. Под андрюшу вышел бинарный транслятор x86 в ARM от программистов из Сколково, что писали нечто подобное под Эльбрус.
В общем эти ребята в Play Market выложили свое творение - wine 1.9, работающий под андройдом на любом ARM устройстве. Там они его распространяют преимущественно для запуска старых игр. Называется ExaGear.
И действительно, на нем работает куча программ. Но только не мои, написанные на delphi с применением библиотеки KOL. А так хотелось.....
Вылетает даже минимальная программа, создающая пустую форму.
Вот скрин https://s1.postimg.org/vkb1liaan/20170722_005204.jpg
Компилирую в delphi 6, запущенной в этой среде. Отладчик не ссылается ни на какой участок кода. Как узреть, что именно приводит к вылету?


L`Autour   (01.08.17 10:27[92]

по функции:
function Extended2Str( E: Extended ): KOLString;

нужно кроме предвартельной проверки E на 0, еще добавить проверку на Infinity и NAN, иначе уйдет в бесконечный цикл.


Dimaxx ©   (28.08.17 20:25[93]

Сделал для себя новый Format для КОЛ - старый слишком убог по функционалу. Абсолютно весь функционал вводить не стал, взял только самое распространенное.

// для unicode - vswprintf_s

function vsprintf_s(Buffer: PChar; BufferSize: integer; const Fmt: PChar; Args: pointer): integer; cdecl; external 'msvcrt.dll';

function Format(const Fmt: string; Params: array of const): string;
var
 VA,Tmp: PByte;
 Buffer: array[0..4095] of Char;
 I,A,Size: integer;
 D: double;
begin
 FillChar(Buffer,sizeof(Buffer),0);
 if High(Params)>=0 then
   begin
     Size:=0;
     // Считаем размер буфера для аргументов
     for I:=0 to High(Params) do
       with Params[I] do
         case VType of
           vtInteger: Inc(Size,sizeof(Integer));
           vtChar: Inc(Size,sizeof(Char));
           vtWideChar: Inc(Size,sizeof(WideChar));
           vtPChar,vtAnsiString,vtPWideChar,vtWideString,vtPointer: Inc(Size,sizeof(Pointer));
           vtExtended: Inc(Size,sizeof(Double));
         end;
     GetMem(VA,Size);
     FillChar(VA^,Size,0);
     Tmp:=VA;
     for I:=0 to High(Params) do
       begin
         A:=sizeof(Pointer);
         with Params[I] do
           case VType of
             vtInteger:
               begin
                 A:=sizeof(Integer);
                 PInteger(Tmp)^:=VInteger;
               end;
             vtChar:
               begin
                 A:=sizeof(Char);
                 PChar(Tmp)^:=VChar;
               end;
             vtPChar: PPointer(Tmp)^:=VPChar;
             vtAnsiString: PPointer(Tmp)^:=VString;
             vtWideChar:
               begin
                 A:=sizeof(WideChar);
                 PWideChar(Tmp)^:=VWideChar;
               end;
             vtPWideChar: PPointer(Tmp)^:=VPWideChar;
             vtWideString: PPointer(Tmp)^:=VWideString;
             vtExtended:
               begin
                 A:=sizeof(Double);
                 D:=VExtended^;
                 PDouble(Tmp)^:=D;
               end;
           end;
         Inc(Tmp,A);
       end;
     I:=vsprintf_s(@Buffer[0],4096,PChar(Fmt),VA);
     if I>0 then
       begin
         SetLength(Result,I);
         Result:=Buffer;
       end;
     if VA<>nil then FreeMem(VA);
   end;
end;


Все символы описаны в https://msdn.microsoft.com/ru-ru/library/hf4y5e3w.aspx


QAZ ©   (06.09.17 17:26[94]


> L`Autour   (01.08.17 10:27) [92]
> по функции:function Extended2Str( E: Extended ): KOLString;
> нужно кроме предвартельной проверки E на 0, еще добавить
> проверку на Infinity и NAN, иначе уйдет в бесконечный цикл.
>

незнай как там с проверками, но Extended2Str в 6 раз!!! медленней стандартной Str и в 4.5 раз FloatToStr из сисутилсов


DKOL   (07.09.17 06:30[95]

>Сделал для себя новый Format для КОЛ - старый слишком убог по функционалу.

А в чем убогость то заключается? Вроде основное все было..

>незнай как там с проверками, но Extended2Str в 6 раз!!! медленней стандартной Str и в 4.5 раз FloatToStr из сисутилсов

Получается у Extended2Str нет никаких преимуществ перед стандартной Str?


QAZ ©   (07.09.17 16:56[96]


> Получается у Extended2Str нет никаких преимуществ перед
> стандартной Str?

нету, так же как и у FloatToSt,IntToStr,Int2Str


L`Autour   (08.09.17 10:24[97]

И как же KOLString, UNICODE_CTRLS?


QAZ ©   (08.09.17 14:22[98]


> И как же KOLString, UNICODE_CTRLS?

а без разницы, Str в топе


Dimaxx ©   (08.09.17 18:02[99]

>> А в чем убогость то заключается? Вроде основное все было..
Типа старые функции небезопасны. И старый Format не поддерживает и половины возможностей. Насколько помню, плавающий формат он не переваривал. Была доработка, но она криво отображала float.


dlf   (06.10.17 22:42[100]

если не ошибаюсь, в ТВижн чё то такое было, и с плавающими итп... без всяких vsprintf_s. по крайней мере видел в исходниках Дос Навигатора


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо