Конференция "KOL" » Версия 2.90 [Delphi, Windows]
 
  • Vladimir Kladov © (27.03.10 22:03) [0]
    Новости от 27 марта 2010 (KOL & MCK v2.90)
    [-]
    Для символа USE_NAMES, исправлен SetName
    Hallif, VK
    [*]
    TStrList, TStrListEx (так же частично для TWStrList, TWStrListEx) методы IndexOf, IndexOf_NoCase, Find и Sort улучшены, добавлен FindFirst
    VK, mdw
    [-]
    Восстановлена совместимость с Delphi2 и Delphi3
    VK
    [*]
    UNI
    Дополнительные изменения для улучшения UNICODE_CTRLS: RemoveSpaces, AnsiCompareText, AnsiCompareStrA, _AnsiCompareStrA, AnsiCompareStrNoCaseA, _AnsiCompareStrNoCaseA, AnsiEq, CompareLVColumns

    [-]
    Ссылка на uxtheme изменена на uxtheme.dll.
    MTsv DN
    [-]
    Исправления в декларациях (для определенного символа STREAM_COMPAT): SeekMemStream, SetSizeMemStream, ReadMemStream, WriteMemStream, WriteExMemoryStream.
    Hallif
    [-]
    Исправление в WndProcToolbarCtrl для Win98
    MTsv DN
    [+]
    TIcon.LoadFromXXXX теперь понимает иконки WinCE (16 бит на пиксель)
    mdw
    [+]
    ASM версия для WinVer
    MTsv DN, VK
    [*]
    MCK
    В mirror.pas и mckCtrls.pas, введен тип TDelphiString и все условные декларации по {$IFDEF _D2009orHigher} устранены - для правильной работы Code Completion.
    VK
    [-]
    TAction.LinkMenuItem исправлен для динамических меню
    mdw
    [*]
    В WndProc_LVCustomDraw, Canvas больше не создается.
    mdw

  • Dufa © (28.03.10 11:58) [1]
    Не понимаю, почему так уопрно не хотите юзать свн... но все же обновил его. Теперь есть пара отличий:

    - delphidef.inc удален, вся информация перенесена в KOLDEF.inc
    * про MCKAppExpert200x, MTsvDN уже писал, но напомню:

    procedure TMCKWizard.Execute;
    var
     prj: String;
     unt: String;
     dlg: TSaveDialog;
     lst: TStringList;
    begin
     dlg            := TSaveDialog.Create(nil);
     dlg.Options    := [ofOverwritePrompt, ofExtensionDifferent, ofPathMustExist];
     dlg.Title      := 'Save Project';
     dlg.Filter     := 'DPR files|*.dpr';
     dlg.DefaultExt := 'dpr';
     if dlg.Execute then begin
       prj := dlg.FileName;
       if (Pos('.', prj) = Length(prj) - 3) then
         SetLength(prj, Length(prj) - 4);
       dlg.Title := 'Save Unit';
       dlg.Filter := 'PAS files|*.pas';
    .....



    KOL.pas:
    * шрифт по умолчанию Tahoma, размер шрифта -11
    + добавлена функция Swap для Byte

    procedure Swap( var X, Y: Integer ); overload;
    {$IFDEF F_P}
    var Tmp: Integer;
    begin
     Tmp := X;
     X := Y;
     Y := Tmp;
    end;
    {$ELSE DELPHI}
    asm
     MOV  ECX, [EDX]
     XCHG ECX, [EAX]
     MOV  [EDX], ECX
    end;
    //[END Swap]
    {$ENDIF F_P/DELPHI}

    //[procedure Swap]
    procedure Swap(var X, Y: Byte); overload;
    var
     T: Byte;
    begin
     T := X;
     X := Y;
     Y := T;
    end;


    + добавлена функции _GetDIBPixelsTrueColorWithAlpha, _SetDIBPixelsTrueColorWithAlpha (для 32битных битмапов, старый код вырезает альфу)
    //[FUNCTION _GetDIBPixelsTrueColorWithAlpha]
    function _GetDIBPixelsTrueColorWithAlpha( Bmp: PBitmap; X, Y: Integer ): TColor;
    var
     Pixel: DWORD;
     RGB:   TRGBQuad;
    begin
     Pixel := PDWORD( Integer(Bmp.fScanLine0) + Y * Bmp.fScanLineDelta +
                      X * Bmp.fBytesPerPixel )^ and $FFFFFFFF;
     RGB := TRGBQuad(Pixel);
     Swap(RGB.rgbBlue, RGB.rgbRed);
     Result := TColor( RGB );
    end;
    //[END _GetDIBPixelsTrueColorWithAlpha]

    function TBitmap.GetDIBPixels(X, Y: Integer): TColor;
    begin
     if not Assigned( fGetDIBPixels ) then
     begin
       if fHandleType = bmDIB then
       begin
         fScanLine0 := ScanLine[ 0 ];
         fScanLineDelta := Integer(ScanLine[ 1 ]) - Integer(fScanLine0);
         case PixelFormat of
         pf1bit:
           begin
             fPixelMask := $01;
             fPixelsPerByteMask := 7;
             fGetDIBPixels := _GetDIBPixelsPalIdx;
           end;
         pf4bit:
           begin
             fPixelMask := $0F;
             fPixelsPerByteMask := 1;
             fGetDIBPixels := _GetDIBPixelsPalIdx;
           end;
         pf8bit:
           begin
             fPixelMask := $FF;
             fPixelsPerByteMask := 0;
             fGetDIBPixels := _GetDIBPixelsPalIdx;
           end;
         pf15bit:
           begin
             fPixelMask := 15;
             fGetDIBPixels := _GetDIBPixels16bit;
           end;
         pf16bit:
           begin
             fPixelMask := 16;
             fGetDIBPixels := _GetDIBPixels16bit;
           end;
         pf24bit:
           begin
             fPixelsPerByteMask := 0;
             fBytesPerPixel := 3;
             fGetDIBPixels := _GetDIBPixelsTrueColor;
           end;
         pf32bit:
           begin
             fPixelsPerByteMask := 1;
             fBytesPerPixel := 4;
             fGetDIBPixels := {$IFDEF FIXDIB32}_GetDIBPixelsTrueColorWithAlpha{$ELSE}_GetDIBPixelsTrueColor{$ENDIF};
           end;
         else;
         end;
       end;
       if not Assigned( fGetDIBPixels ) then
       begin
         Result := Pixels[ X, Y ];
         Exit;
       end;
     end;
     Result := fGetDIBPixels( @Self, X, Y );
    end;

    ...

    //[PROCEDURE _SetDIBPixelsTrueColorWithAlpha]
    procedure _SetDIBPixelsTrueColorWithAlpha(Bmp: PBitmap; X, Y: Integer; Value: TColor);
    var RGB: TRGBQuad;
       Pos: PDWord;
    begin
     RGB := TRGBQuad({Color2RGB}(Value));
     Swap(RGB.rgbBlue, RGB.rgbRed);

     Pos := PDWORD( Integer(Bmp.fScanLine0) + Y * Bmp.fScanLineDelta
                    + X * Bmp.fBytesPerPixel );
     Pos^ := Pos^ {and $FF000000} or DWORD(RGB);
    end;
    //[END _SetDIBPixelsTrueColorWithAlpha]

    procedure TBitmap.SetDIBPixels(X, Y: Integer; const Value: TColor);
    begin
     if not Assigned( fSetDIBPixels ) then
     begin
       if fHandleType = bmDIB then
       begin
         fScanLine0 := ScanLine[ 0 ];
         fScanLineDelta := Integer(ScanLine[ 1 ]) - Integer(fScanLine0);
         case PixelFormat of
         pf1bit:
           begin
             //fPixelMask := $01;
             //fPixelsPerByteMask := 7;
             fSetDIBPixels := _SetDIBPixels1bit;
           end;
         pf4bit:
           begin
             fPixelMask := $0F;
             fPixelsPerByteMask := 1;
             fSetDIBPixels := _SetDIBPixelsPalIdx;
           end;
         pf8bit:
           begin
             fPixelMask := $FF;
             fPixelsPerByteMask := 0;
             fSetDIBPixels := _SetDIBPixelsPalIdx;
           end;
         pf15bit:
           begin
             fPixelMask := 15;
             fSetDIBPixels := _SetDIBPixels16bit;
           end;
         pf16bit:
           begin
             fPixelMask := 16;
             fSetDIBPixels := _SetDIBPixels16bit;
           end;
         pf24bit:
           begin
             fPixelsPerByteMask := 0;
             fBytesPerPixel := 3;
             fSetDIBPixels := _SetDIBPixelsTrueColor;
           end;
         pf32bit:
           begin
             fPixelsPerByteMask := 1;
             fBytesPerPixel := 4;
             fSetDIBPixels := {$IFDEF FIXDIB32}_SetDIBPixelsTrueColorWithAlpha{$ELSE}_SetDIBPixelsTrueColor{$ENDIF};
           end;
         else;
         end;
       end;
       if not Assigned( fSetDIBPixels ) then
       begin
         Pixels[ X, Y ] := Value;
         Exit;
       end;
     end;
     fSetDIBPixels( @Self, X, Y, Value );
    end;



    KOLasm.inc:
    * изменен на использование _GetDIBPixelsTrueColorWithAlpha, _SetDIBPixelsTrueColorWithAlpha
  • Vladimir Kladov © (28.03.10 14:24) [2]
    delphidef.inc удален, вся информация перенесена в KOLDEF.inc
    Давно это произошло? Верните на место. Я сейчас попробую объяснить. koldef.inc предназначен для включения в любой файл проекта, не только в KOL.pas. Его задача - помочь бороться с тысячами ненужных предупреждений от компиляторов новых версий, в основном, ну и уже заодно - добавить символы условной компиляции _$Dxx, _$DxxorHigher и т.п., чтобы можно было в проектах тоже учитывать версию компилятора. delphidef.inc содержит определения только для kol.pas.

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

    шрифт по умолчанию Tahoma, размер шрифта -11 Сколько раз уже писал, что не надо так делать. Дефолтный фонт должен быть таким, чтобы не приходилось его устанавливать программным кодом, пусть даже его генерит автоматом MCK. Кому надо установить в MCK желаемый дефолтный фонт на проект - TKOLProject.DefaultFont + TKOLForm.fontDefault = true. По умолчанию вообще должен быть фонт System, это где-то это когда-то вызывало неприятности, уже не помню где. Против Tahoma я как бы не возражаю как против дефолтного не системного, но он появился как обязательный только начиная с win98, если не ошибаюсь. Нет, не ошибаюсь: http://itua.info/news/hardware/3726.html
    А мы вроде как и Win95 поддерживаем.

    procedure Swap( var X, Y: Integer ); overload; Не очень хорошо. Для Delphi2, 3, и кажется 4, overload - слово неизвестное. Уже лучше назовите SwapBytes. (Можно и IFDEF'ами, но тогда пользователи старых Delphi лишаются одной функции, и непонятно зачем).

    добавлена функции _GetDIBPixelsTrueColorWithAlpha, _SetDIBPixelsTrueColorWithAlpha (для 32битных битмапов, старый код вырезает альфу Не проще ли было поправить (по кондиции или сразу) Color2RGBQuad, ведь альфа именно там и отрезается в _Set, а для _Get - изменить саму _GetDIBPixelsTrueColor (там Color2RGBQuad всего лишь для обмена R и B, и вызывается просто по принципу "вылить из чайника и вызвать уже готовый код").

    SVN я не пробовал, пока на диал-апе сидел. Когда платишь за каждую лишнюю минуту онлайна, сидеть и разбираться, что к чему, некогда. Сейчас можно. Хотя новшеств я не люблю. Если они не позволяют радикально облегчить жизнь. Потому и Delphi 20хx не люблю.
  • Dufa © (28.03.10 16:50) [3]
    delphidef- только для КОЛа, а KOLDEF для всего... малость не понятно %) плюс к этому внутри delphidef.inc можно обнаружить {$I KOLDEF.INC}...
    MCKAppExpert200x- находится в вашем архиве, поэтому и стоит его исправить
    Насчет поддержки 95... Просто каждый раз начиная новый проект (в котором хотелось бы иметь "обычный виндовый шрифт"), с установленным, по умолчанию System приходится его каждый раз менять.. А так один раз поставил и забыл.. Вылез в 95ой глюк - исправил..
    Swap Это еще повезло, что inline; не успел воткнуть :D
    Конечно можно и переименовать, но имхо лучше в сторону юзабельности отказываться от старых версий.. D2 оно зачем ваще?

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

    SVN Предлагаю разобраться как время будет =) я сделаю доступ Вам и сможете напрямую все обновлять. Минусов в SVN нет имхо, даже тот кто не хочет качать через svn-клиент, может сливать все через браузер (GNU tarball)

    Delphi 20хx На самом деле привыкнуть гораздо быстрее чем кажется. Ну и от задач все зависит. Сейчас сижу на Турбе, а уже хотелось бы генереки...

    USE_CONSTRUCTORS, KOLCLASSES USE_CONSTRUCTORS - давно не работает. По KOLCLASSES уже давно не хватает кода.. Реально ли восстановить функциональность? И какой будет прирост к размеру ЕХЕ, если использвать class вместо object?

    Напоминаю адрес SVN http://sourceforge.net/projects/kolmck/
  • Vladimir Kladov © (28.03.10 17:42) [4]
    Ну как же не понятно. Посмотрите, что в них есть. Я всегда включаю koldef.inc во все исходные файлы, чтобы получить удаление всех предупреждений, не имеющих смысла для низкоуровневого кода. И получить символы версии в нормальных запоминаемых буквах, тем более кумулятивные символы сам Delphi Не дает, если ver120, то она и есть 120, а 130 отдельно сравнивать надо. И зачем мне надо, чтобы в каждом исходном файле вставлялись символы из delphidef.inc.

    MCKAppExpert200x - перенаправил ссылку на kolnmck.

    Вылез в 95ой глюк - исправил. Я вот не могу даже запустить под 95, у меня ее нет. Глюк вылезет у того, кто запустит готовую программу на 95.

    имхо лучше в сторону юзабельности отказываться от старых версий.. D2 оно зачем ваще?Delphi2 поддерживает coff-формат объектных файлов,  это единственная версия Delphi, в которой можно делать драйвера. А зачем мне Delphi 5 ? Да потому что он не тормозит даже по сравнению с Delphi 7. И нет никаких особых преимуществ у новых версий по сравнению со старыми.
    Delphi 20хx На самом деле привыкнуть Поэтому дело не в том чтобы привыкнуть, а в тормозах. А привыкать чего, я же на шарпе работал, тот же дико неудобный интерфейс. Но главное - тормоза.

    До сих пор в KOL не было почти ни одного overload'а. Зачем их добавлять, тем более из-за такой функции, для которой отдельное имя никак не уменьшит юзабельности. Я же так понял, что он только для обмена каналов R и B в цвете используется. Пока не поздно, надо поменять.

    GetDIBPixelsTrueColorWithAlpha, SetDIBPixelsTrueColorWithAlpha А вот тут как раз, чтоб не испортить старое Зачем портить IFDEF, никто не отменял.

    USE_CONSTRUCTORS, KOLCLASSES USE_CONSTRUCTORS - давно не работает. Но и выбрасывать тоже как-то не вижу особой причины. По KOLCLASSES уже давно не хватает кода. Это хуже, но тоже поправимо. На все надо время. Прирост небольшой, ровно как после включения classes, килобайт 30.
  • Vladimir Kladov © (28.03.10 17:56) [5]
    Не могу SVN запустить. Я Explorer'ом обычно не пользуюсь. А тут запустил для svn - и сразу после этого и-нет стал недоступен. Отключил Web-экран в авасте, этот сайт пошел, теперь kolmck.net и Soundforge недоступен. Вроде пингуются. Ерунда какая-то. В общем, сегодня и-нет барахлит, не получится.
  • vampir_infernal (28.03.10 18:47) [6]
    Господа, всплыл неприятный глюк. Метод TMenu.RemoveSubMenu в версиях 2.89 и 2.90 оставляет утечку памяти (по fastmm4). В версии 2.88 такого не было, проверил.

    Если закомментировать строку
    M.FMenuItems.Remove( Result );

    в методе TMenu.RemoveSubMenu, то фастмм доволен, но и Count не уменьшается
  • Vladimir Kladov © (28.03.10 19:35) [7]
    А если заменить
    M.FMenuItems.Remove( Result );


    на
    if Result.FParentMenu <> nil then
    Result.FParentMenu.FMenuItems.Remove( Result );


    ?
  • Vladimir Kladov © (28.03.10 19:37) [8]
    Второй вариант - на
    Items.Remove(Result);


    уже без всяких условий.
  • vampir_infernal (28.03.10 22:41) [9]
    Items.Remove(Result);

    хочет, чтобы ему казали индекс, так как
    property Items[ Id: HMenu ]: PMenu

    . Первый вариант тоже не подходит, фастмм ругается на все то же
  • mdw (29.03.10 17:51) [10]

    > TStrList, TStrListEx (так же частично для TWStrList, TWStrListEx)
    > методы IndexOf, IndexOf_NoCase, Find и Sort улучшены...


    Владимир, нашел ошибку в Find(). Возникает, если искомая строка больше любой строки в списке. Вот простейший пример:

    var SL: PStrList;
       I: Integer;
    begin
       SL:= NewStrList;
       SL.Add('0'); SL.Add('1'); SL.Add('2'); SL.Add('3');
       SL.Sort(False);
       SL.Find('1', I); //Здесь отрабатывает нормально
       SL.Find('2', I); //Здесь отрабатывает нормально
       
       SL.Find('4, I); //Здесь валится
       SL.Free;

    Посмотрел код, причина - выхода индекса за пределы диапазона в последнем сравнивании метода Find(). Если использовать AnsiSort, по AV не возникает, но только потому, что используются другие функции сравнивания.
  • mdw (29.03.10 17:54) [11]
    Так поправил:
    ....
     if (L < FCount) and not Result then
         Result := fCompareStrListFun( PAnsiChar( fList.Items[ L ] ),
                                       PAnsiChar( S ) ) = 0;
    end;
  • Vladimir Kladov © (29.03.10 18:12) [12]
    Вытащил версию. Было так (в 2.88):

    //[function TMenu.RemoveSubMenu]
    function TMenu.RemoveSubMenu( ItemToRemove: Integer ): PMenu;
    {$IFDEF DEBUG_MENU}var OK: Boolean; {$ENDIF}
    begin
     Result := Items[ ItemToRemove ];
     if Result = nil then Exit;
     if Result.FParentMenu <> nil then
       {$IFDEF DEBUG_MENU} OK := {$ENDIF}
       RemoveMenu( Result.FParentMenu.FHandle, Result.FId, MF_BYCOMMAND )
     else
       {$IFDEF DEBUG_MENU} OK := {$ENDIF}
       RemoveMenu( FHandle, Result.FId, MF_BYCOMMAND );
     {$IFDEF DEBUG_MENU}
     if not OK then
       ShowMessage( 'Error removing menu: ' + Int2Str( GetLastError ) + ' - ' +
                    SysErrorMessage( GetLastError ) );
     {$ENDIF}
     if Count = 0 then
     begin
       Result.Free;
       Result := nil;
     end;
     RedrawFormMenuBar;
    end;



    Стало так (в 2.89-2.90):
    //[function TMenu.RemoveSubMenu]
    function TMenu.RemoveSubMenu( ItemToRemove: Integer ): PMenu;
    {$IFDEF DEBUG_MENU}var OK: Boolean; {$ENDIF}
    var M: PMenu;
    begin
     Result := Items[ ItemToRemove ];
     if Result = nil then Exit;
     M := Result.FParentMenu;
     if M = nil then M := @Self;
     {$IFDEF DEBUG_MENU} OK := {$ENDIF}
     RemoveMenu( M.FHandle, Result.FId, MF_BYCOMMAND );
     M.FMenuItems.Remove( Result );
     {$IFDEF DEBUG_MENU}
     if not OK then
       ShowMessage( 'Error removing menu: ' + Int2Str( GetLastError ) + ' - ' +
                    SysErrorMessage( GetLastError ) );
     {$ENDIF}
     if Count = 0 then
     begin
       Result.Free;
       Result := nil;
     end;
     RedrawFormMenuBar;
    end;



    Хоть тресни, никак не могу углядеть разницы, кроме формально другого кода с использованием промежуточной переменной. И добавления
    M.FMenuItems.Remove( Result );



    Наконец, просто попробуйте вернуть старый код из 2.88. Если там шло и без утечек. И тогда надо разобраться зачем я добавил (по чьей просьбе) эту строчку. У меня почему-то не помечено, кто просил.

    Ага, MTsv DN: http://pda.delphimaster.net/?id=1259909126&n=10
    Чтобы Count уменьшался типа.
  • Vladimir Kladov © (29.03.10 18:56) [13]
    2mdw:
    if (L < FCount) and not Result then



    Допускаю. На тестах ищется только случайная строка из самого списка. Но, кажется, так будет лучше:
     
     ...
     if  L >= Count then
         Dec( L );
     Index := L;
     if  not Result then
         Result := fCompareStrListFun( PAnsiChar( fList.Items[ L ] ),
                                       PAnsiChar( S ) ) = 0;


    Через параметр Index возвращается в любом случае последняя строка как ближайшая найденная, возвращаемый результат FALSE. Или неважно, лишь бы не падало в случае если больше чем любая в списке?
  • Vladimir Kladov © (29.03.10 19:03) [14]
    Чего-то у меня черепашка svn не может достучаться до nekki.ru. Пишет Cannt connect to host. A connection attempt failed because the connection party did not properly respond after a period of time or established connection failed because connected host has failed to respond. В файрволле крыжык на TortoiseProc.exe стоит. Web-экран в avast! отключен. Не знаю, чего ему еще надо. Может мой провайдер отсекает. ping идет, http://nekki.ru работает.
  • mdw (29.03.10 19:50) [15]

    > Через параметр Index возвращается в любом случае последняя
    > строка как ближайшая найденная, возвращаемый результат FALSE.
    >  Или неважно, лишь бы не падало в случае если больше чем
    > любая в списке?

    Да мне в конкретном случае пофиг, главное - найдено\не найдено. Поэтому так и поправил. Но возможно, кому-то действительно будет важно еще и ближайшая "найденая" строка, да и описанию функции будет соответствовать. :) Ваш вариант оставляем тогда.
  • mdw (29.03.10 19:57) [16]

    > > Через параметр Index возвращается в любом случае последняя
    > > строка как ближайшая найденная, возвращаемый результат
    > FALSE.>  Или неважно, лишь бы не падало в случае если больше
    > чем > любая в списке?Да мне в конкретном случае пофиг, главное
    > - найдено\не найдено. Поэтому так и поправил. Но возможно,
    >  кому-то действительно будет важно еще и ближайшая "найденая"
    > строка, да и описанию функции будет соответствовать. :)
    > Ваш вариант оставляем тогда.

    Хотя, другой стороны, то Index = FCount информирует о том, что строка именно больше последней... В общем, не знаю, на Ваше усмотрение, как правильнее...
  • Vladimir Kladov © (29.03.10 20:53) [17]
    Я предпочел Count-1, т.к. планировал Find использовать для вставки в уже отсортированный список новых строк так, чтобы список оставался отсортированным. Если возвращается false, сравниваем со строкой по индексу, если получилась новая больше, делаем Insert( Index+1, newS ), иначе Insert( Index, newS ). Оно и в случае Index==Count не страшно, но нужна еще одна дополнительная проверка, не вышел ли Index>=Count, зато строку в этом случае сравнивать не нужно. Можно и описание чуть-чуть поменять. Главное здесь - что быстрее. Но если смотреть, что быстрее, то еще быстрее не делать последнее сравнение, оно явно лишнее. А лучше вообще вот так:

    function TStrList.Find(const S: AnsiString; var Index: Integer): Boolean;
    var
     L, H, I, C: Integer;
    begin
     Result := FALSE;
     L := 0;
     H := FCount - 1;
     if  H < 0 then Exit; // === if FCount = 0 then Exit;
     if  fAnsiSort then
     begin
         if  fCaseSensitiveSort then
             fCompareStrListFun := CompareAnsiCase
         else
             fCompareStrListFun := CompareAnsiNoCase;
     end
       else
     begin
         if  fCaseSensitiveSort then
             fCompareStrListFun := StrComp
         else
             fCompareStrListFun := StrComp_NoCase;
     end;
     C := 0;
     while L <= H do
     begin
       I := (L + H) shr 1;
       C := fCompareStrListFun( PAnsiChar( fList.Items[ I ] ),
                                PAnsiChar( S ) );
       if C < 0 then L := I + 1 else
       begin
         H := I - 1;
         if C = 0 then
         begin
           Result := TRUE;
           Index := I;
           Exit;
         end;
       end;
     end;
     Index := L;
     if  C < 0 then Index := -L;
    end;



    Т.е. возвращать в случае FALSE в Index индекс ближайшей строки, но если искомая меньше этой строки, то возвращать Index с минусом. Тогда проверка еще больше упрощается:

    if Index < 0 then Insert( -Index, sNew ) else Insert( Index+1, sNew );

    И соответственно поправить описание.
  • Vladimir Kladov © (29.03.10 21:05) [18]
    Нет, немного не так. На тестах погонял, понял, что не то. Вот так лучше:

    function TStrList.Find(const S: AnsiString; var Index: Integer): Boolean;
    var
     L, H, C: Integer;
    begin
     Result := FALSE;
     Index := 0;
     L := 0;
     H := FCount - 1;
     if  H < 0 then Exit; // === if FCount = 0 then Exit;
     if  fAnsiSort then
     begin
         if  fCaseSensitiveSort then
             fCompareStrListFun := CompareAnsiCase
         else
             fCompareStrListFun := CompareAnsiNoCase;
     end
       else
     begin
         if  fCaseSensitiveSort then
             fCompareStrListFun := StrComp
         else
             fCompareStrListFun := StrComp_NoCase;
     end;
     C := 0;
     while L <= H do
     begin
       Index := (L + H) shr 1;
       C := fCompareStrListFun( PAnsiChar( fList.Items[ Index ] ),
                                PAnsiChar( S ) );
       if C < 0 then L := Index + 1 else
       begin
         H := Index - 1;
         if C = 0 then
         begin
           Result := TRUE;
           Exit;
         end;
       end;
     end;
     if  C < 0 then Index := -L;
    end;

  • Vladimir Kladov © (29.03.10 21:20) [19]
    А если немного улучшить StrComp, StrCom_NoCase, то еще быстрее. Где-то на 5%:

    function StrComp(const Str1, Str2: PAnsiChar): Integer; assembler;
    asm
     {$IFDEF F_P}
           MOV     EAX, [Str1]
           MOV     EDX, [Str2]
     {$ENDIF F_P}
     MOV CL, [EAX]
     SUB CL, [EDX]
     JZ  @@compare
     MOVSX EAX, CL
     JMP @@fin
    @@compare:

           PUSH    EDI
           PUSH    ESI
           MOV     EDI,EDX
           XCHG    ESI,EAX
           OR      ECX, -1
           XOR     EAX,EAX
           REPE    CMPSB
           MOV     AL,[ESI-1]
           MOV     DL,[EDI-1]
           SUB     EAX,EDX
           POP     ESI
           POP     EDI
    @@fin:
    end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};

    function StrComp_NoCase(const Str1, Str2: PAnsiChar): Integer;
    asm
     {$IFDEF F_P}
           MOV     EAX, [Str1]
           MOV     EDX, [Str2]
     {$ENDIF F_P}
           PUSH    EDI
           PUSH    ESI
           MOV     EDI,EDX
           XCHG    ESI,EAX
           OR      ECX, -1
           
           MOV     EDI,EDX
     @@0:
           XOR     EDX,EDX
           REPE    CMPSB
           MOV     AL,[ESI-1]
           MOV     AH, AL
           SUB     AH, 'a'
           CMP     AH, 25
           JA      @@1
           SUB     AL, $20
     @@1:
           MOV     DL,[EDI-1]
           MOV     AH, DL
           SUB     AH, 'a'
           CMP     AH, 25
           JA      @@2
           SUB     DL, $20
     @@2:
           MOV     AH, 0
           SUB     EAX,EDX
           JNZ     @@exit
           CMP     DL, 0
           JNZ     @@0

     @@exit:
           POP     ESI
           POP     EDI
    end {$IFDEF F_P} [ 'EAX', 'EDX', 'ECX' ] {$ENDIF};

  • Vladimir Kladov © (29.03.10 21:46) [20]
    Но так делать нельзя, к сожалению.
  • vampir_infernal (29.03.10 23:46) [21]

    > У меня почему-то не помечено, кто просил.

    Вот тут http://pda.delphimaster.net/?id=1222611039&n=10 в 15м посте я указал на две утечки памяти. В версии 2.89 первая (TempOleStr) вообще не подписана, а вторая подписана D[u]fa. Владимир, ну как же так? :) :)
  • Dufa © (30.03.10 17:20) [22]
    Vladimir Kladov а разве на некки.ру еще что-то есть? До того адреса, что я давал есть коннект?
  • Dufa © (30.03.10 17:23) [23]
    Насчет StrComp не понял.. почему нельзя?

    vampir_infernal , эмм.. не понял.. утечка устранена?
  • Vladimir Kladov © (30.03.10 17:35) [24]
    D[u]fa Насчет StrComp нельзя потому что в случае равных строк сравнение продолжится за пределы строки, пока не будет найдена пара неравных символов, в итоге равенства не будет никогда. Не говоря уже о том, что за границу строки вылазить некрасиво.

    vampir_infernal Вот тут http://pda.delphimaster.net/?id=1222611039&n=10 в 15м Я извиняюсь. Скорее всего, я прочитал не первое сообщение, а перепост от D[u]fa. А что же вы так поздно спохватились - 1.5 года прошло?

    2 D[u]fa Та утечка (или 2) вроде исправлена. Теперь не поймем, что там с RemoveSubMenu творится, mdw пока молчит. До того адреса не достукивается, черепашка открывает окошко, долго висит, потом выдает то сообщение.
  • Dufa © (30.03.10 18:29) [25]
    VK А вот этот адрес https://kolmck.svn.sourceforge.net/svnroot/kolmck ?
    Если опять нет, могу предложить другой, простенький (местами топорный, зато портабл) свн клиент.

    А вот RemoveSubMenu вроде было обсуждение раньше... или путаю уже просто
  • vampir_infernal (30.03.10 19:26) [26]
    1.5 года прошло
    Дык 2 года обновления не было, да и в армию ходил

    VK
    Еще порция. Если в проекте установить NEW_MODAL и PAS_VERSION, то KOL.PAS не компилируется, функция
    function WndProcForm(Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;

    . Все строки со ссылками на поля объекта Self_ (как я понял) там описаны без указания самого объекта, то бишь просто
    if fModalForm <> nil then

    . Поскольку више по коду with нигде нет, получается, нужно дописать Self_ к каждому, или же объявить with Self_^ do begin. Пока у себя исправил так, со строки 36751:
         if Self_.fModalForm <> nil then
           SetFocus( Self_.fModalForm.fHandle )
         else if ( Self_.FCurrentControl <> nil ) and
                 not ( Self_.fCurrentControl.IsForm xor Self_.fIsApplet ) then



    D[u]fa
    RemoveSubMenu обсуждали в версии 2.88, после чего в 2.89 исправили уменьшение свойства Count, но фастмм4 убежденно видит в добавленной строчке утечку.
  • mdw (30.03.10 19:53) [27]

    >  Теперь не поймем, что там с RemoveSubMenu творится, mdw
    > пока молчит.

    А что я должен сказать? Я про RemoveSubMenu вообще не в курсе... Может и есть там утечка, а может нет, мне как-то фиолетово, не так часто и не в таких количествах меню удаляется, чтоб уж так переживать из за нескольких байт.Если кого то это раздражает, пусть исправит, я всеми руками за! :)
  • vampir_infernal (31.03.10 11:25) [28]
    mdw
    Метод RemoveSubMenu вызывается при уничтожении объекта PMenu, так что если у Вас в программе используются главное и/или контекстное меню, пусть и статические, то утечку Вы получите
  • mdw (31.03.10 11:33) [29]

    > mdwМетод RemoveSubMenu вызывается при уничтожении объекта
    > PMenu, так что если у Вас в программе используются главное
    > и/или контекстное меню, пусть и статические, то утечку Вы
    > получите


    > Может и есть там утечка, а может нет, мне как-то фиолетово,
    >  не так часто и не в таких количествах меню удаляется, чтоб
    > уж так переживать из за нескольких байт.
    Если кого то это
    > раздражает, пусть исправит, я всеми руками за! :)
  • QAZ (04.04.10 20:11) [30]
    ошибка
    function FileSeek(Handle: THandle; {$IFNDEF STREAM_COMPAT} const {$ENDIF} MoveTo: TStrmSize; MoveMethod: TMoveMethod): TStrmSize;

    должно быть MoveTo:TStrmMove тк может быть отрицательным

    также видимо не внесено исправление когда на тулбар ложица тракбар или любой комон контрол -вылетает нафиг,исправление было ранее на форуме
    http://pda.delphimaster.net/?id=1245664606&n=10
  • QAZ (04.04.10 20:25) [31]
    также для коректной работы  скролбара нужно

    в procedure TControl.SetSBPageSize(Value: Integer);
    SI.nMax := SI.nMax - Integer(SI.nPage) + Value;
    заменить на SI.nMax := SI.nMax;

    в procedure TControl.SetSBMinMax(const Value: TPoint);
    SetScrollRange(Handle, SB_CTL, Value.X, Value.Y + SBPageSize - 1, True)
    заменить на SetScrollRange(Handle, SB_CTL, Value.X, Value.Y - 1, True)

    иначе PageSize не показывает реального размера прокручиваемых данных
  • Vladimir Kladov © (05.04.10 20:54) [32]
    По FileSeek согласен.

    Второе - сделано:
    if (Child <> nil)
          and (Child <> Self_) //+ by Galkov, Jun-2009


    Положил ListView - не вылетает.

    По скроллбару объсните, что не показывает, или пример приведите. Я поставил SBPageSize 20 - размер 20%, поставил 30 - 30% (SBMax=100 как по умолчанию).
  • Mr (06.04.10 09:21) [33]
    При изменении темы уже падать перестало? Я помню, что ответ был вида: событие редкое если надо делайте сами. Но все-же, что выбираем стабильность или экономию в несколько байт?
    PS
    От чего стандартного еще может падать?
  • QAZ (06.04.10 12:07) [34]

    > //+ by Galkov, Jun-2009

    ну вобщем както еще есть ASM версия,которая не исправлена... и используеца по умолчанию

    > По скроллбару объсните, что не показывает, или пример приведите

    http://narod.ru/disk/19441012000/kosyak.jpg.html
    ---------------------------------------------------
    а это что за хрень стала генерица ?
    {$IF Defined(KOL_MCK)} вместо {$IFDEF KOL_MCK} моя дельфя7 этого не понимает


    { KOL MCK } // Do not remove this line!
    {$DEFINE KOL_MCK}
    unit Unit1;

    interface

    {$IFDEF KOL_MCK}
    uses Windows, Messages, KOL {$IF Defined(KOL_MCK)}{$ELSE}, mirror, Classes,  mckCCtrls, Controls, mckCtrls {$ENDIF};
    {$ELSE}
    {$I uses.inc} mirror,
     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
    {$ENDIF}



    +еще тудаже когда мск не находит путь к модулям она выдает дибильный диалог типа "выбери папку"
    соответствено нужно сделать (добавить флаг) чтоб там был едит для ручной вставки пути, тк за****ся выбирать их вручную в дереве
    либо пусть автоматом определяет по пути к dpr
  • Dufa © (06.04.10 15:52) [35]
    QAZ, {$IF Defined(KOL_MCK)} уже больше года...


    > моя дельфя7 этого не понимает


    кривая делфи
  • QAZ (06.04.10 16:07) [36]

    > кривая делфи

    да нет кривой мск,тк сделали генерацию без учета открытия "старых" исходников
    которые выглядят вот так

    { KOL MCK } // Do not remove this line!
    {$DEFINE KOL_MCK}
    unit Unit1;

    interface

    {$IFDEF KOL_MCK}
    uses Windows, Messages, KOL {$IFNDEF KOL_MCK}, mirror, Classes,  mckCCtrls, Controls, mckCtrls {$ENDIF};
    {$ELSE}
    {$I uses.inc} mirror,
     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
    {$ENDIF}



    соответствено какого хрена после {$IF Defined(KOL_MCK)} пишется {$ELSE} ?
    изза которого собсна и еррор при компиле
  • Dufa © (06.04.10 16:20) [37]
    Ну а если подумать? =)

    {$IFNDEF KOL_MCK}, mirror, Classes,  mckCCtrls, Controls, mckCtrls {$ENDIF};

    в переводе на русский, если НЕ кол то mirror, Classes,  mckCCtrls, Controls, mckCtrls

    {$IF Defined(KOL_MCK)}{$ELSE}, mirror, Classes,  mckCCtrls, Controls, mckCtrls

    в переводе на русский если КОЛ то ..., а если нет то mirror, Classes,  mckCCtrls, Controls, mckCtrls.

    Если ошибка реально в этом то - делфи кривая, ибо на 7 все проверено и работает. Другое дело что при переходе код может криво сгенерица.


    >
    > {$IF Defined(KOL_MCK)}{$ELSE}, mirror, Classes,  mckCCtrls,
    >  Controls, mckCtrls {$ENDIF};

    замени на
    {$IF Defined(KOL_MCK)}{$ELSE}, mirror, Classes,  mckCCtrls, Controls, mckCtrls {$IFEND};
  • Vladimir Kladov © (06.04.10 16:48) [38]
    При изменении темы уже падать перестало? Я помню, что ответ был вида: событие редкое если надо делайте сами. Но все-же, что выбираем стабильность или
    экономию в несколько байт?
    У вас есть фикс? Я например, темами не балуюсь. Кроме крайней необходимости что-то под темы отладить, вырубаю до запрета службы themes. Рюшеки с тормозами - юзерам, мне не надо.

    да нет кривой мск,тк сделали генерацию без учета открытия "старых" исходников
    Как критиковать так все сразу и умные и пряморукие. Проект открывает не MCK, его открывает и корёжит в момент открытия - Delphi. MCK Всего лишь работает с тем, что ему досталось после такого кривого открытия. Если у вас есть идея (в виде готового кода), как сделать так, чтобы кривизны не было - мы тут со всеми распростертыми.
  • QAZ (06.04.10 17:50) [39]

    > Ну а если подумать? =)
    > в переводе на русский

    я в курсе что это за директивы и как они работают

    а вот нафига было вообще менять {$IFNDEF KOL_MCK}.... {$ENDIF}
    на {$IF Defined(KOL_MCK)}{$ELSE}....{$IFEND}
    что в переводе на русский "шило на мыло", можеш просвятить
  • vampir_infernal (06.04.10 18:44) [40]

    > а вот нафига было вообще менять

    а это для поддержки в МСК версий делфи от D2005 и выше. Обсуждалось в форуме же
  • vampir_infernal (06.04.10 19:06) [41]
    Vladimir Kladov
    Скажите, пожалуйста, для чего в KOL.PAS присутствует следующее:
    1) начиная со строки 12033 объявляется свой тип TMenuitemInfo, аналогичный одноименному из windows.pas, с разницей в типе KOLChar;
    2) в строке 27348 указано
    Windows.PMenuitemInfo( @ MII )^ );


    3) в строке 27369 по аналогии с предыдущим пунктом
    и при этом всём в kol_unicode.inc объявлены нормально и закомментированы типы TMenuitemInfo, PMenuitemInfo и MENUITEMINFO?
    Раскомментировал в kol_unicode, закомментировал объявление типа и прямую ссылку на модуль windows в kol.pas, протестировал как сумел, работает и в юникоде, и без. Взгляните, когда будет время
  • Mr (07.04.10 08:52) [42]

    > У вас есть фикс? Я например, темами не балуюсь. Кроме крайней
    > необходимости что-то под темы отладить, вырубаю до запрета
    > службы themes. Рюшеки с тормозами - юзерам, мне не надо.
    >

    Фикса нет (KOL и Delphi у меня используется исключительно на "побаловаться"). Дело не в том, что кому-то темы нужны, а кому-то нет, а в том, что это ненормальная реакция программы. Просто напомнил о старой ошибке.
  • Vladimir Kladov © (07.04.10 16:23) [43]
    Не используйте темы, и все. Кому надо, чтобы работало с темами, тот пусть исправляет. При отсутствии поддержки тем и манифеста ничего не ломается.
  • Vladimir Kladov © (08.04.10 15:27) [44]
    Кстати, с темами тоже чего-то не упало. Дайте пример, который падает, если это что-то более сложное, чем пустой проект с формой и парой кнопок. Или расскажите, как переключать темы, чтобы падало (с какой на какую).
  • Vladimir Kladov © (08.04.10 18:14) [45]
    vampir_infernal
    Скажите, пожалуйста, для чего в KOL.PAS присутствует следующее:
    1) начиная со строки 12033 объявляется свой тип TMenuitemInfo, аналогичный одноименному из windows.pas, с разницей в типе KOLChar;
    2) в строке 27348 указано Windows.PMenuitemInfo( @ MII )^ );
    3) в строке 27369 по аналогии с предыдущим пунктом
    и при этом всём в kol_unicode.inc объявлены нормально и закомментированы типы TMenuitemInfo, PMenuitemInfo и MENUITEMINFO?
    Раскомментировал в kol_unicode, закомментировал объявление типа и прямую ссылку на модуль windows в kol.pas, протестировал как сумел, работает и в юникоде,
    и без. Взгляните, когда будет время

    Дело в совместимости с Win95/NT4 и в совместимости с Delphi2,3. KOLChar = это как раз для UNICODE_CTRL, под древними ОС все равно проект, откомпилированный с этой опцией, не идет, разницы в размере структуры он не дает, важен не тип указателя, а наличие поля hbmItem, его в Delphi 2, 3 не объявили, но это поле и не особенно нужно для обычной работы, а в 95/NT4 даже еще и мешает - система не понимает размер структуры 48, им 44 подавай. Т.е. как было - как раз правильно, и протестировано в NT4 и Win95. Оставьте и не трогайте, или устанавливайте себе 95 (не OSR2!!!) и NT4, тестируйте под ними, а потом говорите, что все работает.
  • Mr (09.04.10 09:04) [46]
    Вот на этом падает при смене тем.
    http://slil.ru/28931281
  • MTsv DN (09.04.10 12:40) [47]
    2 Mr
    Проверь директивы: KOL_MCK;GRAPHCTL_XPSTYLES;PAS_VERSION

    2 Vladimir Kladov
    Я понимаю, что Вы темы не используете и все такое, однако баг где-то в асм-версии. Возможно в прозрачности. С пас-версией все нормуль. Темы работают правильно и корректно.
  • Mr (09.04.10 13:22) [48]
    C PAS_VERSION работает.
  • Mr (09.04.10 13:36) [49]
    Да кстати еще 1 баг в свое время наблюдался: меню вдруг становилось неактивным. Такое было пару раз. Причины и условия возникновения не выяснил.
  • Mr (09.04.10 15:02) [50]
    + Причем очень интересным образом Файл - становился неактивным, Правка и тд работали нормально - в программе активность/неактивность указывалась только для Отменить/повторить.
  • Vladimir Kladov © (09.04.10 16:48) [51]
    А меню динамическое? И как выглядело управление активностью? Я буду смотреть, если будет тестовый пример, или точная инструкция, как воспроизвести баг.

    Вот исправление для переключения тем KOL_ASM:

    function WndProcNotify( Self_: PControl; var Msg: TMsg; var Rslt: Integer ): Boolean;
    asm
          CMP      word ptr [EDX].TMsg.message, WM_NOTIFY
          JNE      @@ret_false
           PUSH     ECX
           PUSH     EDX
          push     eax
          MOV      ECX, [EDX].TMsg.lParam
          {$IFDEF USE_PROP}
          PUSH     offset[ID_SELF]
          PUSH     [ECX].TNMHdr.hwndFrom
          CALL     GetProp
          {$ELSE}
          PUSH     GWL_USERDATA
          PUSH     [ECX].TNMHdr.hwndFrom
          CALL     GetWindowLong
          {$ENDIF}
           pop      ecx
           POP      EDX
           TEST     EAX, EAX
           JZ       @@ret_false_ECX
           cmp      eax, ecx
           jz       @@ret_false_ECX
           MOV      ECX, [EAX].TControl.fHandle
           MOV      [EDX].TMsg.hwnd, ECX
           POP      ECX
          JMP      TControl.EnumDynHandlers
    @@ret_false_ECX:
           POP      ECX
    @@ret_false:
          XOR      EAX, EAX
    end;

  • Vladimir Kladov © (09.04.10 16:49) [52]
    pop ecx мелкими буквами - тоже изменен, забыл выделить полужирным.
  • Mr (09.04.10 16:52) [53]
    Меню не динамическое. Управлялось mnuUndo.Enabled := False/True; Баг стабильно воспроизвести не получается - частота 2 раза за полгода )).
    За фикс спасибо.
  • Dufa © (09.04.10 17:00) [54]
    Vladimir Kladov, опередили меня с фиксом =)
  • Vladimir Kladov © (09.04.10 17:02) [55]
    mnuUndo.Enabled := False/True;
    С этого места можно подробнее: что такое mnuUndo и как оно было присвоено?
    В KOL вообще принята запись типа
       MainMenu1.ItemEnabled[mmUndo] :=
       not MainMenu1.ItemEnabled[mmUndo];

    при условии что константу mmUndo генерирует MCK.
  • Vladimir Kladov © (09.04.10 17:03) [56]
    D[u]fa, если у вас короче, выкладывайте.
  • Dufa © (09.04.10 17:07) [57]
    Vladimir Kladov, у меня тоже самое, но через EDX
  • Mr (09.04.10 19:04) [58]
    Поспешил, в программе
    mnuMain.Items[mnuUndo].Enabled := True/False;
    Значит нужно по другому? через .ItemEnabled?
  • Vladimir Kladov © (09.04.10 19:37) [59]
    Это без особой разницы. Вот если вы выловите закономерность, будет польза. Например: если есть сбой, то он стабилен в экзешнике, пока не будет перекомпилирован, и исчезает после перекомпиляции или проявляется нечаянно во время работы - однократно, и тут же исчезает как не бывало - даже без перезапуска?
  • Mr (09.04.10 22:00) [60]
    С выловом проблема: это происходит ОЧЕНЬ редко буквально 2 раз за полгода. По поведению проявляется нечаянно во время работы - и до перезапуска программы не исчезает. Происходило на нескольких машинах с свежеустановленной WinXP, из неродного софта только дрова на мамку, видеокарточку.
  • Vladimir Kladov © (10.04.10 08:53) [61]
    А запускаете - из Delphi? В том смысле, что если из Delphi, то ситуацию, очевидно, исправляет перекомпиляция. Вполне возможно, что в компиляторе зацепились неверные значения констант в предыдущем сбойном запуске. На такой сбой мог бы повлиять запуск программы из Delphi без ре-билда проекта сразу ПОСЛЕ того, как устанавливался пакет MCK или компилировался другой проект с сильно отличающимися опциями.

    Если это отдельный запуск, то уже такой глюк, какого быть просто не может. Тогда надо выяснять прочие обстоятельства: есть ли в проекте другие меню и другие формы, особенно динамические.

    Если не из Delphi, то остаются только - ошибки доступа к памяти. Т.е. наведенка.
  • Mr (10.04.10 09:36) [62]
    Не из под Delphi, скажем так, релизный вариант - так что в обязательном порядке делался ре-билд. Происходило на разных машинах одинаковой конфигурацией. На моей машине такого не было ни разу. Другие формы (модальные) есть, динамических меню нет, есть контекстное меню тоже не динамическое.
  • Vladimir Kladov © (10.04.10 10:08) [63]
    Тогда надо выяснять, что не так с этими машинами, на которых это было. Если машина такая доступна, с ней есть сетевое соединение, можно попробовать собрать проект в режиме remote debug. И запустить хоть несколько сотен раз, до проявления. Хорошо бы при этом наладить какой-то автоматический способ проверить наступление такого события. Например, при доступе к пункту через Items проверять текст меню. Речь ведь идет о доступе не к тем пунктам меню по индексу, так?

    Ситуация, скорее всего, никогда не наступит таким способом, если речь идет о действии вируса. Это слабое утешение, так как ненаступление события в N испытаниях не гарантирует ненаступление в (N+1)-ом. Если это вирус, то скорее всего, он не модифицирует экзешник, и портит память.

    Это может быть просто физический сбой (память, диск). Маловероятно, но все же.

    Если это коммерческий продукт или сколько нибудь серьезное, чем самоделка: я бы обязательно добавил в код проверку типа
    if MainMenu.ItemText[mm1] <> 'текст пункта меню' ..., если уже такое бывает. Хотя бы сообщить типа "Извините, системный сбой, перезапустите приложение" или просто молча перезапустить с теми же параметрами. Для надежности, чтобы не входило в вечный цикл, в реестре или ини-файле посчитать число перезапусков за секунду, и если стабильно, то выдать сообщение о сбое, сделать копию экзешника (лучше упаковать) и попросить отправить автору.

    А уже с этим экзешником можно было бы и поработать. Побайтно сравнить с текущей версией, проверить на вирусы. Если тождественный - проблема глубже. Копать надо, только куда, я сказать со стороны не могу. Было бы оно у меня, я бы время потратил хоть полгода, но источник глюка все равно бы нашел.
  • Mr (10.04.10 16:53) [64]
    Машины уходят с пром. оборудованием (как бы странно это не звучало но раз клиент хочет WinXP - любой каприз за его деньги). Вероятность вируса - стремиться к нулю - чистая винда + дрова к мамке - если бы возникало у клиента я бы сразу напомнил о необходимости антивируса, но это у нас на этапе прогона оборудования... Программа при этом ведет себя нормально - за счет того что все меню продублировано на тулбаре - работе это не так сильно мешает. В общем добавлю я несколько проверок и если что-то странное обнаружится отпишу вам.
  • QAZ (29.04.10 13:05) [65]
    а когда собствено эти все исправления окажуца в коле ?
  • Путник (29.04.10 17:55) [66]
    Dufa за svn огромное спасибо. не бросай это дело. удачи.
  • QAZ (30.04.10 14:46) [67]
    ошибка
    если заполнять комбобокс строками не важно в дезайнтайме или релтайме то все нормал пока не используеш директиву UNICODE_CTRLS
    с ней вылетает на добавлении первойже строки

    НО!!! у меня версия кол 2.79
    проверьте мошт и тут есть
  • vampir_infernal (02.05.10 16:41) [68]
    у меня в рантайме заполняется комбобокс с помощью метода Add, все работает и с юникодом, и без. Версия KOL 2.90
  • QAZ (04.05.10 13:32) [69]

    > у меня в рантайме заполняется комбобокс с помощью метода
    > Add, все работает и с юникодом, и без. Версия KOL 2.90

    забавно
    тестовая пустышка и там и там работает ,а навароченый проект не работает опятьже не там не там
    выдается AV на первомже ComboBox.Add по поводу kernel32.dll
    конкретно в Add на строке Result := Perform( fCommandActions.aAddItem, 0, Integer( PKOLChar( S ) ) );
    а ище конкретней в function _WStrToPWChar(const S: WideString): PWideChar; модуля System
    ватафака?

    зы
    и почему в Perform и прочих сендмесажах используеца Integer когда должен быть cardinal?
  • QAZ (04.05.10 13:40) [70]
    если делать так:
    ComboBox.Add('впвпавпвпва');


    вылетает....

    а так нет:

    var s:KOLString;
    begin
    s:='впвпавпвпва';
    ComboBox.Add(s);
    end;


    может это и логично и правильно,но мск генерирует какраз первый вариант
    и он собствено чудом работает в "простых" проектах
    ???
  • mdw (04.05.10 18:41) [71]
    Функция
    function DateTime2StrShort( D: TDateTime ): AnsiString;
    возвращает тип AnsiString. При этом вызывает SystemDate2Str и SystemTime2Str, которые возвращают KOLString. Получается несколько преобразований Ansi <-> Wide.
    Предлагаю поменять:

    function DateTime2StrShort( D: TDateTime ): KOLString;
  • Vladimir Kladov © (05.05.10 18:47) [72]
    почему в Perform и прочих сендмесажах используеца Integer когда должен быть cardinalВ контексте Perform это безразлично, код генерируется такой же.

    function DateTime2StrShort( D: TDateTime ): KOLString; Согласен

    если делать так:
    ComboBox.Add('впвпавпвпва');
    вылетает....
    Нет, не вылетает. В Delphi5 проверил при включенном UNICODE_CTRLS. В Delphi 7 SE то же самое. Вам придется приготовить достаточно навороченный тестовый проект, чтобы мы могли повторить явления и разобраться, в чем там дело.
  • vampir_infernal (06.05.10 14:20) [73]
    Функция
    function Format( const fmt: KOLString; params: Array of const ): KOLString;
    var Buffer: array[ 0..2047 ] of KOLChar;



    Если верить MSDN http://msdn.microsoft.com/en-us/library/ms647551(VS.85).aspx , максимальный размер буфера равен 1024 байтам, здесь же выделяется 2 (а в случае unicode_ctrls 4) килобайта. Не принципиально, но лишнее. Предлагаю изменить на
    var Buffer: array[ 0..1023 ] of byte;
    ----------
    Result := PKOLChar(@Buffer[0]);

  • QAZ (06.05.10 15:21) [74]
    а сделайте уже чтоб при открытии , проект сам обновлял пути , ато резервные копии папок делаеш а в форме старые пути остаются,и нафига они вобще???
    что ктото каждую форму хранит в разной папке а проект в другой??
    я про sourcePath и unitsourcePath в колпроект и колформ
  • QAZ (06.05.10 16:49) [75]

    >  Вам придется приготовить достаточно навороченный тестовый
    > проект, чтобы мы могли повторить явления и разобраться,
    > в чем там дело.

    да пожалста http://narod.ru/disk/20463924000/FileLow.rar.html
    + к косяку с комбобоксом, тут ище при буилде тулбар генерирует в *.inс эвенты кнопкам которым они не заданы вообще, ну и еррор соответсно
  • mdw (06.05.10 18:51) [76]

    > + к косяку с комбобоксом, тут ище при буилде тулбар генерирует
    > в *.inс эвенты кнопкам которым они не заданы вообще, ну
    > и еррор соответсно

    А вы как эти эвенты удаляли? Выделили в коде и нажали Del? В dfm они остались. Там еще и ресурсы не существующие цепляются... Вообще странный вы проект выложили, который вообще не компилится.
  • mdw (06.05.10 19:16) [77]

    > >  Вам придется приготовить достаточно навороченный тестовый
    > > проект, чтобы мы могли повторить явления и разобраться,
    >  > в чем там дело.

    Навороченный проект не нужен. Пустой проект с формой, комбобокс на ней. В опциях проекта UNICODE_CTRLS, в опциях комбобокса coLowerCase или coUpperCase. Этого достаточно. Действительно валится. Почему, разбираться лень, да и не нужно мне это, ни разу не пользовался coLowerCase или coUpperCase.:) Кому нужно пусть копает.
  • vampir_infernal (06.05.10 20:20) [78]
    MSDN уже в курсе.
    Comclt32.dll version 5.0 or later: If CBS_LOWERCASE or CBS_UPPERCASE is set, the Unicode version of CB_ADDSTRING alters the string. If using read-only global memory, this causes the application to fail.
  • QAZ (06.05.10 20:36) [79]

    > А вы как эти эвенты удаляли? Выделили в коде и нажали Del?
    >  В dfm они остались.

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

    > опциях комбобокса coLowerCase или coUpperCase. Этого достаточно.

    дествительно изза этого...
    причем ХР вылетает,а в вин7 запускается просто с пустым комбо
    но ведь через промежуточную переменую работает всегда...
  • QAZ (06.05.10 20:40) [80]

    > MSDN уже в курсе.

    тогда видимо пора сделать заполнение комбо через переменную
  • mdw (06.05.10 20:41) [81]

    > и какова они остались в форме это вопрос к мск, тк в редакторе
    > свойств они пустые...

    Это вопрос к Delphi. MCK здесь не причем.
  • QAZ (06.05.10 20:48) [82]

    > Это вопрос к Delphi. MCK здесь не причем.

    еслиб делфи был причем, это былобы не только у тулбара логично предположить
  • mdw (06.05.10 23:56) [83]

    > > Это вопрос к Delphi. MCK здесь не причем.еслиб делфи был
    > причем, это былобы не только у тулбара логично предположить

    Версия Delphi какая? до 7-й включительно ни разу такого не видел. А выше никто толком и не реализовывал, насколько знаю. Хотя не знаю, не устанавливал ни разу старше Delphi7, смысла нет.
  • QAZ (07.05.10 12:17) [84]
    7я , и тупняк этот только в кол и только у тулбар
    причем извращение в том что существующий онклик от несуществующего в тексте формы по формату описания ничем не отличается
    при этом делфи видит только существующий а мск все...
  • QAZ (07.05.10 12:31) [85]
    ище хотел спросить
    это нормалино что при UNICODE_CTRLS добавляется от 3 до 10 килобайт , в зависимости от размера софта? даже если просто пустой от кода проект
    есть подозрение что подключается куча лишних преобразований строк
    ведь все апишные функции имеют псевдонимы под уникод и их вызов не должен на столько увеличивать код
  • Vladimir Kladov © (07.05.10 15:28) [86]
    Увеличение на несколько К - нормально. Часть ассемблерного кода для UNICODE_CTRLS отключается.

    Исправление можно добавить, чтобы строки добавлялись в комбобокс с обязательным переприсваиванием переменной. Нужно ли - не знаю, исправление добавляет немного, и только для UNICODE_CTRLS, и только при наличии комбобокса.

    Чтобы тулбар забывал про назначавшиеся события, надо удалять не событие, а всю кнопку. В MCK приходится хранить имя события, как хранить ссылку на событие другим способом и стирать ее при удалении, мне неизвестно.
  • user89879 (12.05.10 12:56) [87]
    я прошу прощения что оффтоплю, сайт kolnmck.net показывает 404, что-то случилось?
  • Vladimir Kladov © (12.05.10 18:12) [88]
    Разбираемся.
  • QAZ (13.05.10 11:46) [89]
    ошибка в
    procedure TList.SetCapacity( Value: Integer );
    asm
           CMP       EDX, [EAX].fCount
           {$IFDEF USE_CMOV}
           CMOVL     EDX, [EAX].fCount
           {$ELSE}
           JGE       @@1
           MOV       EDX, [EAX].fCount
    @@1:    {$ENDIF}
           CMP       EDX, [EAX].fCapacity
           JE        @@exit

           MOV       [EAX].fCapacity, EDX
           SAL       EDX, 2
           LEA       EAX, [EAX].fItems
          CALL      System.@ReallocMem
    @@exit:
    end;



    выдает EoutOfMemory после добавления 68044 итема
    "лечица" заданием больших значений Capacity  но после его превышения один фиг вылетает
    например если задать Capacity:=100000 то вылетет после 120932 итема
    ватафака?
    я не против сразу ставить Capacity:=10000000 но наскока это влияет на память?
  • Vladimir Kladov © (13.05.10 16:14) [90]
    procedure TForm1.KOLForm1Show(Sender: PObj);
    var L: PList;
       i: Integer;
    begin
       L := NewList;
       for i := 1 to 100000 do
       begin
           L.Add( Pointer( i ) );
       end;
       ShowMessage( Int2Str( L.Count ) );
       L.Free;



    Ничего не вылетает, пишет 100000 и работает дальше.
    ТАк что давайте минимальный проект, на котором вылетает.
  • vampir_infernal (13.05.10 18:49) [91]
    При использовании файла справки в процедуре AssignHtmlHelp или методе TControl.SetHelpPath выделяется память в переменную HelpFilePath, которая никак не освобождается при выходе из приложения. Предлагаю исправить метод TControl.ProcessMessage примерно так:

    if (Msg.message = WM_QUIT) then
         begin
           AppletTerminated := True;
           if HelpFilePath <> '' then
             FreeMem(HelpFilePath);
           {$IFDEF PROVIDE_EXITCODE}
           ExitCode := Msg.wParam;
           {$ENDIF PROVIDE_EXITCODE}
         end

  • Vladimir Kladov © (13.05.10 19:51) [92]
    Моим тапочкам даже не смешно. Даже в win95, когда завершается работа приложения, вся память гарантированно освобождается, если это не был GlobalAlloc из системы. В NT-based системах вообще вся память освобождается. Начиная с Win2K гарантируется освобождение уже не только всей памяти, но и всех дескрипторов gdi, user и kernel.
  • vampir_infernal (13.05.10 23:02) [93]
    FastMM тоже не смеется. Сколько читал про выделение\освобождение памяти, про такие гарантии не знал. Спасибо, буду знать.
  • QAZ (17.05.10 15:47) [94]
    а вот от меня пример по поводу косяка скролбара
    http://narod.ru/disk/20833716000/scrollbartest.rar.html
    таскаем скролбары до полного просветления
  • Vladimir Kladov © (17.05.10 19:46) [95]
    Достижимость SBPosition = SBMax могу продемонстрировать сейчас, программно. Немного переделанный ваш же пример: http://kolmck.net/demos/scrollbartest2.rar Жать на числа в listview (особенно после 20) и смотреть на значения текущей позиции в заголовке формы (это значение, которое возвращает SetScrollInfo в мемо) и в нижней Label3 (значение, полученное GetScrollInfo из того же мемо). Окна не ограничиваются мемо. Если мемо умеет визуально корректировать позицию скроллбара, это не значит, что все контролы в windows такие умные. По крайней мере, траблы с пересчетом скролл-позиций я имел немаленькие, когда делал ScrollBox.

    Далее, вы прекрасно продемонстрировали, что левый дополнительный скроллбар, хотя и называется SBAPI, как раз удовлетворяет требованиям KOL. В нем применена корректировка, которая как раз и нужна для правильного отображения. Ни о чем не говорит? И чем не устраивает такая корректировка, если она приводит к желаемому результату?
  • QAZ (17.05.10 20:49) [96]

    > Достижимость SBPosition = SBMax

    для этого существует тракбар,
    а скролбар существует чтоб прокручивать чтолибо в области отображения, и в нем SBMax=число элементов, а Page=число видимых элементов
    и неважно строки это или попиксельный прокрут картинки все логично и работает как надо

    > траблы с пересчетом скролл-позиций я имел немаленькие

    траблы были видимо изза того, что Вы считали,что если есть Max то Position обязан его достигать,но это не так, этим кокраз ведает Page

    > И чем не устраивает такая корректировка, если она приводит
    > к желаемому результату?

    да тем что это антикоректировка Вашей коректировки
    и тем что не надо трогать святое, как в винде сделано так и должно быть,а уш если приспичило чтоб было  SBPosition = SBMax то Page:=1 и будет Вам счастие без всяких корекций
    или делайте чисто для своих целей,а не глобально
  • QAZ (17.05.10 21:21) [97]

    >  и в нижней Label3 (значение, полученное GetScrollInfo из
    > того же мемо).

    а вот тут неправда получается кокраз из SBKOL т.к. он последний

    procedure TForm1.ListView1LVStateChange(Sender: PControl; IdxFrom,
     IdxTo: Integer; OldState, NewState: Cardinal);
    var i: Integer;
       procedure UpdScr( Ctl: PControl; F: DWORD );
       var j: Integer;
       begin
           GetScrollInfo( Ctl.Handle, F, si );
           si.nPos := i;
           j := SetScrollInfo( Ctl.Handle, F, si, TRUE );
           Form.Caption := 'Current pos = ' + Int2Str(j);
           GetScrollInfo( Ctl.Handle, F, si );
           Label3.Caption := 'nMax=' + Int2Str(si.nMax) +
               ' nPage=' + Int2Str(si.nPage) +
               ' nPos='  + Int2Str(si.nPos);
       end;
    begin
       i := ListView1.LVCurItem;
       if i < 0 then Exit;
       UpdScr( Memo1, SB_VERT );
       UpdScr( SBAPI, SB_CTL );
       UpdScr( SBKOL, SB_CTL );
    end;

  • QAZ (17.05.10 21:38) [98]
    такчто
    "Достижимость SBPosition = SBMax могу продемонстрировать сейчас"
    не удалось
  • QAZ (18.05.10 14:02) [99]

    > По крайней мере, траблы с пересчетом скролл-позиций я имел
    > немаленькие, когда делал ScrollBox.

    я вот даже не представляю какие там могли быть траблы
    вот пример моего самопального "ScrollBoxа"
    http://narod.ru/disk/20873205000/ScrollBoxTEST.rar.html
  • Vladimir Kladov © (18.05.10 17:22) [100]
    Ну тогда я действительно ошибался. То, что траблы были, это точно. Но вспомнить где именно и как именно, уже вряд ли получится. Можно сделать ваш варианта кода основным, а старый оставить в скобках {$IFDEF SCROLL_OLD}, чтобы с совместимостью не заморачиваться.

    Вообще, скроллбар отдельный был дополнен в KOL не очень давно, намного позже основных контролов. Я просто помнил тогда, какие траблы мне попались до этого (те, что сейчас не вспомню), и полагая, что все то же самое верно и для отдельного скролбара, сразу же реализовал его именно так.

    Так что, извиняйте.

    А что, со сколлбоксом тоже что-то не так?
  • Vladimir Kladov © (18.05.10 17:43) [101]
    Не знаю, то ли у меня раньше MSDN не было, только что нашел:

    The SetScrollInfo function performs range checking on the values specified by the nPage and nPos members of the SCROLLINFO structure. The nPage member must specify a value from 0 to nMax - nMin +1. The nPos member must specify a value between nMin and nMax - max( nPage– 1, 0). If either value is beyond its range, the function sets it to a value that is just within the range.

    То есть вы правы, я не прав, еще раз приношу свои извинения.
  • QAZ (18.05.10 19:06) [102]

    > А что, со сколлбоксом тоже что-то не так?

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

    ну а то что ошиблись-бывает
    у людей про скролы инфы\опыта особо нет, а в рамках КОЛ возможно только нам они и понадобились :)
  • Vladimir Kladov © (19.05.10 16:09) [103]
    Нет, они там не могут использоваться. Скроллбокс появился на пару-тройку лет до того, как был добавлен отдельный скроллбар. Там может быть используется алгоритм пересчета максимума, но где именно, я на вскидку уже не скажу Хотя смотреть дальше WndProcScrollBox вроде бы и некуда.
  • QAZ (19.05.10 18:40) [104]
    на глаз видно , что например движок должен быть ровно половину (типа скролбох 200х200 а содержимое 400х400) ,ан нет - меньше, как раз похоже на корекцию
  • QAZ (19.05.10 19:45) [105]
    хотя походу все норм. в VCL также
  • 1 (22.03.12 00:12) [106]
    -1'
  • -1' (22.03.12 00:12) [107]
    1
  • 1 (22.03.12 00:12) [108]
    1
  • 1 (22.03.12 00:12) [109]
    1
 
Конференция "KOL" » Версия 2.90 [Delphi, Windows]
Есть новые Нет новых   [118462   +18][b:0.001][p:0.025]